Whamcloud - gitweb
cb8d362346ca9b3f03822e1aa8d750298026a6c0
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 test_27p() {
1912         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1914         remote_mds_nodsh && skip "remote MDS with nodsh"
1915         remote_ost_nodsh && skip "remote OST with nodsh"
1916
1917         reset_enospc
1918         rm -f $DIR/$tdir/$tfile
1919         test_mkdir $DIR/$tdir
1920
1921         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1922         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1923         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1924
1925         exhaust_precreations 0 0x80000215
1926         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1927         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1928         $LFS getstripe $DIR/$tdir/$tfile
1929
1930         reset_enospc
1931 }
1932 run_test 27p "append to a truncated file with some full OSTs"
1933
1934 test_27q() {
1935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1937         remote_mds_nodsh && skip "remote MDS with nodsh"
1938         remote_ost_nodsh && skip "remote OST with nodsh"
1939
1940         reset_enospc
1941         rm -f $DIR/$tdir/$tfile
1942
1943         test_mkdir $DIR/$tdir
1944         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1945         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1946                 error "truncate $DIR/$tdir/$tfile failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_all_precreations 0x215
1950
1951         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1952         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1953
1954         reset_enospc
1955 }
1956 run_test 27q "append to truncated file with all OSTs full (should error)"
1957
1958 test_27r() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966         exhaust_precreations 0 0x80000215
1967
1968         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1969
1970         reset_enospc
1971 }
1972 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1973
1974 test_27s() { # bug 10725
1975         test_mkdir $DIR/$tdir
1976         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1977         local stripe_count=0
1978         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1979         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1980                 error "stripe width >= 2^32 succeeded" || true
1981
1982 }
1983 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1984
1985 test_27t() { # bug 10864
1986         WDIR=$(pwd)
1987         WLFS=$(which lfs)
1988         cd $DIR
1989         touch $tfile
1990         $WLFS getstripe $tfile
1991         cd $WDIR
1992 }
1993 run_test 27t "check that utils parse path correctly"
1994
1995 test_27u() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998
1999         local index
2000         local list=$(comma_list $(mdts_nodes))
2001
2002 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2003         do_nodes $list $LCTL set_param fail_loc=0x139
2004         test_mkdir -p $DIR/$tdir
2005         trap simple_cleanup_common EXIT
2006         createmany -o $DIR/$tdir/t- 1000
2007         do_nodes $list $LCTL set_param fail_loc=0
2008
2009         TLOG=$TMP/$tfile.getstripe
2010         $LFS getstripe $DIR/$tdir > $TLOG
2011         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2012         unlinkmany $DIR/$tdir/t- 1000
2013         trap 0
2014         [[ $OBJS -gt 0 ]] &&
2015                 error "$OBJS objects created on OST-0. See $TLOG" ||
2016                 rm -f $TLOG
2017 }
2018 run_test 27u "skip object creation on OSC w/o objects"
2019
2020 test_27v() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2023         remote_mds_nodsh && skip "remote MDS with nodsh"
2024         remote_ost_nodsh && skip "remote OST with nodsh"
2025
2026         exhaust_all_precreations 0x215
2027         reset_enospc
2028
2029         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2030
2031         touch $DIR/$tdir/$tfile
2032         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2033         # all except ost1
2034         for (( i=1; i < OSTCOUNT; i++ )); do
2035                 do_facet ost$i lctl set_param fail_loc=0x705
2036         done
2037         local START=`date +%s`
2038         createmany -o $DIR/$tdir/$tfile 32
2039
2040         local FINISH=`date +%s`
2041         local TIMEOUT=`lctl get_param -n timeout`
2042         local PROCESS=$((FINISH - START))
2043         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2044                error "$FINISH - $START >= $TIMEOUT / 2"
2045         sleep $((TIMEOUT / 2 - PROCESS))
2046         reset_enospc
2047 }
2048 run_test 27v "skip object creation on slow OST"
2049
2050 test_27w() { # bug 10997
2051         test_mkdir $DIR/$tdir
2052         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2053         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2054                 error "stripe size $size != 65536" || true
2055         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2056                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2057 }
2058 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2059
2060 test_27wa() {
2061         [[ $OSTCOUNT -lt 2 ]] &&
2062                 skip_env "skipping multiple stripe count/offset test"
2063
2064         test_mkdir $DIR/$tdir
2065         for i in $(seq 1 $OSTCOUNT); do
2066                 offset=$((i - 1))
2067                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2068                         error "setstripe -c $i -i $offset failed"
2069                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2070                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2071                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2072                 [ $index -ne $offset ] &&
2073                         error "stripe offset $index != $offset" || true
2074         done
2075 }
2076 run_test 27wa "check $LFS setstripe -c -i options"
2077
2078 test_27x() {
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082
2083         OFFSET=$(($OSTCOUNT - 1))
2084         OSTIDX=0
2085         local OST=$(ostname_from_index $OSTIDX)
2086
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2089         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2090         sleep_maxage
2091         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2092         for i in $(seq 0 $OFFSET); do
2093                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2094                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2095                 error "OST0 was degraded but new created file still use it"
2096         done
2097         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2098 }
2099 run_test 27x "create files while OST0 is degraded"
2100
2101 test_27y() {
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         remote_mds_nodsh && skip "remote MDS with nodsh"
2104         remote_ost_nodsh && skip "remote OST with nodsh"
2105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2106
2107         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2108         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2109                 osp.$mdtosc.prealloc_last_id)
2110         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2111                 osp.$mdtosc.prealloc_next_id)
2112         local fcount=$((last_id - next_id))
2113         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2114         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2115
2116         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2117                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2118         local OST_DEACTIVE_IDX=-1
2119         local OSC
2120         local OSTIDX
2121         local OST
2122
2123         for OSC in $MDS_OSCS; do
2124                 OST=$(osc_to_ost $OSC)
2125                 OSTIDX=$(index_from_ostuuid $OST)
2126                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2127                         OST_DEACTIVE_IDX=$OSTIDX
2128                 fi
2129                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2130                         echo $OSC "is Deactivated:"
2131                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2132                 fi
2133         done
2134
2135         OSTIDX=$(index_from_ostuuid $OST)
2136         test_mkdir $DIR/$tdir
2137         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2138
2139         for OSC in $MDS_OSCS; do
2140                 OST=$(osc_to_ost $OSC)
2141                 OSTIDX=$(index_from_ostuuid $OST)
2142                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2143                         echo $OST "is degraded:"
2144                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2145                                                 obdfilter.$OST.degraded=1
2146                 fi
2147         done
2148
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $fcount
2151
2152         for OSC in $MDS_OSCS; do
2153                 OST=$(osc_to_ost $OSC)
2154                 OSTIDX=$(index_from_ostuuid $OST)
2155                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2156                         echo $OST "is recovered from degraded:"
2157                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2158                                                 obdfilter.$OST.degraded=0
2159                 else
2160                         do_facet $SINGLEMDS lctl --device %$OSC activate
2161                 fi
2162         done
2163
2164         # all osp devices get activated, hence -1 stripe count restored
2165         local stripe_count=0
2166
2167         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2168         # devices get activated.
2169         sleep_maxage
2170         $LFS setstripe -c -1 $DIR/$tfile
2171         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2172         rm -f $DIR/$tfile
2173         [ $stripe_count -ne $OSTCOUNT ] &&
2174                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2175         return 0
2176 }
2177 run_test 27y "create files while OST0 is degraded and the rest inactive"
2178
2179 check_seq_oid()
2180 {
2181         log "check file $1"
2182
2183         lmm_count=$($LFS getstripe -c $1)
2184         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2185         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2186
2187         local old_ifs="$IFS"
2188         IFS=$'[:]'
2189         fid=($($LFS path2fid $1))
2190         IFS="$old_ifs"
2191
2192         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2193         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2194
2195         # compare lmm_seq and lu_fid->f_seq
2196         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2197         # compare lmm_object_id and lu_fid->oid
2198         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2199
2200         # check the trusted.fid attribute of the OST objects of the file
2201         local have_obdidx=false
2202         local stripe_nr=0
2203         $LFS getstripe $1 | while read obdidx oid hex seq; do
2204                 # skip lines up to and including "obdidx"
2205                 [ -z "$obdidx" ] && break
2206                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2207                 $have_obdidx || continue
2208
2209                 local ost=$((obdidx + 1))
2210                 local dev=$(ostdevname $ost)
2211                 local oid_hex
2212
2213                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2214
2215                 seq=$(echo $seq | sed -e "s/^0x//g")
2216                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2217                         oid_hex=$(echo $oid)
2218                 else
2219                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2220                 fi
2221                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2222
2223                 local ff=""
2224                 #
2225                 # Don't unmount/remount the OSTs if we don't need to do that.
2226                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2227                 # update too, until that use mount/ll_decode_filter_fid/mount.
2228                 # Re-enable when debugfs will understand new filter_fid.
2229                 #
2230                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2231                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2232                                 $dev 2>/dev/null" | grep "parent=")
2233                 fi
2234                 if [ -z "$ff" ]; then
2235                         stop ost$ost
2236                         mount_fstype ost$ost
2237                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2238                                 $(facet_mntpt ost$ost)/$obj_file)
2239                         unmount_fstype ost$ost
2240                         start ost$ost $dev $OST_MOUNT_OPTS
2241                         clients_up
2242                 fi
2243
2244                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2245
2246                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2247
2248                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2249                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2250                 #
2251                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2252                 #       stripe_size=1048576 component_id=1 component_start=0 \
2253                 #       component_end=33554432
2254                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2255                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2256                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2257                 local ff_pstripe
2258                 if grep -q 'stripe=' <<<$ff; then
2259                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2260                 else
2261                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2262                         # into f_ver in this case.  See comment on ff_parent.
2263                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2264                 fi
2265
2266                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2267                 [ $ff_pseq = $lmm_seq ] ||
2268                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2269                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2270                 [ $ff_poid = $lmm_oid ] ||
2271                         error "FF parent OID $ff_poid != $lmm_oid"
2272                 (($ff_pstripe == $stripe_nr)) ||
2273                         error "FF stripe $ff_pstripe != $stripe_nr"
2274
2275                 stripe_nr=$((stripe_nr + 1))
2276                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2277                         continue
2278                 if grep -q 'stripe_count=' <<<$ff; then
2279                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2280                                             -e 's/ .*//' <<<$ff)
2281                         [ $lmm_count = $ff_scnt ] ||
2282                                 error "FF stripe count $lmm_count != $ff_scnt"
2283                 fi
2284         done
2285 }
2286
2287 test_27z() {
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2293                 { error "setstripe -c -1 failed"; return 1; }
2294         # We need to send a write to every object to get parent FID info set.
2295         # This _should_ also work for setattr, but does not currently.
2296         # touch $DIR/$tdir/$tfile-1 ||
2297         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2298                 { error "dd $tfile-1 failed"; return 2; }
2299         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2300                 { error "setstripe -c -1 failed"; return 3; }
2301         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2302                 { error "dd $tfile-2 failed"; return 4; }
2303
2304         # make sure write RPCs have been sent to OSTs
2305         sync; sleep 5; sync
2306
2307         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2308         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2309 }
2310 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2311
2312 test_27A() { # b=19102
2313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2314
2315         save_layout_restore_at_exit $MOUNT
2316         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2317         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2318                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2319         local default_size=$($LFS getstripe -S $MOUNT)
2320         local default_offset=$($LFS getstripe -i $MOUNT)
2321         local dsize=$(do_facet $SINGLEMDS \
2322                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2323         [ $default_size -eq $dsize ] ||
2324                 error "stripe size $default_size != $dsize"
2325         [ $default_offset -eq -1 ] ||
2326                 error "stripe offset $default_offset != -1"
2327 }
2328 run_test 27A "check filesystem-wide default LOV EA values"
2329
2330 test_27B() { # LU-2523
2331         test_mkdir $DIR/$tdir
2332         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2333         touch $DIR/$tdir/f0
2334         # open f1 with O_LOV_DELAY_CREATE
2335         # rename f0 onto f1
2336         # call setstripe ioctl on open file descriptor for f1
2337         # close
2338         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2339                 $DIR/$tdir/f0
2340
2341         rm -f $DIR/$tdir/f1
2342         # open f1 with O_LOV_DELAY_CREATE
2343         # unlink f1
2344         # call setstripe ioctl on open file descriptor for f1
2345         # close
2346         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2347
2348         # Allow multiop to fail in imitation of NFS's busted semantics.
2349         true
2350 }
2351 run_test 27B "call setstripe on open unlinked file/rename victim"
2352
2353 # 27C family tests full striping and overstriping
2354 test_27Ca() { #LU-2871
2355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2356
2357         declare -a ost_idx
2358         local index
2359         local found
2360         local i
2361         local j
2362
2363         test_mkdir $DIR/$tdir
2364         cd $DIR/$tdir
2365         for i in $(seq 0 $((OSTCOUNT - 1))); do
2366                 # set stripe across all OSTs starting from OST$i
2367                 $LFS setstripe -i $i -c -1 $tfile$i
2368                 # get striping information
2369                 ost_idx=($($LFS getstripe $tfile$i |
2370                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2371                 echo ${ost_idx[@]}
2372
2373                 # check the layout
2374                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2375                         error "${#ost_idx[@]} != $OSTCOUNT"
2376
2377                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2378                         found=0
2379                         for j in $(echo ${ost_idx[@]}); do
2380                                 if [ $index -eq $j ]; then
2381                                         found=1
2382                                         break
2383                                 fi
2384                         done
2385                         [ $found = 1 ] ||
2386                                 error "Can not find $index in ${ost_idx[@]}"
2387                 done
2388         done
2389 }
2390 run_test 27Ca "check full striping across all OSTs"
2391
2392 test_27Cb() {
2393         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2394                 skip "server does not support overstriping"
2395         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2396                 skip_env "too many osts, skipping"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT * 2))
2400         [ $setcount -ge 160 ] || large_xattr_enabled ||
2401                 skip_env "ea_inode feature disabled"
2402
2403         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2404                 error "setstripe failed"
2405
2406         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2407         [ $count -eq $setcount ] ||
2408                 error "stripe count $count, should be $setcount"
2409
2410         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2411                 error "overstriped should be set in pattern"
2412
2413         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2414                 error "dd failed"
2415 }
2416 run_test 27Cb "more stripes than OSTs with -C"
2417
2418 test_27Cc() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2422
2423         test_mkdir -p $DIR/$tdir
2424         local setcount=$(($OSTCOUNT - 1))
2425
2426         [ $setcount -ge 160 ] || large_xattr_enabled ||
2427                 skip_env "ea_inode feature disabled"
2428
2429         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2430                 error "setstripe failed"
2431
2432         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2433         [ $count -eq $setcount ] ||
2434                 error "stripe count $count, should be $setcount"
2435
2436         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2437                 error "overstriped should not be set in pattern"
2438
2439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2440                 error "dd failed"
2441 }
2442 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2443
2444 test_27Cd() {
2445         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2446                 skip "server does not support overstriping"
2447         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2448         large_xattr_enabled || skip_env "ea_inode feature disabled"
2449
2450         test_mkdir -p $DIR/$tdir
2451         local setcount=$LOV_MAX_STRIPE_COUNT
2452
2453         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2454                 error "setstripe failed"
2455
2456         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2457         [ $count -eq $setcount ] ||
2458                 error "stripe count $count, should be $setcount"
2459
2460         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2461                 error "overstriped should be set in pattern"
2462
2463         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2464                 error "dd failed"
2465
2466         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2467 }
2468 run_test 27Cd "test maximum stripe count"
2469
2470 test_27Ce() {
2471         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2472                 skip "server does not support overstriping"
2473         test_mkdir -p $DIR/$tdir
2474
2475         pool_add $TESTNAME || error "Pool creation failed"
2476         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2477
2478         local setcount=8
2479
2480         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2488                 error "overstriped should be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492
2493         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2494 }
2495 run_test 27Ce "test pool with overstriping"
2496
2497 test_27Cf() {
2498         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2499                 skip "server does not support overstriping"
2500         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2501                 skip_env "too many osts, skipping"
2502
2503         test_mkdir -p $DIR/$tdir
2504
2505         local setcount=$(($OSTCOUNT * 2))
2506         [ $setcount -ge 160 ] || large_xattr_enabled ||
2507                 skip_env "ea_inode feature disabled"
2508
2509         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2510                 error "setstripe failed"
2511
2512         echo 1 > $DIR/$tdir/$tfile
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2519                 error "overstriped should be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523
2524         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2525 }
2526 run_test 27Cf "test default inheritance with overstriping"
2527
2528 test_27D() {
2529         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2530         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2531         remote_mds_nodsh && skip "remote MDS with nodsh"
2532
2533         local POOL=${POOL:-testpool}
2534         local first_ost=0
2535         local last_ost=$(($OSTCOUNT - 1))
2536         local ost_step=1
2537         local ost_list=$(seq $first_ost $ost_step $last_ost)
2538         local ost_range="$first_ost $last_ost $ost_step"
2539
2540         test_mkdir $DIR/$tdir
2541         pool_add $POOL || error "pool_add failed"
2542         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2543
2544         local skip27D
2545         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2546                 skip27D+="-s 29"
2547         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2548                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2549                         skip27D+=" -s 30,31"
2550         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2551           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip27D+=" -s 32,33"
2553         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2554                 skip27D+=" -s 34"
2555         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2556                 error "llapi_layout_test failed"
2557
2558         destroy_test_pools || error "destroy test pools failed"
2559 }
2560 run_test 27D "validate llapi_layout API"
2561
2562 # Verify that default_easize is increased from its initial value after
2563 # accessing a widely striped file.
2564 test_27E() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2567                 skip "client does not have LU-3338 fix"
2568
2569         # 72 bytes is the minimum space required to store striping
2570         # information for a file striped across one OST:
2571         # (sizeof(struct lov_user_md_v3) +
2572         #  sizeof(struct lov_user_ost_data_v1))
2573         local min_easize=72
2574         $LCTL set_param -n llite.*.default_easize $min_easize ||
2575                 error "lctl set_param failed"
2576         local easize=$($LCTL get_param -n llite.*.default_easize)
2577
2578         [ $easize -eq $min_easize ] ||
2579                 error "failed to set default_easize"
2580
2581         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2582                 error "setstripe failed"
2583         # In order to ensure stat() call actually talks to MDS we need to
2584         # do something drastic to this file to shake off all lock, e.g.
2585         # rename it (kills lookup lock forcing cache cleaning)
2586         mv $DIR/$tfile $DIR/${tfile}-1
2587         ls -l $DIR/${tfile}-1
2588         rm $DIR/${tfile}-1
2589
2590         easize=$($LCTL get_param -n llite.*.default_easize)
2591
2592         [ $easize -gt $min_easize ] ||
2593                 error "default_easize not updated"
2594 }
2595 run_test 27E "check that default extended attribute size properly increases"
2596
2597 test_27F() { # LU-5346/LU-7975
2598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2599         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2600         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2601                 skip "Need MDS version at least 2.8.51"
2602         remote_ost_nodsh && skip "remote OST with nodsh"
2603
2604         test_mkdir $DIR/$tdir
2605         rm -f $DIR/$tdir/f0
2606         $LFS setstripe -c 2 $DIR/$tdir
2607
2608         # stop all OSTs to reproduce situation for LU-7975 ticket
2609         for num in $(seq $OSTCOUNT); do
2610                 stop ost$num
2611         done
2612
2613         # open/create f0 with O_LOV_DELAY_CREATE
2614         # truncate f0 to a non-0 size
2615         # close
2616         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2617
2618         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2619         # open/write it again to force delayed layout creation
2620         cat /etc/hosts > $DIR/$tdir/f0 &
2621         catpid=$!
2622
2623         # restart OSTs
2624         for num in $(seq $OSTCOUNT); do
2625                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2626                         error "ost$num failed to start"
2627         done
2628
2629         wait $catpid || error "cat failed"
2630
2631         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2632         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2633                 error "wrong stripecount"
2634
2635 }
2636 run_test 27F "Client resend delayed layout creation with non-zero size"
2637
2638 test_27G() { #LU-10629
2639         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2640                 skip "Need MDS version at least 2.11.51"
2641         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2642         remote_mds_nodsh && skip "remote MDS with nodsh"
2643         local POOL=${POOL:-testpool}
2644         local ostrange="0 0 1"
2645
2646         test_mkdir $DIR/$tdir
2647         touch $DIR/$tdir/$tfile.nopool
2648         pool_add $POOL || error "pool_add failed"
2649         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2650         $LFS setstripe -p $POOL $DIR/$tdir
2651
2652         local pool=$($LFS getstripe -p $DIR/$tdir)
2653
2654         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2655         touch $DIR/$tdir/$tfile.default
2656         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2657         $LFS find $DIR/$tdir -type f --pool $POOL
2658         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2659         [[ "$found" == "2" ]] ||
2660                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2661
2662         $LFS setstripe -d $DIR/$tdir
2663
2664         pool=$($LFS getstripe -p -d $DIR/$tdir)
2665
2666         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2667 }
2668 run_test 27G "Clear OST pool from stripe"
2669
2670 test_27H() {
2671         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2672                 skip "Need MDS version newer than 2.11.54"
2673         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2674         test_mkdir $DIR/$tdir
2675         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2676         touch $DIR/$tdir/$tfile
2677         $LFS getstripe -c $DIR/$tdir/$tfile
2678         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2679                 error "two-stripe file doesn't have two stripes"
2680
2681         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2682         $LFS getstripe -y $DIR/$tdir/$tfile
2683         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2684              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2685                 error "expected l_ost_idx: [02]$ not matched"
2686
2687         # make sure ost list has been cleared
2688         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2689         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2690                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2691         touch $DIR/$tdir/f3
2692         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2693 }
2694 run_test 27H "Set specific OSTs stripe"
2695
2696 test_27I() {
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2699         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2700                 skip "Need MDS version newer than 2.12.52"
2701         local pool=$TESTNAME
2702         local ostrange="1 1 1"
2703
2704         save_layout_restore_at_exit $MOUNT
2705         $LFS setstripe -c 2 -i 0 $MOUNT
2706         pool_add $pool || error "pool_add failed"
2707         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2708         test_mkdir $DIR/$tdir
2709         $LFS setstripe -p $pool $DIR/$tdir
2710         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2711         $LFS getstripe $DIR/$tdir/$tfile
2712 }
2713 run_test 27I "check that root dir striping does not break parent dir one"
2714
2715 test_27J() {
2716         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2717                 skip "Need MDS version newer than 2.12.51"
2718
2719         test_mkdir $DIR/$tdir
2720         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2721         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2722
2723         # create foreign file (raw way)
2724         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2725                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2726
2727         ! $LFS setstripe --foreign --flags foo \
2728                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2729                         error "creating $tfile with '--flags foo' should fail"
2730
2731         ! $LFS setstripe --foreign --flags 0xffffffff \
2732                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2733                         error "creating $tfile w/ 0xffffffff flags should fail"
2734
2735         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2736                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2737
2738         # verify foreign file (raw way)
2739         parse_foreign_file -f $DIR/$tdir/$tfile |
2740                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2742         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2743                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2744         parse_foreign_file -f $DIR/$tdir/$tfile |
2745                 grep "lov_foreign_size: 73" ||
2746                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2747         parse_foreign_file -f $DIR/$tdir/$tfile |
2748                 grep "lov_foreign_type: 1" ||
2749                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2750         parse_foreign_file -f $DIR/$tdir/$tfile |
2751                 grep "lov_foreign_flags: 0x0000DA08" ||
2752                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2753         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2754                 grep "lov_foreign_value: 0x" |
2755                 sed -e 's/lov_foreign_value: 0x//')
2756         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2757         [[ $lov = ${lov2// /} ]] ||
2758                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2759
2760         # create foreign file (lfs + API)
2761         $LFS setstripe --foreign=none --flags 0xda08 \
2762                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: create failed"
2764
2765         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2766                 grep "lfm_magic:.*0x0BD70BD0" ||
2767                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2768         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2769         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2770                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2771         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2772                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2773         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2774                 grep "lfm_flags:.*0x0000DA08" ||
2775                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2776         $LFS getstripe $DIR/$tdir/${tfile}2 |
2777                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2778                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2779
2780         # modify striping should fail
2781         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2782                 error "$DIR/$tdir/$tfile: setstripe should fail"
2783         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2784                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2785
2786         # R/W should fail
2787         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2788         cat $DIR/$tdir/${tfile}2 &&
2789                 error "$DIR/$tdir/${tfile}2: read should fail"
2790         cat /etc/passwd > $DIR/$tdir/$tfile &&
2791                 error "$DIR/$tdir/$tfile: write should fail"
2792         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2793                 error "$DIR/$tdir/${tfile}2: write should fail"
2794
2795         # chmod should work
2796         chmod 222 $DIR/$tdir/$tfile ||
2797                 error "$DIR/$tdir/$tfile: chmod failed"
2798         chmod 222 $DIR/$tdir/${tfile}2 ||
2799                 error "$DIR/$tdir/${tfile}2: chmod failed"
2800
2801         # chown should work
2802         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2803                 error "$DIR/$tdir/$tfile: chown failed"
2804         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2805                 error "$DIR/$tdir/${tfile}2: chown failed"
2806
2807         # rename should work
2808         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2809                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2810         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2811                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2812
2813         #remove foreign file
2814         rm $DIR/$tdir/${tfile}.new ||
2815                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2816         rm $DIR/$tdir/${tfile}2.new ||
2817                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2818 }
2819 run_test 27J "basic ops on file with foreign LOV"
2820
2821 test_27K() {
2822         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2823                 skip "Need MDS version newer than 2.12.49"
2824
2825         test_mkdir $DIR/$tdir
2826         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2827         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2828
2829         # create foreign dir (raw way)
2830         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2831                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2832
2833         ! $LFS setdirstripe --foreign --flags foo \
2834                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2835                         error "creating $tdir with '--flags foo' should fail"
2836
2837         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2838                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2839                         error "creating $tdir w/ 0xffffffff flags should fail"
2840
2841         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2842                 error "create_foreign_dir FAILED"
2843
2844         # verify foreign dir (raw way)
2845         parse_foreign_dir -d $DIR/$tdir/$tdir |
2846                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2847                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2848         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2849                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2850         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2851                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2852         parse_foreign_dir -d $DIR/$tdir/$tdir |
2853                 grep "lmv_foreign_flags: 55813$" ||
2854                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2855         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2856                 grep "lmv_foreign_value: 0x" |
2857                 sed 's/lmv_foreign_value: 0x//')
2858         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2859                 sed 's/ //g')
2860         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2861
2862         # create foreign dir (lfs + API)
2863         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2864                 $DIR/$tdir/${tdir}2 ||
2865                 error "$DIR/$tdir/${tdir}2: create failed"
2866
2867         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2868                 grep "lfm_magic:.*0x0CD50CD0" ||
2869                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2870         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2871         # - sizeof(lfm_type) - sizeof(lfm_flags)
2872         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2873                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2874         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2875                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2876         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2877                 grep "lfm_flags:.*0x0000DA05" ||
2878                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2879         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2880                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2881                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2882
2883         # file create in dir should fail
2884         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2885         touch $DIR/$tdir/${tdir}2/$tfile &&
2886                 "$DIR/${tdir}2: file create should fail"
2887
2888         # chmod should work
2889         chmod 777 $DIR/$tdir/$tdir ||
2890                 error "$DIR/$tdir: chmod failed"
2891         chmod 777 $DIR/$tdir/${tdir}2 ||
2892                 error "$DIR/${tdir}2: chmod failed"
2893
2894         # chown should work
2895         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2896                 error "$DIR/$tdir: chown failed"
2897         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2898                 error "$DIR/${tdir}2: chown failed"
2899
2900         # rename should work
2901         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2902                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2903         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2904                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2905
2906         #remove foreign dir
2907         rmdir $DIR/$tdir/${tdir}.new ||
2908                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2909         rmdir $DIR/$tdir/${tdir}2.new ||
2910                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2911 }
2912 run_test 27K "basic ops on dir with foreign LMV"
2913
2914 test_27L() {
2915         remote_mds_nodsh && skip "remote MDS with nodsh"
2916
2917         local POOL=${POOL:-$TESTNAME}
2918
2919         pool_add $POOL || error "pool_add failed"
2920
2921         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2922                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2923                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2924 }
2925 run_test 27L "lfs pool_list gives correct pool name"
2926
2927 test_27M() {
2928         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2929                 skip "Need MDS version >= than 2.12.57"
2930         remote_mds_nodsh && skip "remote MDS with nodsh"
2931         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2932
2933         test_mkdir $DIR/$tdir
2934
2935         # Set default striping on directory
2936         $LFS setstripe -C 4 $DIR/$tdir
2937
2938         echo 1 > $DIR/$tdir/${tfile}.1
2939         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2940         local setcount=4
2941         [ $count -eq $setcount ] ||
2942                 error "(1) stripe count $count, should be $setcount"
2943
2944         # Capture existing append_stripe_count setting for restore
2945         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2946         local mdts=$(comma_list $(mdts_nodes))
2947         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2948
2949         local appendcount=$orig_count
2950         echo 1 >> $DIR/$tdir/${tfile}.2_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(2)stripe count $count, should be $appendcount for append"
2954
2955         # Disable O_APPEND striping, verify it works
2956         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2957
2958         # Should now get the default striping, which is 4
2959         setcount=4
2960         echo 1 >> $DIR/$tdir/${tfile}.3_append
2961         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2962         [ $count -eq $setcount ] ||
2963                 error "(3) stripe count $count, should be $setcount"
2964
2965         # Try changing the stripe count for append files
2966         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2967
2968         # Append striping is now 2 (directory default is still 4)
2969         appendcount=2
2970         echo 1 >> $DIR/$tdir/${tfile}.4_append
2971         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2972         [ $count -eq $appendcount ] ||
2973                 error "(4) stripe count $count, should be $appendcount for append"
2974
2975         # Test append stripe count of -1
2976         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2977         appendcount=$OSTCOUNT
2978         echo 1 >> $DIR/$tdir/${tfile}.5
2979         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2980         [ $count -eq $appendcount ] ||
2981                 error "(5) stripe count $count, should be $appendcount for append"
2982
2983         # Set append striping back to default of 1
2984         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2985
2986         # Try a new default striping, PFL + DOM
2987         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2988
2989         # Create normal DOM file, DOM returns stripe count == 0
2990         setcount=0
2991         touch $DIR/$tdir/${tfile}.6
2992         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2993         [ $count -eq $setcount ] ||
2994                 error "(6) stripe count $count, should be $setcount"
2995
2996         # Show
2997         appendcount=1
2998         echo 1 >> $DIR/$tdir/${tfile}.7_append
2999         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3000         [ $count -eq $appendcount ] ||
3001                 error "(7) stripe count $count, should be $appendcount for append"
3002
3003         # Clean up DOM layout
3004         $LFS setstripe -d $DIR/$tdir
3005
3006         # Now test that append striping works when layout is from root
3007         $LFS setstripe -c 2 $MOUNT
3008         # Make a special directory for this
3009         mkdir $DIR/${tdir}/${tdir}.2
3010         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3011
3012         # Verify for normal file
3013         setcount=2
3014         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3015         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3016         [ $count -eq $setcount ] ||
3017                 error "(8) stripe count $count, should be $setcount"
3018
3019         appendcount=1
3020         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3021         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3022         [ $count -eq $appendcount ] ||
3023                 error "(9) stripe count $count, should be $appendcount for append"
3024
3025         # Now test O_APPEND striping with pools
3026         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3027         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3028
3029         # Create the pool
3030         pool_add $TESTNAME || error "pool creation failed"
3031         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3032
3033         echo 1 >> $DIR/$tdir/${tfile}.10_append
3034
3035         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3036         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3037
3038         # Check that count is still correct
3039         appendcount=1
3040         echo 1 >> $DIR/$tdir/${tfile}.11_append
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3042         [ $count -eq $appendcount ] ||
3043                 error "(11) stripe count $count, should be $appendcount for append"
3044
3045         # Disable O_APPEND stripe count, verify pool works separately
3046         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3047
3048         echo 1 >> $DIR/$tdir/${tfile}.12_append
3049
3050         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3051         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3052
3053         # Remove pool setting, verify it's not applied
3054         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3055
3056         echo 1 >> $DIR/$tdir/${tfile}.13_append
3057
3058         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3059         [ "$pool" = "" ] || error "(13) pool found: $pool"
3060 }
3061 run_test 27M "test O_APPEND striping"
3062
3063 test_27N() {
3064         combined_mgs_mds && skip "needs separate MGS/MDT"
3065
3066         pool_add $TESTNAME || error "pool_add failed"
3067         do_facet mgs "$LCTL pool_list $FSNAME" |
3068                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3069                 error "lctl pool_list on MGS failed"
3070 }
3071 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3072
3073 clean_foreign_symlink() {
3074         trap 0
3075         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3076         for i in $DIR/$tdir/* ; do
3077                 $LFS unlink_foreign $i || true
3078         done
3079 }
3080
3081 test_27O() {
3082         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3083                 skip "Need MDS version newer than 2.12.51"
3084
3085         test_mkdir $DIR/$tdir
3086         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3087         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3088
3089         trap clean_foreign_symlink EXIT
3090
3091         # enable foreign_symlink behaviour
3092         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3093
3094         # foreign symlink LOV format is a partial path by default
3095
3096         # create foreign file (lfs + API)
3097         $LFS setstripe --foreign=symlink --flags 0xda05 \
3098                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3099                 error "$DIR/$tdir/${tfile}: create failed"
3100
3101         $LFS getstripe -v $DIR/$tdir/${tfile} |
3102                 grep "lfm_magic:.*0x0BD70BD0" ||
3103                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3104         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3105                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3106         $LFS getstripe -v $DIR/$tdir/${tfile} |
3107                 grep "lfm_flags:.*0x0000DA05" ||
3108                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3109         $LFS getstripe $DIR/$tdir/${tfile} |
3110                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3111                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3112
3113         # modify striping should fail
3114         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3115                 error "$DIR/$tdir/$tfile: setstripe should fail"
3116
3117         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3118         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3119         cat /etc/passwd > $DIR/$tdir/$tfile &&
3120                 error "$DIR/$tdir/$tfile: write should fail"
3121
3122         # rename should succeed
3123         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3124                 error "$DIR/$tdir/$tfile: rename has failed"
3125
3126         #remove foreign_symlink file should fail
3127         rm $DIR/$tdir/${tfile}.new &&
3128                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3129
3130         #test fake symlink
3131         mkdir /tmp/${uuid1} ||
3132                 error "/tmp/${uuid1}: mkdir has failed"
3133         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3134                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3135         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3136         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3137                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3138         #read should succeed now
3139         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3140                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3141         #write should succeed now
3142         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3143                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3144         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3145                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3146         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3147                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3148
3149         #check that getstripe still works
3150         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3151                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3152
3153         # chmod should still succeed
3154         chmod 644 $DIR/$tdir/${tfile}.new ||
3155                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3156
3157         # chown should still succeed
3158         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3159                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3160
3161         # rename should still succeed
3162         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3163                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3164
3165         #remove foreign_symlink file should still fail
3166         rm $DIR/$tdir/${tfile} &&
3167                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3168
3169         #use special ioctl() to unlink foreign_symlink file
3170         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3171                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3172
3173 }
3174 run_test 27O "basic ops on foreign file of symlink type"
3175
3176 test_27P() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3178                 skip "Need MDS version newer than 2.12.49"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LMV format is a partial path by default
3190
3191         # create foreign dir (lfs + API)
3192         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3193                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3194                 error "$DIR/$tdir/${tdir}: create failed"
3195
3196         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3197                 grep "lfm_magic:.*0x0CD50CD0" ||
3198                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3199         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3201         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3204         $LFS getdirstripe $DIR/$tdir/${tdir} |
3205                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3207
3208         # file create in dir should fail
3209         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3210         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3211
3212         # rename should succeed
3213         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3214                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3215
3216         #remove foreign_symlink dir should fail
3217         rmdir $DIR/$tdir/${tdir}.new &&
3218                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3219
3220         #test fake symlink
3221         mkdir -p /tmp/${uuid1}/${uuid2} ||
3222                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3223         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3224                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3225         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3226         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3227                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3228         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3229                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3230
3231         #check that getstripe fails now that foreign_symlink enabled
3232         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3233                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3234
3235         # file create in dir should work now
3236         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3237                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3238         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3239                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3240         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3241                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3242
3243         # chmod should still succeed
3244         chmod 755 $DIR/$tdir/${tdir}.new ||
3245                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3246
3247         # chown should still succeed
3248         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3249                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3250
3251         # rename should still succeed
3252         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3254
3255         #remove foreign_symlink dir should still fail
3256         rmdir $DIR/$tdir/${tdir} &&
3257                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3258
3259         #use special ioctl() to unlink foreign_symlink file
3260         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3261                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3262
3263         #created file should still exist
3264         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3265                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3266         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3267                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3268 }
3269 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3270
3271 # createtest also checks that device nodes are created and
3272 # then visible correctly (#2091)
3273 test_28() { # bug 2091
3274         test_mkdir $DIR/d28
3275         $CREATETEST $DIR/d28/ct || error "createtest failed"
3276 }
3277 run_test 28 "create/mknod/mkdir with bad file types ============"
3278
3279 test_29() {
3280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3281
3282         sync; sleep 1; sync # flush out any dirty pages from previous tests
3283         cancel_lru_locks
3284         test_mkdir $DIR/d29
3285         touch $DIR/d29/foo
3286         log 'first d29'
3287         ls -l $DIR/d29
3288
3289         declare -i LOCKCOUNTORIG=0
3290         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3291                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3292         done
3293         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3294
3295         declare -i LOCKUNUSEDCOUNTORIG=0
3296         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3297                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3298         done
3299
3300         log 'second d29'
3301         ls -l $DIR/d29
3302         log 'done'
3303
3304         declare -i LOCKCOUNTCURRENT=0
3305         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3306                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3307         done
3308
3309         declare -i LOCKUNUSEDCOUNTCURRENT=0
3310         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3311                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3312         done
3313
3314         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3315                 $LCTL set_param -n ldlm.dump_namespaces ""
3316                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3317                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3318                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3319                 return 2
3320         fi
3321         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3322                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3323                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3324                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3325                 return 3
3326         fi
3327 }
3328 run_test 29 "IT_GETATTR regression  ============================"
3329
3330 test_30a() { # was test_30
3331         cp $(which ls) $DIR || cp /bin/ls $DIR
3332         $DIR/ls / || error "Can't execute binary from lustre"
3333         rm $DIR/ls
3334 }
3335 run_test 30a "execute binary from Lustre (execve) =============="
3336
3337 test_30b() {
3338         cp `which ls` $DIR || cp /bin/ls $DIR
3339         chmod go+rx $DIR/ls
3340         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3341         rm $DIR/ls
3342 }
3343 run_test 30b "execute binary from Lustre as non-root ==========="
3344
3345 test_30c() { # b=22376
3346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3347
3348         cp $(which ls) $DIR || cp /bin/ls $DIR
3349         chmod a-rw $DIR/ls
3350         cancel_lru_locks mdc
3351         cancel_lru_locks osc
3352         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3353         rm -f $DIR/ls
3354 }
3355 run_test 30c "execute binary from Lustre without read perms ===="
3356
3357 test_30d() {
3358         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3359
3360         for i in {1..10}; do
3361                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3362                 local PID=$!
3363                 sleep 1
3364                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3365                 wait $PID || error "executing dd from Lustre failed"
3366                 rm -f $DIR/$tfile
3367         done
3368
3369         rm -f $DIR/dd
3370 }
3371 run_test 30d "execute binary from Lustre while clear locks"
3372
3373 test_31a() {
3374         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3375         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3376 }
3377 run_test 31a "open-unlink file =================================="
3378
3379 test_31b() {
3380         touch $DIR/f31 || error "touch $DIR/f31 failed"
3381         ln $DIR/f31 $DIR/f31b || error "ln failed"
3382         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3383         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3384 }
3385 run_test 31b "unlink file with multiple links while open ======="
3386
3387 test_31c() {
3388         touch $DIR/f31 || error "touch $DIR/f31 failed"
3389         ln $DIR/f31 $DIR/f31c || error "ln failed"
3390         multiop_bg_pause $DIR/f31 O_uc ||
3391                 error "multiop_bg_pause for $DIR/f31 failed"
3392         MULTIPID=$!
3393         $MULTIOP $DIR/f31c Ouc
3394         kill -USR1 $MULTIPID
3395         wait $MULTIPID
3396 }
3397 run_test 31c "open-unlink file with multiple links ============="
3398
3399 test_31d() {
3400         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3401         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3402 }
3403 run_test 31d "remove of open directory ========================="
3404
3405 test_31e() { # bug 2904
3406         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3407 }
3408 run_test 31e "remove of open non-empty directory ==============="
3409
3410 test_31f() { # bug 4554
3411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3412
3413         set -vx
3414         test_mkdir $DIR/d31f
3415         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3416         cp /etc/hosts $DIR/d31f
3417         ls -l $DIR/d31f
3418         $LFS getstripe $DIR/d31f/hosts
3419         multiop_bg_pause $DIR/d31f D_c || return 1
3420         MULTIPID=$!
3421
3422         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3423         test_mkdir $DIR/d31f
3424         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3425         cp /etc/hosts $DIR/d31f
3426         ls -l $DIR/d31f
3427         $LFS getstripe $DIR/d31f/hosts
3428         multiop_bg_pause $DIR/d31f D_c || return 1
3429         MULTIPID2=$!
3430
3431         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3432         wait $MULTIPID || error "first opendir $MULTIPID failed"
3433
3434         sleep 6
3435
3436         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3437         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3438         set +vx
3439 }
3440 run_test 31f "remove of open directory with open-unlink file ==="
3441
3442 test_31g() {
3443         echo "-- cross directory link --"
3444         test_mkdir -c1 $DIR/${tdir}ga
3445         test_mkdir -c1 $DIR/${tdir}gb
3446         touch $DIR/${tdir}ga/f
3447         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3448         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3449         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3450         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3451         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3452 }
3453 run_test 31g "cross directory link==============="
3454
3455 test_31h() {
3456         echo "-- cross directory link --"
3457         test_mkdir -c1 $DIR/${tdir}
3458         test_mkdir -c1 $DIR/${tdir}/dir
3459         touch $DIR/${tdir}/f
3460         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3461         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3462         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3463         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3464         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3465 }
3466 run_test 31h "cross directory link under child==============="
3467
3468 test_31i() {
3469         echo "-- cross directory link --"
3470         test_mkdir -c1 $DIR/$tdir
3471         test_mkdir -c1 $DIR/$tdir/dir
3472         touch $DIR/$tdir/dir/f
3473         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3474         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3475         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3476         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3477         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3478 }
3479 run_test 31i "cross directory link under parent==============="
3480
3481 test_31j() {
3482         test_mkdir -c1 -p $DIR/$tdir
3483         test_mkdir -c1 -p $DIR/$tdir/dir1
3484         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3485         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3486         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3487         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3488         return 0
3489 }
3490 run_test 31j "link for directory==============="
3491
3492 test_31k() {
3493         test_mkdir -c1 -p $DIR/$tdir
3494         touch $DIR/$tdir/s
3495         touch $DIR/$tdir/exist
3496         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3497         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3498         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3499         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3500         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3501         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3502         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3503         return 0
3504 }
3505 run_test 31k "link to file: the same, non-existing, dir==============="
3506
3507 test_31m() {
3508         mkdir $DIR/d31m
3509         touch $DIR/d31m/s
3510         mkdir $DIR/d31m2
3511         touch $DIR/d31m2/exist
3512         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3513         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3514         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3515         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3516         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3517         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3518         return 0
3519 }
3520 run_test 31m "link to file: the same, non-existing, dir==============="
3521
3522 test_31n() {
3523         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3524         nlink=$(stat --format=%h $DIR/$tfile)
3525         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3526         local fd=$(free_fd)
3527         local cmd="exec $fd<$DIR/$tfile"
3528         eval $cmd
3529         cmd="exec $fd<&-"
3530         trap "eval $cmd" EXIT
3531         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3532         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3533         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3534         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3535         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3536         eval $cmd
3537 }
3538 run_test 31n "check link count of unlinked file"
3539
3540 link_one() {
3541         local tempfile=$(mktemp $1_XXXXXX)
3542         mlink $tempfile $1 2> /dev/null &&
3543                 echo "$BASHPID: link $tempfile to $1 succeeded"
3544         munlink $tempfile
3545 }
3546
3547 test_31o() { # LU-2901
3548         test_mkdir $DIR/$tdir
3549         for LOOP in $(seq 100); do
3550                 rm -f $DIR/$tdir/$tfile*
3551                 for THREAD in $(seq 8); do
3552                         link_one $DIR/$tdir/$tfile.$LOOP &
3553                 done
3554                 wait
3555                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3556                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3557                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3558                         break || true
3559         done
3560 }
3561 run_test 31o "duplicate hard links with same filename"
3562
3563 test_31p() {
3564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3565
3566         test_mkdir $DIR/$tdir
3567         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3568         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3569
3570         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3571                 error "open unlink test1 failed"
3572         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3573                 error "open unlink test2 failed"
3574
3575         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3576                 error "test1 still exists"
3577         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3578                 error "test2 still exists"
3579 }
3580 run_test 31p "remove of open striped directory"
3581
3582 test_31q() {
3583         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3584
3585         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3586         index=$($LFS getdirstripe -i $DIR/$tdir)
3587         [ $index -eq 3 ] || error "first stripe index $index != 3"
3588         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3589         [ $index -eq 1 ] || error "second stripe index $index != 1"
3590
3591         # when "-c <stripe_count>" is set, the number of MDTs specified after
3592         # "-i" should equal to the stripe count
3593         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3594 }
3595 run_test 31q "create striped directory on specific MDTs"
3596
3597 cleanup_test32_mount() {
3598         local rc=0
3599         trap 0
3600         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3601         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3602         losetup -d $loopdev || true
3603         rm -rf $DIR/$tdir
3604         return $rc
3605 }
3606
3607 test_32a() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         echo "== more mountpoints and symlinks ================="
3611         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3612         trap cleanup_test32_mount EXIT
3613         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3614         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3615                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3616         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3617                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3618         cleanup_test32_mount
3619 }
3620 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3621
3622 test_32b() {
3623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3624
3625         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3626         trap cleanup_test32_mount EXIT
3627         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3628         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3629                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3630         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3631                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3632         cleanup_test32_mount
3633 }
3634 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3635
3636 test_32c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638
3639         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3640         trap cleanup_test32_mount EXIT
3641         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3642         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3643                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3644         test_mkdir -p $DIR/$tdir/d2/test_dir
3645         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3646                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3647         cleanup_test32_mount
3648 }
3649 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3650
3651 test_32d() {
3652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3653
3654         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3655         trap cleanup_test32_mount EXIT
3656         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3657         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3658                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3659         test_mkdir -p $DIR/$tdir/d2/test_dir
3660         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3661                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3662         cleanup_test32_mount
3663 }
3664 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3665
3666 test_32e() {
3667         rm -fr $DIR/$tdir
3668         test_mkdir -p $DIR/$tdir/tmp
3669         local tmp_dir=$DIR/$tdir/tmp
3670         ln -s $DIR/$tdir $tmp_dir/symlink11
3671         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3672         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3673         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3674 }
3675 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3676
3677 test_32f() {
3678         rm -fr $DIR/$tdir
3679         test_mkdir -p $DIR/$tdir/tmp
3680         local tmp_dir=$DIR/$tdir/tmp
3681         ln -s $DIR/$tdir $tmp_dir/symlink11
3682         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3683         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3684         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3685 }
3686 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3687
3688 test_32g() {
3689         local tmp_dir=$DIR/$tdir/tmp
3690         test_mkdir -p $tmp_dir
3691         test_mkdir $DIR/${tdir}2
3692         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3693         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3694         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3695         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3696         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3697         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3698 }
3699 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3700
3701 test_32h() {
3702         rm -fr $DIR/$tdir $DIR/${tdir}2
3703         tmp_dir=$DIR/$tdir/tmp
3704         test_mkdir -p $tmp_dir
3705         test_mkdir $DIR/${tdir}2
3706         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3707         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3708         ls $tmp_dir/symlink12 || error "listing symlink12"
3709         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3710 }
3711 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3712
3713 test_32i() {
3714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3715
3716         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3717         trap cleanup_test32_mount EXIT
3718         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3719         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3720                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3721         touch $DIR/$tdir/test_file
3722         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3723                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3724         cleanup_test32_mount
3725 }
3726 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3727
3728 test_32j() {
3729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3730
3731         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3732         trap cleanup_test32_mount EXIT
3733         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3734         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3735                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3736         touch $DIR/$tdir/test_file
3737         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3738                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3739         cleanup_test32_mount
3740 }
3741 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3742
3743 test_32k() {
3744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3745
3746         rm -fr $DIR/$tdir
3747         trap cleanup_test32_mount EXIT
3748         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3749         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3750                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3751         test_mkdir -p $DIR/$tdir/d2
3752         touch $DIR/$tdir/d2/test_file || error "touch failed"
3753         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3754                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3755         cleanup_test32_mount
3756 }
3757 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3758
3759 test_32l() {
3760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3761
3762         rm -fr $DIR/$tdir
3763         trap cleanup_test32_mount EXIT
3764         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3765         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3766                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3767         test_mkdir -p $DIR/$tdir/d2
3768         touch $DIR/$tdir/d2/test_file || error "touch failed"
3769         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3770                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3771         cleanup_test32_mount
3772 }
3773 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3774
3775 test_32m() {
3776         rm -fr $DIR/d32m
3777         test_mkdir -p $DIR/d32m/tmp
3778         TMP_DIR=$DIR/d32m/tmp
3779         ln -s $DIR $TMP_DIR/symlink11
3780         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3781         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3782                 error "symlink11 not a link"
3783         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3784                 error "symlink01 not a link"
3785 }
3786 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3787
3788 test_32n() {
3789         rm -fr $DIR/d32n
3790         test_mkdir -p $DIR/d32n/tmp
3791         TMP_DIR=$DIR/d32n/tmp
3792         ln -s $DIR $TMP_DIR/symlink11
3793         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3794         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3795         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3796 }
3797 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3798
3799 test_32o() {
3800         touch $DIR/$tfile
3801         test_mkdir -p $DIR/d32o/tmp
3802         TMP_DIR=$DIR/d32o/tmp
3803         ln -s $DIR/$tfile $TMP_DIR/symlink12
3804         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3805         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3806                 error "symlink12 not a link"
3807         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3808         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3809                 error "$DIR/d32o/tmp/symlink12 not file type"
3810         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3811                 error "$DIR/d32o/symlink02 not file type"
3812 }
3813 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3814
3815 test_32p() {
3816         log 32p_1
3817         rm -fr $DIR/d32p
3818         log 32p_2
3819         rm -f $DIR/$tfile
3820         log 32p_3
3821         touch $DIR/$tfile
3822         log 32p_4
3823         test_mkdir -p $DIR/d32p/tmp
3824         log 32p_5
3825         TMP_DIR=$DIR/d32p/tmp
3826         log 32p_6
3827         ln -s $DIR/$tfile $TMP_DIR/symlink12
3828         log 32p_7
3829         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3830         log 32p_8
3831         cat $DIR/d32p/tmp/symlink12 ||
3832                 error "Can't open $DIR/d32p/tmp/symlink12"
3833         log 32p_9
3834         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3835         log 32p_10
3836 }
3837 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3838
3839 test_32q() {
3840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3841
3842         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3843         trap cleanup_test32_mount EXIT
3844         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3845         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3846         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3847                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3848         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3849         cleanup_test32_mount
3850 }
3851 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3852
3853 test_32r() {
3854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3855
3856         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3857         trap cleanup_test32_mount EXIT
3858         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3859         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3860         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3861                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3862         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3863         cleanup_test32_mount
3864 }
3865 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3866
3867 test_33aa() {
3868         rm -f $DIR/$tfile
3869         touch $DIR/$tfile
3870         chmod 444 $DIR/$tfile
3871         chown $RUNAS_ID $DIR/$tfile
3872         log 33_1
3873         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3874         log 33_2
3875 }
3876 run_test 33aa "write file with mode 444 (should return error)"
3877
3878 test_33a() {
3879         rm -fr $DIR/$tdir
3880         test_mkdir $DIR/$tdir
3881         chown $RUNAS_ID $DIR/$tdir
3882         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3883                 error "$RUNAS create $tdir/$tfile failed"
3884         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3885                 error "open RDWR" || true
3886 }
3887 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3888
3889 test_33b() {
3890         rm -fr $DIR/$tdir
3891         test_mkdir $DIR/$tdir
3892         chown $RUNAS_ID $DIR/$tdir
3893         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3894 }
3895 run_test 33b "test open file with malformed flags (No panic)"
3896
3897 test_33c() {
3898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3899         remote_ost_nodsh && skip "remote OST with nodsh"
3900
3901         local ostnum
3902         local ostname
3903         local write_bytes
3904         local all_zeros
3905
3906         all_zeros=:
3907         rm -fr $DIR/$tdir
3908         test_mkdir $DIR/$tdir
3909         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3910
3911         sync
3912         for ostnum in $(seq $OSTCOUNT); do
3913                 # test-framework's OST numbering is one-based, while Lustre's
3914                 # is zero-based
3915                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3916                 # Parsing llobdstat's output sucks; we could grep the /proc
3917                 # path, but that's likely to not be as portable as using the
3918                 # llobdstat utility.  So we parse lctl output instead.
3919                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3920                         obdfilter/$ostname/stats |
3921                         awk '/^write_bytes/ {print $7}' )
3922                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3923                 if (( ${write_bytes:-0} > 0 ))
3924                 then
3925                         all_zeros=false
3926                         break;
3927                 fi
3928         done
3929
3930         $all_zeros || return 0
3931
3932         # Write four bytes
3933         echo foo > $DIR/$tdir/bar
3934         # Really write them
3935         sync
3936
3937         # Total up write_bytes after writing.  We'd better find non-zeros.
3938         for ostnum in $(seq $OSTCOUNT); do
3939                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3940                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3941                         obdfilter/$ostname/stats |
3942                         awk '/^write_bytes/ {print $7}' )
3943                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3944                 if (( ${write_bytes:-0} > 0 ))
3945                 then
3946                         all_zeros=false
3947                         break;
3948                 fi
3949         done
3950
3951         if $all_zeros
3952         then
3953                 for ostnum in $(seq $OSTCOUNT); do
3954                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3955                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3956                         do_facet ost$ostnum lctl get_param -n \
3957                                 obdfilter/$ostname/stats
3958                 done
3959                 error "OST not keeping write_bytes stats (b22312)"
3960         fi
3961 }
3962 run_test 33c "test llobdstat and write_bytes"
3963
3964 test_33d() {
3965         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         local MDTIDX=1
3969         local remote_dir=$DIR/$tdir/remote_dir
3970
3971         test_mkdir $DIR/$tdir
3972         $LFS mkdir -i $MDTIDX $remote_dir ||
3973                 error "create remote directory failed"
3974
3975         touch $remote_dir/$tfile
3976         chmod 444 $remote_dir/$tfile
3977         chown $RUNAS_ID $remote_dir/$tfile
3978
3979         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3980
3981         chown $RUNAS_ID $remote_dir
3982         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3983                                         error "create" || true
3984         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3985                                     error "open RDWR" || true
3986         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3987 }
3988 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3989
3990 test_33e() {
3991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3992
3993         mkdir $DIR/$tdir
3994
3995         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3996         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3997         mkdir $DIR/$tdir/local_dir
3998
3999         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4000         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4001         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4002
4003         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4004                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4005
4006         rmdir $DIR/$tdir/* || error "rmdir failed"
4007
4008         umask 777
4009         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4010         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4011         mkdir $DIR/$tdir/local_dir
4012
4013         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4014         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4015         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4016
4017         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4018                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4019
4020         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4021
4022         umask 000
4023         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4024         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4025         mkdir $DIR/$tdir/local_dir
4026
4027         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4028         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4029         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4030
4031         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4032                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4033 }
4034 run_test 33e "mkdir and striped directory should have same mode"
4035
4036 cleanup_33f() {
4037         trap 0
4038         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4039 }
4040
4041 test_33f() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043         remote_mds_nodsh && skip "remote MDS with nodsh"
4044
4045         mkdir $DIR/$tdir
4046         chmod go+rwx $DIR/$tdir
4047         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4048         trap cleanup_33f EXIT
4049
4050         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4051                 error "cannot create striped directory"
4052
4053         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4054                 error "cannot create files in striped directory"
4055
4056         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4057                 error "cannot remove files in striped directory"
4058
4059         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4060                 error "cannot remove striped directory"
4061
4062         cleanup_33f
4063 }
4064 run_test 33f "nonroot user can create, access, and remove a striped directory"
4065
4066 test_33g() {
4067         mkdir -p $DIR/$tdir/dir2
4068
4069         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4070         echo $err
4071         [[ $err =~ "exists" ]] || error "Not exists error"
4072 }
4073 run_test 33g "nonroot user create already existing root created file"
4074
4075 test_33h() {
4076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4077         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4078                 skip "Need MDS version at least 2.13.50"
4079
4080         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4081                 error "mkdir $tdir failed"
4082         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4083
4084         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4085         local index2
4086
4087         for fname in $DIR/$tdir/$tfile.bak \
4088                      $DIR/$tdir/$tfile.SAV \
4089                      $DIR/$tdir/$tfile.orig \
4090                      $DIR/$tdir/$tfile~; do
4091                 touch $fname  || error "touch $fname failed"
4092                 index2=$($LFS getstripe -m $fname)
4093                 [ $index -eq $index2 ] ||
4094                         error "$fname MDT index mismatch $index != $index2"
4095         done
4096
4097         local failed=0
4098         for i in {1..250}; do
4099                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4100                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4101                         touch $fname  || error "touch $fname failed"
4102                         index2=$($LFS getstripe -m $fname)
4103                         if [[ $index != $index2 ]]; then
4104                                 failed=$((failed + 1))
4105                                 echo "$fname MDT index mismatch $index != $index2"
4106                         fi
4107                 done
4108         done
4109         echo "$failed MDT index mismatches"
4110         (( failed < 20 )) || error "MDT index mismatch $failed times"
4111
4112 }
4113 run_test 33h "temp file is located on the same MDT as target"
4114
4115 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4116 test_34a() {
4117         rm -f $DIR/f34
4118         $MCREATE $DIR/f34 || error "mcreate failed"
4119         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4120                 error "getstripe failed"
4121         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4122         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4123                 error "getstripe failed"
4124         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4125                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4126 }
4127 run_test 34a "truncate file that has not been opened ==========="
4128
4129 test_34b() {
4130         [ ! -f $DIR/f34 ] && test_34a
4131         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4132                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4133         $OPENFILE -f O_RDONLY $DIR/f34
4134         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4135                 error "getstripe failed"
4136         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4137                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4138 }
4139 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4140
4141 test_34c() {
4142         [ ! -f $DIR/f34 ] && test_34a
4143         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4144                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4145         $OPENFILE -f O_RDWR $DIR/f34
4146         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4147                 error "$LFS getstripe failed"
4148         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4149                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4150 }
4151 run_test 34c "O_RDWR opening file-with-size works =============="
4152
4153 test_34d() {
4154         [ ! -f $DIR/f34 ] && test_34a
4155         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4156                 error "dd failed"
4157         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4158                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4159         rm $DIR/f34
4160 }
4161 run_test 34d "write to sparse file ============================="
4162
4163 test_34e() {
4164         rm -f $DIR/f34e
4165         $MCREATE $DIR/f34e || error "mcreate failed"
4166         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4167         $CHECKSTAT -s 1000 $DIR/f34e ||
4168                 error "Size of $DIR/f34e not equal to 1000 bytes"
4169         $OPENFILE -f O_RDWR $DIR/f34e
4170         $CHECKSTAT -s 1000 $DIR/f34e ||
4171                 error "Size of $DIR/f34e not equal to 1000 bytes"
4172 }
4173 run_test 34e "create objects, some with size and some without =="
4174
4175 test_34f() { # bug 6242, 6243
4176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4177
4178         SIZE34F=48000
4179         rm -f $DIR/f34f
4180         $MCREATE $DIR/f34f || error "mcreate failed"
4181         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4182         dd if=$DIR/f34f of=$TMP/f34f
4183         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4184         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4185         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4186         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4187         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4188 }
4189 run_test 34f "read from a file with no objects until EOF ======="
4190
4191 test_34g() {
4192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4193
4194         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4195                 error "dd failed"
4196         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4197         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4198                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4199         cancel_lru_locks osc
4200         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4201                 error "wrong size after lock cancel"
4202
4203         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4204         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4205                 error "expanding truncate failed"
4206         cancel_lru_locks osc
4207         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4208                 error "wrong expanded size after lock cancel"
4209 }
4210 run_test 34g "truncate long file ==============================="
4211
4212 test_34h() {
4213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4214
4215         local gid=10
4216         local sz=1000
4217
4218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4219         sync # Flush the cache so that multiop below does not block on cache
4220              # flush when getting the group lock
4221         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4222         MULTIPID=$!
4223
4224         # Since just timed wait is not good enough, let's do a sync write
4225         # that way we are sure enough time for a roundtrip + processing
4226         # passed + 2 seconds of extra margin.
4227         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4228         rm $DIR/${tfile}-1
4229         sleep 2
4230
4231         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4232                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4233                 kill -9 $MULTIPID
4234         fi
4235         wait $MULTIPID
4236         local nsz=`stat -c %s $DIR/$tfile`
4237         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4238 }
4239 run_test 34h "ftruncate file under grouplock should not block"
4240
4241 test_35a() {
4242         cp /bin/sh $DIR/f35a
4243         chmod 444 $DIR/f35a
4244         chown $RUNAS_ID $DIR/f35a
4245         $RUNAS $DIR/f35a && error || true
4246         rm $DIR/f35a
4247 }
4248 run_test 35a "exec file with mode 444 (should return and not leak)"
4249
4250 test_36a() {
4251         rm -f $DIR/f36
4252         utime $DIR/f36 || error "utime failed for MDS"
4253 }
4254 run_test 36a "MDS utime check (mknod, utime)"
4255
4256 test_36b() {
4257         echo "" > $DIR/f36
4258         utime $DIR/f36 || error "utime failed for OST"
4259 }
4260 run_test 36b "OST utime check (open, utime)"
4261
4262 test_36c() {
4263         rm -f $DIR/d36/f36
4264         test_mkdir $DIR/d36
4265         chown $RUNAS_ID $DIR/d36
4266         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4267 }
4268 run_test 36c "non-root MDS utime check (mknod, utime)"
4269
4270 test_36d() {
4271         [ ! -d $DIR/d36 ] && test_36c
4272         echo "" > $DIR/d36/f36
4273         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4274 }
4275 run_test 36d "non-root OST utime check (open, utime)"
4276
4277 test_36e() {
4278         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4279
4280         test_mkdir $DIR/$tdir
4281         touch $DIR/$tdir/$tfile
4282         $RUNAS utime $DIR/$tdir/$tfile &&
4283                 error "utime worked, expected failure" || true
4284 }
4285 run_test 36e "utime on non-owned file (should return error)"
4286
4287 subr_36fh() {
4288         local fl="$1"
4289         local LANG_SAVE=$LANG
4290         local LC_LANG_SAVE=$LC_LANG
4291         export LANG=C LC_LANG=C # for date language
4292
4293         DATESTR="Dec 20  2000"
4294         test_mkdir $DIR/$tdir
4295         lctl set_param fail_loc=$fl
4296         date; date +%s
4297         cp /etc/hosts $DIR/$tdir/$tfile
4298         sync & # write RPC generated with "current" inode timestamp, but delayed
4299         sleep 1
4300         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4301         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4302         cancel_lru_locks $OSC
4303         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4304         date; date +%s
4305         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4306                 echo "BEFORE: $LS_BEFORE" && \
4307                 echo "AFTER : $LS_AFTER" && \
4308                 echo "WANT  : $DATESTR" && \
4309                 error "$DIR/$tdir/$tfile timestamps changed" || true
4310
4311         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4312 }
4313
4314 test_36f() {
4315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4316
4317         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4318         subr_36fh "0x80000214"
4319 }
4320 run_test 36f "utime on file racing with OST BRW write =========="
4321
4322 test_36g() {
4323         remote_ost_nodsh && skip "remote OST with nodsh"
4324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4325         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4326                 skip "Need MDS version at least 2.12.51"
4327
4328         local fmd_max_age
4329         local fmd
4330         local facet="ost1"
4331         local tgt="obdfilter"
4332
4333         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4334
4335         test_mkdir $DIR/$tdir
4336         fmd_max_age=$(do_facet $facet \
4337                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4338                 head -n 1")
4339
4340         echo "FMD max age: ${fmd_max_age}s"
4341         touch $DIR/$tdir/$tfile
4342         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4343                 gawk '{cnt=cnt+$1}  END{print cnt}')
4344         echo "FMD before: $fmd"
4345         [[ $fmd == 0 ]] &&
4346                 error "FMD wasn't create by touch"
4347         sleep $((fmd_max_age + 12))
4348         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4349                 gawk '{cnt=cnt+$1}  END{print cnt}')
4350         echo "FMD after: $fmd"
4351         [[ $fmd == 0 ]] ||
4352                 error "FMD wasn't expired by ping"
4353 }
4354 run_test 36g "FMD cache expiry ====================="
4355
4356 test_36h() {
4357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4358
4359         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4360         subr_36fh "0x80000227"
4361 }
4362 run_test 36h "utime on file racing with OST BRW write =========="
4363
4364 test_36i() {
4365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4366
4367         test_mkdir $DIR/$tdir
4368         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4369
4370         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4371         local new_mtime=$((mtime + 200))
4372
4373         #change Modify time of striped dir
4374         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4375                         error "change mtime failed"
4376
4377         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4378
4379         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4380 }
4381 run_test 36i "change mtime on striped directory"
4382
4383 # test_37 - duplicate with tests 32q 32r
4384
4385 test_38() {
4386         local file=$DIR/$tfile
4387         touch $file
4388         openfile -f O_DIRECTORY $file
4389         local RC=$?
4390         local ENOTDIR=20
4391         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4392         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4393 }
4394 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4395
4396 test_39a() { # was test_39
4397         touch $DIR/$tfile
4398         touch $DIR/${tfile}2
4399 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4400 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4401 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4402         sleep 2
4403         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4404         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4405                 echo "mtime"
4406                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4407                 echo "atime"
4408                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4409                 echo "ctime"
4410                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4411                 error "O_TRUNC didn't change timestamps"
4412         fi
4413 }
4414 run_test 39a "mtime changed on create"
4415
4416 test_39b() {
4417         test_mkdir -c1 $DIR/$tdir
4418         cp -p /etc/passwd $DIR/$tdir/fopen
4419         cp -p /etc/passwd $DIR/$tdir/flink
4420         cp -p /etc/passwd $DIR/$tdir/funlink
4421         cp -p /etc/passwd $DIR/$tdir/frename
4422         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4423
4424         sleep 1
4425         echo "aaaaaa" >> $DIR/$tdir/fopen
4426         echo "aaaaaa" >> $DIR/$tdir/flink
4427         echo "aaaaaa" >> $DIR/$tdir/funlink
4428         echo "aaaaaa" >> $DIR/$tdir/frename
4429
4430         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4431         local link_new=`stat -c %Y $DIR/$tdir/flink`
4432         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4433         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4434
4435         cat $DIR/$tdir/fopen > /dev/null
4436         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4437         rm -f $DIR/$tdir/funlink2
4438         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4439
4440         for (( i=0; i < 2; i++ )) ; do
4441                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4442                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4443                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4444                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4445
4446                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4447                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4448                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4449                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4450
4451                 cancel_lru_locks $OSC
4452                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4453         done
4454 }
4455 run_test 39b "mtime change on open, link, unlink, rename  ======"
4456
4457 # this should be set to past
4458 TEST_39_MTIME=`date -d "1 year ago" +%s`
4459
4460 # bug 11063
4461 test_39c() {
4462         touch $DIR1/$tfile
4463         sleep 2
4464         local mtime0=`stat -c %Y $DIR1/$tfile`
4465
4466         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4467         local mtime1=`stat -c %Y $DIR1/$tfile`
4468         [ "$mtime1" = $TEST_39_MTIME ] || \
4469                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4470
4471         local d1=`date +%s`
4472         echo hello >> $DIR1/$tfile
4473         local d2=`date +%s`
4474         local mtime2=`stat -c %Y $DIR1/$tfile`
4475         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4476                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4477
4478         mv $DIR1/$tfile $DIR1/$tfile-1
4479
4480         for (( i=0; i < 2; i++ )) ; do
4481                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4482                 [ "$mtime2" = "$mtime3" ] || \
4483                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4484
4485                 cancel_lru_locks $OSC
4486                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4487         done
4488 }
4489 run_test 39c "mtime change on rename ==========================="
4490
4491 # bug 21114
4492 test_39d() {
4493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4494
4495         touch $DIR1/$tfile
4496         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4497
4498         for (( i=0; i < 2; i++ )) ; do
4499                 local mtime=`stat -c %Y $DIR1/$tfile`
4500                 [ $mtime = $TEST_39_MTIME ] || \
4501                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4502
4503                 cancel_lru_locks $OSC
4504                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4505         done
4506 }
4507 run_test 39d "create, utime, stat =============================="
4508
4509 # bug 21114
4510 test_39e() {
4511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4512
4513         touch $DIR1/$tfile
4514         local mtime1=`stat -c %Y $DIR1/$tfile`
4515
4516         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4517
4518         for (( i=0; i < 2; i++ )) ; do
4519                 local mtime2=`stat -c %Y $DIR1/$tfile`
4520                 [ $mtime2 = $TEST_39_MTIME ] || \
4521                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4522
4523                 cancel_lru_locks $OSC
4524                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4525         done
4526 }
4527 run_test 39e "create, stat, utime, stat ========================"
4528
4529 # bug 21114
4530 test_39f() {
4531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4532
4533         touch $DIR1/$tfile
4534         mtime1=`stat -c %Y $DIR1/$tfile`
4535
4536         sleep 2
4537         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4538
4539         for (( i=0; i < 2; i++ )) ; do
4540                 local mtime2=`stat -c %Y $DIR1/$tfile`
4541                 [ $mtime2 = $TEST_39_MTIME ] || \
4542                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4543
4544                 cancel_lru_locks $OSC
4545                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4546         done
4547 }
4548 run_test 39f "create, stat, sleep, utime, stat ================="
4549
4550 # bug 11063
4551 test_39g() {
4552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4553
4554         echo hello >> $DIR1/$tfile
4555         local mtime1=`stat -c %Y $DIR1/$tfile`
4556
4557         sleep 2
4558         chmod o+r $DIR1/$tfile
4559
4560         for (( i=0; i < 2; i++ )) ; do
4561                 local mtime2=`stat -c %Y $DIR1/$tfile`
4562                 [ "$mtime1" = "$mtime2" ] || \
4563                         error "lost mtime: $mtime2, should be $mtime1"
4564
4565                 cancel_lru_locks $OSC
4566                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4567         done
4568 }
4569 run_test 39g "write, chmod, stat ==============================="
4570
4571 # bug 11063
4572 test_39h() {
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         touch $DIR1/$tfile
4576         sleep 1
4577
4578         local d1=`date`
4579         echo hello >> $DIR1/$tfile
4580         local mtime1=`stat -c %Y $DIR1/$tfile`
4581
4582         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4583         local d2=`date`
4584         if [ "$d1" != "$d2" ]; then
4585                 echo "write and touch not within one second"
4586         else
4587                 for (( i=0; i < 2; i++ )) ; do
4588                         local mtime2=`stat -c %Y $DIR1/$tfile`
4589                         [ "$mtime2" = $TEST_39_MTIME ] || \
4590                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4591
4592                         cancel_lru_locks $OSC
4593                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4594                 done
4595         fi
4596 }
4597 run_test 39h "write, utime within one second, stat ============="
4598
4599 test_39i() {
4600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4601
4602         touch $DIR1/$tfile
4603         sleep 1
4604
4605         echo hello >> $DIR1/$tfile
4606         local mtime1=`stat -c %Y $DIR1/$tfile`
4607
4608         mv $DIR1/$tfile $DIR1/$tfile-1
4609
4610         for (( i=0; i < 2; i++ )) ; do
4611                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4612
4613                 [ "$mtime1" = "$mtime2" ] || \
4614                         error "lost mtime: $mtime2, should be $mtime1"
4615
4616                 cancel_lru_locks $OSC
4617                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4618         done
4619 }
4620 run_test 39i "write, rename, stat =============================="
4621
4622 test_39j() {
4623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4624
4625         start_full_debug_logging
4626         touch $DIR1/$tfile
4627         sleep 1
4628
4629         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4630         lctl set_param fail_loc=0x80000412
4631         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4632                 error "multiop failed"
4633         local multipid=$!
4634         local mtime1=`stat -c %Y $DIR1/$tfile`
4635
4636         mv $DIR1/$tfile $DIR1/$tfile-1
4637
4638         kill -USR1 $multipid
4639         wait $multipid || error "multiop close failed"
4640
4641         for (( i=0; i < 2; i++ )) ; do
4642                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4643                 [ "$mtime1" = "$mtime2" ] ||
4644                         error "mtime is lost on close: $mtime2, " \
4645                               "should be $mtime1"
4646
4647                 cancel_lru_locks
4648                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4649         done
4650         lctl set_param fail_loc=0
4651         stop_full_debug_logging
4652 }
4653 run_test 39j "write, rename, close, stat ======================="
4654
4655 test_39k() {
4656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4657
4658         touch $DIR1/$tfile
4659         sleep 1
4660
4661         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4662         local multipid=$!
4663         local mtime1=`stat -c %Y $DIR1/$tfile`
4664
4665         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4666
4667         kill -USR1 $multipid
4668         wait $multipid || error "multiop close failed"
4669
4670         for (( i=0; i < 2; i++ )) ; do
4671                 local mtime2=`stat -c %Y $DIR1/$tfile`
4672
4673                 [ "$mtime2" = $TEST_39_MTIME ] || \
4674                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4675
4676                 cancel_lru_locks
4677                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4678         done
4679 }
4680 run_test 39k "write, utime, close, stat ========================"
4681
4682 # this should be set to future
4683 TEST_39_ATIME=`date -d "1 year" +%s`
4684
4685 test_39l() {
4686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4687         remote_mds_nodsh && skip "remote MDS with nodsh"
4688
4689         local atime_diff=$(do_facet $SINGLEMDS \
4690                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4691         rm -rf $DIR/$tdir
4692         mkdir -p $DIR/$tdir
4693
4694         # test setting directory atime to future
4695         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4696         local atime=$(stat -c %X $DIR/$tdir)
4697         [ "$atime" = $TEST_39_ATIME ] ||
4698                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4699
4700         # test setting directory atime from future to now
4701         local now=$(date +%s)
4702         touch -a -d @$now $DIR/$tdir
4703
4704         atime=$(stat -c %X $DIR/$tdir)
4705         [ "$atime" -eq "$now"  ] ||
4706                 error "atime is not updated from future: $atime, $now"
4707
4708         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4709         sleep 3
4710
4711         # test setting directory atime when now > dir atime + atime_diff
4712         local d1=$(date +%s)
4713         ls $DIR/$tdir
4714         local d2=$(date +%s)
4715         cancel_lru_locks mdc
4716         atime=$(stat -c %X $DIR/$tdir)
4717         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4718                 error "atime is not updated  : $atime, should be $d2"
4719
4720         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4721         sleep 3
4722
4723         # test not setting directory atime when now < dir atime + atime_diff
4724         ls $DIR/$tdir
4725         cancel_lru_locks mdc
4726         atime=$(stat -c %X $DIR/$tdir)
4727         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4728                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4729
4730         do_facet $SINGLEMDS \
4731                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4732 }
4733 run_test 39l "directory atime update ==========================="
4734
4735 test_39m() {
4736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4737
4738         touch $DIR1/$tfile
4739         sleep 2
4740         local far_past_mtime=$(date -d "May 29 1953" +%s)
4741         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4742
4743         touch -m -d @$far_past_mtime $DIR1/$tfile
4744         touch -a -d @$far_past_atime $DIR1/$tfile
4745
4746         for (( i=0; i < 2; i++ )) ; do
4747                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4748                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4749                         error "atime or mtime set incorrectly"
4750
4751                 cancel_lru_locks $OSC
4752                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4753         done
4754 }
4755 run_test 39m "test atime and mtime before 1970"
4756
4757 test_39n() { # LU-3832
4758         remote_mds_nodsh && skip "remote MDS with nodsh"
4759
4760         local atime_diff=$(do_facet $SINGLEMDS \
4761                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4762         local atime0
4763         local atime1
4764         local atime2
4765
4766         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4767
4768         rm -rf $DIR/$tfile
4769         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4770         atime0=$(stat -c %X $DIR/$tfile)
4771
4772         sleep 5
4773         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4774         atime1=$(stat -c %X $DIR/$tfile)
4775
4776         sleep 5
4777         cancel_lru_locks mdc
4778         cancel_lru_locks osc
4779         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4780         atime2=$(stat -c %X $DIR/$tfile)
4781
4782         do_facet $SINGLEMDS \
4783                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4784
4785         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4786         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4787 }
4788 run_test 39n "check that O_NOATIME is honored"
4789
4790 test_39o() {
4791         TESTDIR=$DIR/$tdir/$tfile
4792         [ -e $TESTDIR ] && rm -rf $TESTDIR
4793         mkdir -p $TESTDIR
4794         cd $TESTDIR
4795         links1=2
4796         ls
4797         mkdir a b
4798         ls
4799         links2=$(stat -c %h .)
4800         [ $(($links1 + 2)) != $links2 ] &&
4801                 error "wrong links count $(($links1 + 2)) != $links2"
4802         rmdir b
4803         links3=$(stat -c %h .)
4804         [ $(($links1 + 1)) != $links3 ] &&
4805                 error "wrong links count $links1 != $links3"
4806         return 0
4807 }
4808 run_test 39o "directory cached attributes updated after create"
4809
4810 test_39p() {
4811         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4812
4813         local MDTIDX=1
4814         TESTDIR=$DIR/$tdir/$tdir
4815         [ -e $TESTDIR ] && rm -rf $TESTDIR
4816         test_mkdir -p $TESTDIR
4817         cd $TESTDIR
4818         links1=2
4819         ls
4820         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4821         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4822         ls
4823         links2=$(stat -c %h .)
4824         [ $(($links1 + 2)) != $links2 ] &&
4825                 error "wrong links count $(($links1 + 2)) != $links2"
4826         rmdir remote_dir2
4827         links3=$(stat -c %h .)
4828         [ $(($links1 + 1)) != $links3 ] &&
4829                 error "wrong links count $links1 != $links3"
4830         return 0
4831 }
4832 run_test 39p "remote directory cached attributes updated after create ========"
4833
4834 test_39r() {
4835         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4836                 skip "no atime update on old OST"
4837         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4838                 skip_env "ldiskfs only test"
4839         fi
4840
4841         local saved_adiff
4842         saved_adiff=$(do_facet ost1 \
4843                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4844         stack_trap "do_facet ost1 \
4845                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4846
4847         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4848
4849         $LFS setstripe -i 0 $DIR/$tfile
4850         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4851                 error "can't write initial file"
4852         cancel_lru_locks osc
4853
4854         # exceed atime_diff and access file
4855         sleep 6
4856         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4857                 error "can't udpate atime"
4858
4859         local atime_cli=$(stat -c %X $DIR/$tfile)
4860         echo "client atime: $atime_cli"
4861         # allow atime update to be written to device
4862         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4863         sleep 5
4864
4865         local ostdev=$(ostdevname 1)
4866         local fid=($(lfs getstripe -y $DIR/$tfile |
4867                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4868         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4869         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4870
4871         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4872         local atime_ost=$(do_facet ost1 "$cmd" |&
4873                           awk -F'[: ]' '/atime:/ { print $4 }')
4874         (( atime_cli == atime_ost )) ||
4875                 error "atime on client $atime_cli != ost $atime_ost"
4876 }
4877 run_test 39r "lazy atime update on OST"
4878
4879 test_39q() { # LU-8041
4880         local testdir=$DIR/$tdir
4881         mkdir -p $testdir
4882         multiop_bg_pause $testdir D_c || error "multiop failed"
4883         local multipid=$!
4884         cancel_lru_locks mdc
4885         kill -USR1 $multipid
4886         local atime=$(stat -c %X $testdir)
4887         [ "$atime" -ne 0 ] || error "atime is zero"
4888 }
4889 run_test 39q "close won't zero out atime"
4890
4891 test_40() {
4892         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4893         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4894                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4895         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4896                 error "$tfile is not 4096 bytes in size"
4897 }
4898 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4899
4900 test_41() {
4901         # bug 1553
4902         small_write $DIR/f41 18
4903 }
4904 run_test 41 "test small file write + fstat ====================="
4905
4906 count_ost_writes() {
4907         lctl get_param -n ${OSC}.*.stats |
4908                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4909                         END { printf("%0.0f", writes) }'
4910 }
4911
4912 # decent default
4913 WRITEBACK_SAVE=500
4914 DIRTY_RATIO_SAVE=40
4915 MAX_DIRTY_RATIO=50
4916 BG_DIRTY_RATIO_SAVE=10
4917 MAX_BG_DIRTY_RATIO=25
4918
4919 start_writeback() {
4920         trap 0
4921         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4922         # dirty_ratio, dirty_background_ratio
4923         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4924                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4925                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4926                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4927         else
4928                 # if file not here, we are a 2.4 kernel
4929                 kill -CONT `pidof kupdated`
4930         fi
4931 }
4932
4933 stop_writeback() {
4934         # setup the trap first, so someone cannot exit the test at the
4935         # exact wrong time and mess up a machine
4936         trap start_writeback EXIT
4937         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4938         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4939                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4940                 sysctl -w vm.dirty_writeback_centisecs=0
4941                 sysctl -w vm.dirty_writeback_centisecs=0
4942                 # save and increase /proc/sys/vm/dirty_ratio
4943                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4944                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4945                 # save and increase /proc/sys/vm/dirty_background_ratio
4946                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4947                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4948         else
4949                 # if file not here, we are a 2.4 kernel
4950                 kill -STOP `pidof kupdated`
4951         fi
4952 }
4953
4954 # ensure that all stripes have some grant before we test client-side cache
4955 setup_test42() {
4956         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4957                 dd if=/dev/zero of=$i bs=4k count=1
4958                 rm $i
4959         done
4960 }
4961
4962 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4963 # file truncation, and file removal.
4964 test_42a() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         setup_test42
4968         cancel_lru_locks $OSC
4969         stop_writeback
4970         sync; sleep 1; sync # just to be safe
4971         BEFOREWRITES=`count_ost_writes`
4972         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4973         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4974         AFTERWRITES=`count_ost_writes`
4975         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4976                 error "$BEFOREWRITES < $AFTERWRITES"
4977         start_writeback
4978 }
4979 run_test 42a "ensure that we don't flush on close"
4980
4981 test_42b() {
4982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4983
4984         setup_test42
4985         cancel_lru_locks $OSC
4986         stop_writeback
4987         sync
4988         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4989         BEFOREWRITES=$(count_ost_writes)
4990         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4991         AFTERWRITES=$(count_ost_writes)
4992         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4993                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4994         fi
4995         BEFOREWRITES=$(count_ost_writes)
4996         sync || error "sync: $?"
4997         AFTERWRITES=$(count_ost_writes)
4998         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4999                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5000         fi
5001         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5002         start_writeback
5003         return 0
5004 }
5005 run_test 42b "test destroy of file with cached dirty data ======"
5006
5007 # if these tests just want to test the effect of truncation,
5008 # they have to be very careful.  consider:
5009 # - the first open gets a {0,EOF}PR lock
5010 # - the first write conflicts and gets a {0, count-1}PW
5011 # - the rest of the writes are under {count,EOF}PW
5012 # - the open for truncate tries to match a {0,EOF}PR
5013 #   for the filesize and cancels the PWs.
5014 # any number of fixes (don't get {0,EOF} on open, match
5015 # composite locks, do smarter file size management) fix
5016 # this, but for now we want these tests to verify that
5017 # the cancellation with truncate intent works, so we
5018 # start the file with a full-file pw lock to match against
5019 # until the truncate.
5020 trunc_test() {
5021         test=$1
5022         file=$DIR/$test
5023         offset=$2
5024         cancel_lru_locks $OSC
5025         stop_writeback
5026         # prime the file with 0,EOF PW to match
5027         touch $file
5028         $TRUNCATE $file 0
5029         sync; sync
5030         # now the real test..
5031         dd if=/dev/zero of=$file bs=1024 count=100
5032         BEFOREWRITES=`count_ost_writes`
5033         $TRUNCATE $file $offset
5034         cancel_lru_locks $OSC
5035         AFTERWRITES=`count_ost_writes`
5036         start_writeback
5037 }
5038
5039 test_42c() {
5040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5041
5042         trunc_test 42c 1024
5043         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5044                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5045         rm $file
5046 }
5047 run_test 42c "test partial truncate of file with cached dirty data"
5048
5049 test_42d() {
5050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5051
5052         trunc_test 42d 0
5053         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5054                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5055         rm $file
5056 }
5057 run_test 42d "test complete truncate of file with cached dirty data"
5058
5059 test_42e() { # bug22074
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         local TDIR=$DIR/${tdir}e
5063         local pages=16 # hardcoded 16 pages, don't change it.
5064         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5065         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5066         local max_dirty_mb
5067         local warmup_files
5068
5069         test_mkdir $DIR/${tdir}e
5070         $LFS setstripe -c 1 $TDIR
5071         createmany -o $TDIR/f $files
5072
5073         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5074
5075         # we assume that with $OSTCOUNT files, at least one of them will
5076         # be allocated on OST0.
5077         warmup_files=$((OSTCOUNT * max_dirty_mb))
5078         createmany -o $TDIR/w $warmup_files
5079
5080         # write a large amount of data into one file and sync, to get good
5081         # avail_grant number from OST.
5082         for ((i=0; i<$warmup_files; i++)); do
5083                 idx=$($LFS getstripe -i $TDIR/w$i)
5084                 [ $idx -ne 0 ] && continue
5085                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5086                 break
5087         done
5088         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5089         sync
5090         $LCTL get_param $proc_osc0/cur_dirty_bytes
5091         $LCTL get_param $proc_osc0/cur_grant_bytes
5092
5093         # create as much dirty pages as we can while not to trigger the actual
5094         # RPCs directly. but depends on the env, VFS may trigger flush during this
5095         # period, hopefully we are good.
5096         for ((i=0; i<$warmup_files; i++)); do
5097                 idx=$($LFS getstripe -i $TDIR/w$i)
5098                 [ $idx -ne 0 ] && continue
5099                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5100         done
5101         $LCTL get_param $proc_osc0/cur_dirty_bytes
5102         $LCTL get_param $proc_osc0/cur_grant_bytes
5103
5104         # perform the real test
5105         $LCTL set_param $proc_osc0/rpc_stats 0
5106         for ((;i<$files; i++)); do
5107                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5108                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5109         done
5110         sync
5111         $LCTL get_param $proc_osc0/rpc_stats
5112
5113         local percent=0
5114         local have_ppr=false
5115         $LCTL get_param $proc_osc0/rpc_stats |
5116                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5117                         # skip lines until we are at the RPC histogram data
5118                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5119                         $have_ppr || continue
5120
5121                         # we only want the percent stat for < 16 pages
5122                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5123
5124                         percent=$((percent + WPCT))
5125                         if [[ $percent -gt 15 ]]; then
5126                                 error "less than 16-pages write RPCs" \
5127                                       "$percent% > 15%"
5128                                 break
5129                         fi
5130                 done
5131         rm -rf $TDIR
5132 }
5133 run_test 42e "verify sub-RPC writes are not done synchronously"
5134
5135 test_43A() { # was test_43
5136         test_mkdir $DIR/$tdir
5137         cp -p /bin/ls $DIR/$tdir/$tfile
5138         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5139         pid=$!
5140         # give multiop a chance to open
5141         sleep 1
5142
5143         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5144         kill -USR1 $pid
5145         # Wait for multiop to exit
5146         wait $pid
5147 }
5148 run_test 43A "execution of file opened for write should return -ETXTBSY"
5149
5150 test_43a() {
5151         test_mkdir $DIR/$tdir
5152         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5153         $DIR/$tdir/sleep 60 &
5154         SLEEP_PID=$!
5155         # Make sure exec of $tdir/sleep wins race with truncate
5156         sleep 1
5157         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5158         kill $SLEEP_PID
5159 }
5160 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5161
5162 test_43b() {
5163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5164
5165         test_mkdir $DIR/$tdir
5166         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5167         $DIR/$tdir/sleep 60 &
5168         SLEEP_PID=$!
5169         # Make sure exec of $tdir/sleep wins race with truncate
5170         sleep 1
5171         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5172         kill $SLEEP_PID
5173 }
5174 run_test 43b "truncate of file being executed should return -ETXTBSY"
5175
5176 test_43c() {
5177         local testdir="$DIR/$tdir"
5178         test_mkdir $testdir
5179         cp $SHELL $testdir/
5180         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5181                 ( cd $testdir && md5sum -c )
5182 }
5183 run_test 43c "md5sum of copy into lustre"
5184
5185 test_44A() { # was test_44
5186         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5187
5188         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5189         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5190 }
5191 run_test 44A "zero length read from a sparse stripe"
5192
5193 test_44a() {
5194         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
5195                 awk '{ print $2 }')
5196         [ -z "$nstripe" ] && skip "can't get stripe info"
5197         [[ $nstripe -gt $OSTCOUNT ]] &&
5198                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5199
5200         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
5201                 awk '{ print $2 }')
5202         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5203                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
5204                         awk '{ print $2 }')
5205         fi
5206
5207         OFFSETS="0 $((stride/2)) $((stride-1))"
5208         for offset in $OFFSETS; do
5209                 for i in $(seq 0 $((nstripe-1))); do
5210                         local GLOBALOFFSETS=""
5211                         # size in Bytes
5212                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5213                         local myfn=$DIR/d44a-$size
5214                         echo "--------writing $myfn at $size"
5215                         ll_sparseness_write $myfn $size ||
5216                                 error "ll_sparseness_write"
5217                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5218                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5219                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5220
5221                         for j in $(seq 0 $((nstripe-1))); do
5222                                 # size in Bytes
5223                                 size=$((((j + $nstripe )*$stride + $offset)))
5224                                 ll_sparseness_write $myfn $size ||
5225                                         error "ll_sparseness_write"
5226                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5227                         done
5228                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5229                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5230                         rm -f $myfn
5231                 done
5232         done
5233 }
5234 run_test 44a "test sparse pwrite ==============================="
5235
5236 dirty_osc_total() {
5237         tot=0
5238         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5239                 tot=$(($tot + $d))
5240         done
5241         echo $tot
5242 }
5243 do_dirty_record() {
5244         before=`dirty_osc_total`
5245         echo executing "\"$*\""
5246         eval $*
5247         after=`dirty_osc_total`
5248         echo before $before, after $after
5249 }
5250 test_45() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252
5253         f="$DIR/f45"
5254         # Obtain grants from OST if it supports it
5255         echo blah > ${f}_grant
5256         stop_writeback
5257         sync
5258         do_dirty_record "echo blah > $f"
5259         [[ $before -eq $after ]] && error "write wasn't cached"
5260         do_dirty_record "> $f"
5261         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5262         do_dirty_record "echo blah > $f"
5263         [[ $before -eq $after ]] && error "write wasn't cached"
5264         do_dirty_record "sync"
5265         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5266         do_dirty_record "echo blah > $f"
5267         [[ $before -eq $after ]] && error "write wasn't cached"
5268         do_dirty_record "cancel_lru_locks osc"
5269         [[ $before -gt $after ]] ||
5270                 error "lock cancellation didn't lower dirty count"
5271         start_writeback
5272 }
5273 run_test 45 "osc io page accounting ============================"
5274
5275 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5276 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5277 # objects offset and an assert hit when an rpc was built with 1023's mapped
5278 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5279 test_46() {
5280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5281
5282         f="$DIR/f46"
5283         stop_writeback
5284         sync
5285         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5286         sync
5287         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5288         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5289         sync
5290         start_writeback
5291 }
5292 run_test 46 "dirtying a previously written page ================"
5293
5294 # test_47 is removed "Device nodes check" is moved to test_28
5295
5296 test_48a() { # bug 2399
5297         [ "$mds1_FSTYPE" = "zfs" ] &&
5298         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5299                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5300
5301         test_mkdir $DIR/$tdir
5302         cd $DIR/$tdir
5303         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5304         test_mkdir $DIR/$tdir
5305         touch foo || error "'touch foo' failed after recreating cwd"
5306         test_mkdir bar
5307         touch .foo || error "'touch .foo' failed after recreating cwd"
5308         test_mkdir .bar
5309         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5310         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5311         cd . || error "'cd .' failed after recreating cwd"
5312         mkdir . && error "'mkdir .' worked after recreating cwd"
5313         rmdir . && error "'rmdir .' worked after recreating cwd"
5314         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5315         cd .. || error "'cd ..' failed after recreating cwd"
5316 }
5317 run_test 48a "Access renamed working dir (should return errors)="
5318
5319 test_48b() { # bug 2399
5320         rm -rf $DIR/$tdir
5321         test_mkdir $DIR/$tdir
5322         cd $DIR/$tdir
5323         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5324         touch foo && error "'touch foo' worked after removing cwd"
5325         mkdir foo && error "'mkdir foo' worked after removing cwd"
5326         touch .foo && error "'touch .foo' worked after removing cwd"
5327         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5328         ls . > /dev/null && error "'ls .' worked after removing cwd"
5329         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5330         mkdir . && error "'mkdir .' worked after removing cwd"
5331         rmdir . && error "'rmdir .' worked after removing cwd"
5332         ln -s . foo && error "'ln -s .' worked after removing cwd"
5333         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5334 }
5335 run_test 48b "Access removed working dir (should return errors)="
5336
5337 test_48c() { # bug 2350
5338         #lctl set_param debug=-1
5339         #set -vx
5340         rm -rf $DIR/$tdir
5341         test_mkdir -p $DIR/$tdir/dir
5342         cd $DIR/$tdir/dir
5343         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5344         $TRACE touch foo && error "touch foo worked after removing cwd"
5345         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5346         touch .foo && error "touch .foo worked after removing cwd"
5347         mkdir .foo && error "mkdir .foo worked after removing cwd"
5348         $TRACE ls . && error "'ls .' worked after removing cwd"
5349         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5350         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5351         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5352         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5353         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5354 }
5355 run_test 48c "Access removed working subdir (should return errors)"
5356
5357 test_48d() { # bug 2350
5358         #lctl set_param debug=-1
5359         #set -vx
5360         rm -rf $DIR/$tdir
5361         test_mkdir -p $DIR/$tdir/dir
5362         cd $DIR/$tdir/dir
5363         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5364         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5365         $TRACE touch foo && error "'touch foo' worked after removing parent"
5366         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5367         touch .foo && error "'touch .foo' worked after removing parent"
5368         mkdir .foo && error "mkdir .foo worked after removing parent"
5369         $TRACE ls . && error "'ls .' worked after removing parent"
5370         $TRACE ls .. && error "'ls ..' worked after removing parent"
5371         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5372         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5373         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5374         true
5375 }
5376 run_test 48d "Access removed parent subdir (should return errors)"
5377
5378 test_48e() { # bug 4134
5379         #lctl set_param debug=-1
5380         #set -vx
5381         rm -rf $DIR/$tdir
5382         test_mkdir -p $DIR/$tdir/dir
5383         cd $DIR/$tdir/dir
5384         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5385         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5386         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5387         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5388         # On a buggy kernel addition of "touch foo" after cd .. will
5389         # produce kernel oops in lookup_hash_it
5390         touch ../foo && error "'cd ..' worked after recreate parent"
5391         cd $DIR
5392         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5393 }
5394 run_test 48e "Access to recreated parent subdir (should return errors)"
5395
5396 test_48f() {
5397         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5398                 skip "need MDS >= 2.13.55"
5399         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5400         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5401                 skip "needs different host for mdt1 mdt2"
5402         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5403
5404         $LFS mkdir -i0 $DIR/$tdir
5405         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5406
5407         for d in sub1 sub2 sub3; do
5408                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5409                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5410                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5411         done
5412
5413         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5414 }
5415 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5416
5417 test_49() { # LU-1030
5418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5419         remote_ost_nodsh && skip "remote OST with nodsh"
5420
5421         # get ost1 size - $FSNAME-OST0000
5422         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5423                 awk '{ print $4 }')
5424         # write 800M at maximum
5425         [[ $ost1_size -lt 2 ]] && ost1_size=2
5426         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5427
5428         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5429         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5430         local dd_pid=$!
5431
5432         # change max_pages_per_rpc while writing the file
5433         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5434         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5435         # loop until dd process exits
5436         while ps ax -opid | grep -wq $dd_pid; do
5437                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5438                 sleep $((RANDOM % 5 + 1))
5439         done
5440         # restore original max_pages_per_rpc
5441         $LCTL set_param $osc1_mppc=$orig_mppc
5442         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5443 }
5444 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5445
5446 test_50() {
5447         # bug 1485
5448         test_mkdir $DIR/$tdir
5449         cd $DIR/$tdir
5450         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5451 }
5452 run_test 50 "special situations: /proc symlinks  ==============="
5453
5454 test_51a() {    # was test_51
5455         # bug 1516 - create an empty entry right after ".." then split dir
5456         test_mkdir -c1 $DIR/$tdir
5457         touch $DIR/$tdir/foo
5458         $MCREATE $DIR/$tdir/bar
5459         rm $DIR/$tdir/foo
5460         createmany -m $DIR/$tdir/longfile 201
5461         FNUM=202
5462         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5463                 $MCREATE $DIR/$tdir/longfile$FNUM
5464                 FNUM=$(($FNUM + 1))
5465                 echo -n "+"
5466         done
5467         echo
5468         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5469 }
5470 run_test 51a "special situations: split htree with empty entry =="
5471
5472 cleanup_print_lfs_df () {
5473         trap 0
5474         $LFS df
5475         $LFS df -i
5476 }
5477
5478 test_51b() {
5479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5480
5481         local dir=$DIR/$tdir
5482         local nrdirs=$((65536 + 100))
5483
5484         # cleanup the directory
5485         rm -fr $dir
5486
5487         test_mkdir -c1 $dir
5488
5489         $LFS df
5490         $LFS df -i
5491         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5492         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5493         [[ $numfree -lt $nrdirs ]] &&
5494                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5495
5496         # need to check free space for the directories as well
5497         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5498         numfree=$(( blkfree / $(fs_inode_ksize) ))
5499         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5500
5501         trap cleanup_print_lfs_df EXIT
5502
5503         # create files
5504         createmany -d $dir/d $nrdirs || {
5505                 unlinkmany $dir/d $nrdirs
5506                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5507         }
5508
5509         # really created :
5510         nrdirs=$(ls -U $dir | wc -l)
5511
5512         # unlink all but 100 subdirectories, then check it still works
5513         local left=100
5514         local delete=$((nrdirs - left))
5515
5516         $LFS df
5517         $LFS df -i
5518
5519         # for ldiskfs the nlink count should be 1, but this is OSD specific
5520         # and so this is listed for informational purposes only
5521         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5522         unlinkmany -d $dir/d $delete ||
5523                 error "unlink of first $delete subdirs failed"
5524
5525         echo "nlink between: $(stat -c %h $dir)"
5526         local found=$(ls -U $dir | wc -l)
5527         [ $found -ne $left ] &&
5528                 error "can't find subdirs: found only $found, expected $left"
5529
5530         unlinkmany -d $dir/d $delete $left ||
5531                 error "unlink of second $left subdirs failed"
5532         # regardless of whether the backing filesystem tracks nlink accurately
5533         # or not, the nlink count shouldn't be more than "." and ".." here
5534         local after=$(stat -c %h $dir)
5535         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5536                 echo "nlink after: $after"
5537
5538         cleanup_print_lfs_df
5539 }
5540 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5541
5542 test_51d() {
5543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5544         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5545
5546         test_mkdir $DIR/$tdir
5547         createmany -o $DIR/$tdir/t- 1000
5548         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5549         for N in $(seq 0 $((OSTCOUNT - 1))); do
5550                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5551                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5552                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5553                         '($1 == '$N') { objs += 1 } \
5554                         END { printf("%0.0f", objs) }')
5555                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5556         done
5557         unlinkmany $DIR/$tdir/t- 1000
5558
5559         NLAST=0
5560         for N in $(seq 1 $((OSTCOUNT - 1))); do
5561                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5562                         error "OST $N has less objects vs OST $NLAST" \
5563                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5564                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5565                         error "OST $N has less objects vs OST $NLAST" \
5566                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5567
5568                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5569                         error "OST $N has less #0 objects vs OST $NLAST" \
5570                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5571                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5572                         error "OST $N has less #0 objects vs OST $NLAST" \
5573                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5574                 NLAST=$N
5575         done
5576         rm -f $TMP/$tfile
5577 }
5578 run_test 51d "check object distribution"
5579
5580 test_51e() {
5581         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5582                 skip_env "ldiskfs only test"
5583         fi
5584
5585         test_mkdir -c1 $DIR/$tdir
5586         test_mkdir -c1 $DIR/$tdir/d0
5587
5588         touch $DIR/$tdir/d0/foo
5589         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5590                 error "file exceed 65000 nlink limit!"
5591         unlinkmany $DIR/$tdir/d0/f- 65001
5592         return 0
5593 }
5594 run_test 51e "check file nlink limit"
5595
5596 test_51f() {
5597         test_mkdir $DIR/$tdir
5598
5599         local max=100000
5600         local ulimit_old=$(ulimit -n)
5601         local spare=20 # number of spare fd's for scripts/libraries, etc.
5602         local mdt=$($LFS getstripe -m $DIR/$tdir)
5603         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5604
5605         echo "MDT$mdt numfree=$numfree, max=$max"
5606         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5607         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5608                 while ! ulimit -n $((numfree + spare)); do
5609                         numfree=$((numfree * 3 / 4))
5610                 done
5611                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5612         else
5613                 echo "left ulimit at $ulimit_old"
5614         fi
5615
5616         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5617                 unlinkmany $DIR/$tdir/f $numfree
5618                 error "create+open $numfree files in $DIR/$tdir failed"
5619         }
5620         ulimit -n $ulimit_old
5621
5622         # if createmany exits at 120s there will be fewer than $numfree files
5623         unlinkmany $DIR/$tdir/f $numfree || true
5624 }
5625 run_test 51f "check many open files limit"
5626
5627 test_52a() {
5628         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5629         test_mkdir $DIR/$tdir
5630         touch $DIR/$tdir/foo
5631         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5632         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5633         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5634         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5635         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5636                                         error "link worked"
5637         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5638         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5639         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5640                                                      error "lsattr"
5641         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5642         cp -r $DIR/$tdir $TMP/
5643         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5644 }
5645 run_test 52a "append-only flag test (should return errors)"
5646
5647 test_52b() {
5648         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5649         test_mkdir $DIR/$tdir
5650         touch $DIR/$tdir/foo
5651         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5652         cat test > $DIR/$tdir/foo && error "cat test worked"
5653         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5654         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5655         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5656                                         error "link worked"
5657         echo foo >> $DIR/$tdir/foo && error "echo worked"
5658         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5659         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5660         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5661         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5662                                                         error "lsattr"
5663         chattr -i $DIR/$tdir/foo || error "chattr failed"
5664
5665         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5666 }
5667 run_test 52b "immutable flag test (should return errors) ======="
5668
5669 test_53() {
5670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5671         remote_mds_nodsh && skip "remote MDS with nodsh"
5672         remote_ost_nodsh && skip "remote OST with nodsh"
5673
5674         local param
5675         local param_seq
5676         local ostname
5677         local mds_last
5678         local mds_last_seq
5679         local ost_last
5680         local ost_last_seq
5681         local ost_last_id
5682         local ostnum
5683         local node
5684         local found=false
5685         local support_last_seq=true
5686
5687         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5688                 support_last_seq=false
5689
5690         # only test MDT0000
5691         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5692         local value
5693         for value in $(do_facet $SINGLEMDS \
5694                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5695                 param=$(echo ${value[0]} | cut -d "=" -f1)
5696                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5697
5698                 if $support_last_seq; then
5699                         param_seq=$(echo $param |
5700                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5701                         mds_last_seq=$(do_facet $SINGLEMDS \
5702                                        $LCTL get_param -n $param_seq)
5703                 fi
5704                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5705
5706                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5707                 node=$(facet_active_host ost$((ostnum+1)))
5708                 param="obdfilter.$ostname.last_id"
5709                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5710                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5711                         ost_last_id=$ost_last
5712
5713                         if $support_last_seq; then
5714                                 ost_last_id=$(echo $ost_last |
5715                                               awk -F':' '{print $2}' |
5716                                               sed -e "s/^0x//g")
5717                                 ost_last_seq=$(echo $ost_last |
5718                                                awk -F':' '{print $1}')
5719                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5720                         fi
5721
5722                         if [[ $ost_last_id != $mds_last ]]; then
5723                                 error "$ost_last_id != $mds_last"
5724                         else
5725                                 found=true
5726                                 break
5727                         fi
5728                 done
5729         done
5730         $found || error "can not match last_seq/last_id for $mdtosc"
5731         return 0
5732 }
5733 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5734
5735 test_54a() {
5736         perl -MSocket -e ';' || skip "no Socket perl module installed"
5737
5738         $SOCKETSERVER $DIR/socket ||
5739                 error "$SOCKETSERVER $DIR/socket failed: $?"
5740         $SOCKETCLIENT $DIR/socket ||
5741                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5742         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5743 }
5744 run_test 54a "unix domain socket test =========================="
5745
5746 test_54b() {
5747         f="$DIR/f54b"
5748         mknod $f c 1 3
5749         chmod 0666 $f
5750         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5751 }
5752 run_test 54b "char device works in lustre ======================"
5753
5754 find_loop_dev() {
5755         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5756         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5757         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5758
5759         for i in $(seq 3 7); do
5760                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5761                 LOOPDEV=$LOOPBASE$i
5762                 LOOPNUM=$i
5763                 break
5764         done
5765 }
5766
5767 cleanup_54c() {
5768         local rc=0
5769         loopdev="$DIR/loop54c"
5770
5771         trap 0
5772         $UMOUNT $DIR/$tdir || rc=$?
5773         losetup -d $loopdev || true
5774         losetup -d $LOOPDEV || true
5775         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5776         return $rc
5777 }
5778
5779 test_54c() {
5780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5781
5782         loopdev="$DIR/loop54c"
5783
5784         find_loop_dev
5785         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5786         trap cleanup_54c EXIT
5787         mknod $loopdev b 7 $LOOPNUM
5788         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5789         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5790         losetup $loopdev $DIR/$tfile ||
5791                 error "can't set up $loopdev for $DIR/$tfile"
5792         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5793         test_mkdir $DIR/$tdir
5794         mount -t ext2 $loopdev $DIR/$tdir ||
5795                 error "error mounting $loopdev on $DIR/$tdir"
5796         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5797                 error "dd write"
5798         df $DIR/$tdir
5799         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5800                 error "dd read"
5801         cleanup_54c
5802 }
5803 run_test 54c "block device works in lustre ====================="
5804
5805 test_54d() {
5806         f="$DIR/f54d"
5807         string="aaaaaa"
5808         mknod $f p
5809         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5810 }
5811 run_test 54d "fifo device works in lustre ======================"
5812
5813 test_54e() {
5814         f="$DIR/f54e"
5815         string="aaaaaa"
5816         cp -aL /dev/console $f
5817         echo $string > $f || error "echo $string to $f failed"
5818 }
5819 run_test 54e "console/tty device works in lustre ======================"
5820
5821 test_56a() {
5822         local numfiles=3
5823         local dir=$DIR/$tdir
5824
5825         rm -rf $dir
5826         test_mkdir -p $dir/dir
5827         for i in $(seq $numfiles); do
5828                 touch $dir/file$i
5829                 touch $dir/dir/file$i
5830         done
5831
5832         local numcomp=$($LFS getstripe --component-count $dir)
5833
5834         [[ $numcomp == 0 ]] && numcomp=1
5835
5836         # test lfs getstripe with --recursive
5837         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5838
5839         [[ $filenum -eq $((numfiles * 2)) ]] ||
5840                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5841         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5842         [[ $filenum -eq $numfiles ]] ||
5843                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5844         echo "$LFS getstripe showed obdidx or l_ost_idx"
5845
5846         # test lfs getstripe with file instead of dir
5847         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5848         [[ $filenum -eq 1 ]] ||
5849                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5850         echo "$LFS getstripe file1 passed"
5851
5852         #test lfs getstripe with --verbose
5853         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5854         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5855                 error "$LFS getstripe --verbose $dir: "\
5856                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5857         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5858                 error "$LFS getstripe $dir: showed lmm_magic"
5859
5860         #test lfs getstripe with -v prints lmm_fid
5861         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5862         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5863                 error "$LFS getstripe -v $dir: "\
5864                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5865         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5866                 error "$LFS getstripe $dir: showed lmm_fid by default"
5867         echo "$LFS getstripe --verbose passed"
5868
5869         #check for FID information
5870         local fid1=$($LFS getstripe --fid $dir/file1)
5871         local fid2=$($LFS getstripe --verbose $dir/file1 |
5872                      awk '/lmm_fid: / { print $2; exit; }')
5873         local fid3=$($LFS path2fid $dir/file1)
5874
5875         [ "$fid1" != "$fid2" ] &&
5876                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5877         [ "$fid1" != "$fid3" ] &&
5878                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5879         echo "$LFS getstripe --fid passed"
5880
5881         #test lfs getstripe with --obd
5882         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5883                 error "$LFS getstripe --obd wrong_uuid: should return error"
5884
5885         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5886
5887         local ostidx=1
5888         local obduuid=$(ostuuid_from_index $ostidx)
5889         local found=$($LFS getstripe -r --obd $obduuid $dir |
5890                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5891
5892         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5893         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5894                 ((filenum--))
5895         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5896                 ((filenum--))
5897
5898         [[ $found -eq $filenum ]] ||
5899                 error "$LFS getstripe --obd: found $found expect $filenum"
5900         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5901                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5902                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5903                 error "$LFS getstripe --obd: should not show file on other obd"
5904         echo "$LFS getstripe --obd passed"
5905 }
5906 run_test 56a "check $LFS getstripe"
5907
5908 test_56b() {
5909         local dir=$DIR/$tdir
5910         local numdirs=3
5911
5912         test_mkdir $dir
5913         for i in $(seq $numdirs); do
5914                 test_mkdir $dir/dir$i
5915         done
5916
5917         # test lfs getdirstripe default mode is non-recursion, which is
5918         # different from lfs getstripe
5919         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5920
5921         [[ $dircnt -eq 1 ]] ||
5922                 error "$LFS getdirstripe: found $dircnt, not 1"
5923         dircnt=$($LFS getdirstripe --recursive $dir |
5924                 grep -c lmv_stripe_count)
5925         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5926                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5927 }
5928 run_test 56b "check $LFS getdirstripe"
5929
5930 test_56c() {
5931         remote_ost_nodsh && skip "remote OST with nodsh"
5932
5933         local ost_idx=0
5934         local ost_name=$(ostname_from_index $ost_idx)
5935         local old_status=$(ost_dev_status $ost_idx)
5936         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5937
5938         [[ -z "$old_status" ]] ||
5939                 skip_env "OST $ost_name is in $old_status status"
5940
5941         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5942         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5943                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5944         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5945                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5946                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5947         fi
5948
5949         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5950                 error "$LFS df -v showing inactive devices"
5951         sleep_maxage
5952
5953         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5954
5955         [[ "$new_status" =~ "D" ]] ||
5956                 error "$ost_name status is '$new_status', missing 'D'"
5957         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5958                 [[ "$new_status" =~ "N" ]] ||
5959                         error "$ost_name status is '$new_status', missing 'N'"
5960         fi
5961         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5962                 [[ "$new_status" =~ "f" ]] ||
5963                         error "$ost_name status is '$new_status', missing 'f'"
5964         fi
5965
5966         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5967         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5968                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5969         [[ -z "$p" ]] && restore_lustre_params < $p || true
5970         sleep_maxage
5971
5972         new_status=$(ost_dev_status $ost_idx)
5973         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5974                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5975         # can't check 'f' as devices may actually be on flash
5976 }
5977 run_test 56c "check 'lfs df' showing device status"
5978
5979 test_56d() {
5980         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5981         local osts=$($LFS df -v $MOUNT | grep -c OST)
5982
5983         $LFS df $MOUNT
5984
5985         (( mdts == MDSCOUNT )) ||
5986                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5987         (( osts == OSTCOUNT )) ||
5988                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5989 }
5990 run_test 56d "'lfs df -v' prints only configured devices"
5991
5992 NUMFILES=3
5993 NUMDIRS=3
5994 setup_56() {
5995         local local_tdir="$1"
5996         local local_numfiles="$2"
5997         local local_numdirs="$3"
5998         local dir_params="$4"
5999         local dir_stripe_params="$5"
6000
6001         if [ ! -d "$local_tdir" ] ; then
6002                 test_mkdir -p $dir_stripe_params $local_tdir
6003                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6004                 for i in $(seq $local_numfiles) ; do
6005                         touch $local_tdir/file$i
6006                 done
6007                 for i in $(seq $local_numdirs) ; do
6008                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6009                         for j in $(seq $local_numfiles) ; do
6010                                 touch $local_tdir/dir$i/file$j
6011                         done
6012                 done
6013         fi
6014 }
6015
6016 setup_56_special() {
6017         local local_tdir=$1
6018         local local_numfiles=$2
6019         local local_numdirs=$3
6020
6021         setup_56 $local_tdir $local_numfiles $local_numdirs
6022
6023         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6024                 for i in $(seq $local_numfiles) ; do
6025                         mknod $local_tdir/loop${i}b b 7 $i
6026                         mknod $local_tdir/null${i}c c 1 3
6027                         ln -s $local_tdir/file1 $local_tdir/link${i}
6028                 done
6029                 for i in $(seq $local_numdirs) ; do
6030                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6031                         mknod $local_tdir/dir$i/null${i}c c 1 3
6032                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6033                 done
6034         fi
6035 }
6036
6037 test_56g() {
6038         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6039         local expected=$(($NUMDIRS + 2))
6040
6041         setup_56 $dir $NUMFILES $NUMDIRS
6042
6043         # test lfs find with -name
6044         for i in $(seq $NUMFILES) ; do
6045                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6046
6047                 [ $nums -eq $expected ] ||
6048                         error "lfs find -name '*$i' $dir wrong: "\
6049                               "found $nums, expected $expected"
6050         done
6051 }
6052 run_test 56g "check lfs find -name"
6053
6054 test_56h() {
6055         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6056         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6057
6058         setup_56 $dir $NUMFILES $NUMDIRS
6059
6060         # test lfs find with ! -name
6061         for i in $(seq $NUMFILES) ; do
6062                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6063
6064                 [ $nums -eq $expected ] ||
6065                         error "lfs find ! -name '*$i' $dir wrong: "\
6066                               "found $nums, expected $expected"
6067         done
6068 }
6069 run_test 56h "check lfs find ! -name"
6070
6071 test_56i() {
6072         local dir=$DIR/$tdir
6073
6074         test_mkdir $dir
6075
6076         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6077         local out=$($cmd)
6078
6079         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6080 }
6081 run_test 56i "check 'lfs find -ost UUID' skips directories"
6082
6083 test_56j() {
6084         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6085
6086         setup_56_special $dir $NUMFILES $NUMDIRS
6087
6088         local expected=$((NUMDIRS + 1))
6089         local cmd="$LFS find -type d $dir"
6090         local nums=$($cmd | wc -l)
6091
6092         [ $nums -eq $expected ] ||
6093                 error "'$cmd' wrong: found $nums, expected $expected"
6094 }
6095 run_test 56j "check lfs find -type d"
6096
6097 test_56k() {
6098         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6099
6100         setup_56_special $dir $NUMFILES $NUMDIRS
6101
6102         local expected=$(((NUMDIRS + 1) * NUMFILES))
6103         local cmd="$LFS find -type f $dir"
6104         local nums=$($cmd | wc -l)
6105
6106         [ $nums -eq $expected ] ||
6107                 error "'$cmd' wrong: found $nums, expected $expected"
6108 }
6109 run_test 56k "check lfs find -type f"
6110
6111 test_56l() {
6112         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6113
6114         setup_56_special $dir $NUMFILES $NUMDIRS
6115
6116         local expected=$((NUMDIRS + NUMFILES))
6117         local cmd="$LFS find -type b $dir"
6118         local nums=$($cmd | wc -l)
6119
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56l "check lfs find -type b"
6124
6125 test_56m() {
6126         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6127
6128         setup_56_special $dir $NUMFILES $NUMDIRS
6129
6130         local expected=$((NUMDIRS + NUMFILES))
6131         local cmd="$LFS find -type c $dir"
6132         local nums=$($cmd | wc -l)
6133         [ $nums -eq $expected ] ||
6134                 error "'$cmd' wrong: found $nums, expected $expected"
6135 }
6136 run_test 56m "check lfs find -type c"
6137
6138 test_56n() {
6139         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6140         setup_56_special $dir $NUMFILES $NUMDIRS
6141
6142         local expected=$((NUMDIRS + NUMFILES))
6143         local cmd="$LFS find -type l $dir"
6144         local nums=$($cmd | wc -l)
6145
6146         [ $nums -eq $expected ] ||
6147                 error "'$cmd' wrong: found $nums, expected $expected"
6148 }
6149 run_test 56n "check lfs find -type l"
6150
6151 test_56o() {
6152         local dir=$DIR/$tdir
6153
6154         setup_56 $dir $NUMFILES $NUMDIRS
6155         utime $dir/file1 > /dev/null || error "utime (1)"
6156         utime $dir/file2 > /dev/null || error "utime (2)"
6157         utime $dir/dir1 > /dev/null || error "utime (3)"
6158         utime $dir/dir2 > /dev/null || error "utime (4)"
6159         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6160         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6161
6162         local expected=4
6163         local nums=$($LFS find -mtime +0 $dir | wc -l)
6164
6165         [ $nums -eq $expected ] ||
6166                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6167
6168         expected=12
6169         cmd="$LFS find -mtime 0 $dir"
6170         nums=$($cmd | wc -l)
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173 }
6174 run_test 56o "check lfs find -mtime for old files"
6175
6176 test_56ob() {
6177         local dir=$DIR/$tdir
6178         local expected=1
6179         local count=0
6180
6181         # just to make sure there is something that won't be found
6182         test_mkdir $dir
6183         touch $dir/$tfile.now
6184
6185         for age in year week day hour min; do
6186                 count=$((count + 1))
6187
6188                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6189                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6190                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6191
6192                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6193                 local nums=$($cmd | wc -l)
6194                 [ $nums -eq $expected ] ||
6195                         error "'$cmd' wrong: found $nums, expected $expected"
6196
6197                 cmd="$LFS find $dir -atime $count${age:0:1}"
6198                 nums=$($cmd | wc -l)
6199                 [ $nums -eq $expected ] ||
6200                         error "'$cmd' wrong: found $nums, expected $expected"
6201         done
6202
6203         sleep 2
6204         cmd="$LFS find $dir -ctime +1s -type f"
6205         nums=$($cmd | wc -l)
6206         (( $nums == $count * 2 + 1)) ||
6207                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6208 }
6209 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6210
6211 test_newerXY_base() {
6212         local x=$1
6213         local y=$2
6214         local dir=$DIR/$tdir
6215         local ref
6216         local negref
6217
6218         if [ $y == "t" ]; then
6219                 if [ $x == "b" ]; then
6220                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6221                 else
6222                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6223                 fi
6224         else
6225                 ref=$DIR/$tfile.newer.$x$y
6226                 touch $ref || error "touch $ref failed"
6227         fi
6228
6229         echo "before = $ref"
6230         sleep 2
6231         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6232         sleep 2
6233         if [ $y == "t" ]; then
6234                 if [ $x == "b" ]; then
6235                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6236                 else
6237                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6238                 fi
6239         else
6240                 negref=$DIR/$tfile.negnewer.$x$y
6241                 touch $negref || error "touch $negref failed"
6242         fi
6243
6244         echo "after = $negref"
6245         local cmd="$LFS find $dir -newer$x$y $ref"
6246         local nums=$(eval $cmd | wc -l)
6247         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6248
6249         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6250                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6251
6252         cmd="$LFS find $dir ! -newer$x$y $negref"
6253         nums=$(eval $cmd | wc -l)
6254         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6255                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6256
6257         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6258         nums=$(eval $cmd | wc -l)
6259         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6260                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6261
6262         rm -rf $DIR/*
6263 }
6264
6265 test_56oc() {
6266         test_newerXY_base "a" "a"
6267         test_newerXY_base "a" "m"
6268         test_newerXY_base "a" "c"
6269         test_newerXY_base "m" "a"
6270         test_newerXY_base "m" "m"
6271         test_newerXY_base "m" "c"
6272         test_newerXY_base "c" "a"
6273         test_newerXY_base "c" "m"
6274         test_newerXY_base "c" "c"
6275
6276         [[ -n "$sles_version" ]] &&
6277                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6278
6279         test_newerXY_base "a" "t"
6280         test_newerXY_base "m" "t"
6281         test_newerXY_base "c" "t"
6282
6283         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6284            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6285                 ! btime_supported && echo "btime unsupported" && return 0
6286
6287         test_newerXY_base "b" "b"
6288         test_newerXY_base "b" "t"
6289 }
6290 run_test 56oc "check lfs find -newerXY work"
6291
6292 btime_supported() {
6293         local dir=$DIR/$tdir
6294         local rc
6295
6296         mkdir -p $dir
6297         touch $dir/$tfile
6298         $LFS find $dir -btime -1d -type f
6299         rc=$?
6300         rm -rf $dir
6301         return $rc
6302 }
6303
6304 test_56od() {
6305         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6306                 ! btime_supported && skip "btime unsupported on MDS"
6307
6308         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6309                 ! btime_supported && skip "btime unsupported on clients"
6310
6311         local dir=$DIR/$tdir
6312         local ref=$DIR/$tfile.ref
6313         local negref=$DIR/$tfile.negref
6314
6315         mkdir $dir || error "mkdir $dir failed"
6316         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6317         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6318         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6319         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6320         touch $ref || error "touch $ref failed"
6321         # sleep 3 seconds at least
6322         sleep 3
6323
6324         local before=$(do_facet mds1 date +%s)
6325         local skew=$(($(date +%s) - before + 1))
6326
6327         if (( skew < 0 && skew > -5 )); then
6328                 sleep $((0 - skew + 1))
6329                 skew=0
6330         fi
6331
6332         # Set the dir stripe params to limit files all on MDT0,
6333         # otherwise we need to calc the max clock skew between
6334         # the client and MDTs.
6335         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6336         sleep 2
6337         touch $negref || error "touch $negref failed"
6338
6339         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6340         local nums=$($cmd | wc -l)
6341         local expected=$(((NUMFILES + 1) * NUMDIRS))
6342
6343         [ $nums -eq $expected ] ||
6344                 error "'$cmd' wrong: found $nums, expected $expected"
6345
6346         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6347         nums=$($cmd | wc -l)
6348         expected=$((NUMFILES + 1))
6349         [ $nums -eq $expected ] ||
6350                 error "'$cmd' wrong: found $nums, expected $expected"
6351
6352         [ $skew -lt 0 ] && return
6353
6354         local after=$(do_facet mds1 date +%s)
6355         local age=$((after - before + 1 + skew))
6356
6357         cmd="$LFS find $dir -btime -${age}s -type f"
6358         nums=$($cmd | wc -l)
6359         expected=$(((NUMFILES + 1) * NUMDIRS))
6360
6361         echo "Clock skew between client and server: $skew, age:$age"
6362         [ $nums -eq $expected ] ||
6363                 error "'$cmd' wrong: found $nums, expected $expected"
6364
6365         expected=$(($NUMDIRS + 1))
6366         cmd="$LFS find $dir -btime -${age}s -type d"
6367         nums=$($cmd | wc -l)
6368         [ $nums -eq $expected ] ||
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370         rm -f $ref $negref || error "Failed to remove $ref $negref"
6371 }
6372 run_test 56od "check lfs find -btime with units"
6373
6374 test_56p() {
6375         [ $RUNAS_ID -eq $UID ] &&
6376                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6377
6378         local dir=$DIR/$tdir
6379
6380         setup_56 $dir $NUMFILES $NUMDIRS
6381         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6382
6383         local expected=$NUMFILES
6384         local cmd="$LFS find -uid $RUNAS_ID $dir"
6385         local nums=$($cmd | wc -l)
6386
6387         [ $nums -eq $expected ] ||
6388                 error "'$cmd' wrong: found $nums, expected $expected"
6389
6390         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6391         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6392         nums=$($cmd | wc -l)
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395 }
6396 run_test 56p "check lfs find -uid and ! -uid"
6397
6398 test_56q() {
6399         [ $RUNAS_ID -eq $UID ] &&
6400                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6401
6402         local dir=$DIR/$tdir
6403
6404         setup_56 $dir $NUMFILES $NUMDIRS
6405         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6406
6407         local expected=$NUMFILES
6408         local cmd="$LFS find -gid $RUNAS_GID $dir"
6409         local nums=$($cmd | wc -l)
6410
6411         [ $nums -eq $expected ] ||
6412                 error "'$cmd' wrong: found $nums, expected $expected"
6413
6414         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6415         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6416         nums=$($cmd | wc -l)
6417         [ $nums -eq $expected ] ||
6418                 error "'$cmd' wrong: found $nums, expected $expected"
6419 }
6420 run_test 56q "check lfs find -gid and ! -gid"
6421
6422 test_56r() {
6423         local dir=$DIR/$tdir
6424
6425         setup_56 $dir $NUMFILES $NUMDIRS
6426
6427         local expected=12
6428         local cmd="$LFS find -size 0 -type f -lazy $dir"
6429         local nums=$($cmd | wc -l)
6430
6431         [ $nums -eq $expected ] ||
6432                 error "'$cmd' wrong: found $nums, expected $expected"
6433         cmd="$LFS find -size 0 -type f $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=0
6439         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6440         nums=$($cmd | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443         cmd="$LFS find ! -size 0 -type f $dir"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447
6448         echo "test" > $dir/$tfile
6449         echo "test2" > $dir/$tfile.2 && sync
6450         expected=1
6451         cmd="$LFS find -size 5 -type f -lazy $dir"
6452         nums=$($cmd | wc -l)
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455         cmd="$LFS find -size 5 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         expected=1
6461         cmd="$LFS find -size +5 -type f -lazy $dir"
6462         nums=$($cmd | wc -l)
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465         cmd="$LFS find -size +5 -type f $dir"
6466         nums=$($cmd | wc -l)
6467         [ $nums -eq $expected ] ||
6468                 error "'$cmd' wrong: found $nums, expected $expected"
6469
6470         expected=2
6471         cmd="$LFS find -size +0 -type f -lazy $dir"
6472         nums=$($cmd | wc -l)
6473         [ $nums -eq $expected ] ||
6474                 error "'$cmd' wrong: found $nums, expected $expected"
6475         cmd="$LFS find -size +0 -type f $dir"
6476         nums=$($cmd | wc -l)
6477         [ $nums -eq $expected ] ||
6478                 error "'$cmd' wrong: found $nums, expected $expected"
6479
6480         expected=2
6481         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485         cmd="$LFS find ! -size -5 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=12
6491         cmd="$LFS find -size -5 -type f -lazy $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495         cmd="$LFS find -size -5 -type f $dir"
6496         nums=$($cmd | wc -l)
6497         [ $nums -eq $expected ] ||
6498                 error "'$cmd' wrong: found $nums, expected $expected"
6499 }
6500 run_test 56r "check lfs find -size works"
6501
6502 test_56ra_sub() {
6503         local expected=$1
6504         local glimpses=$2
6505         local cmd="$3"
6506
6507         cancel_lru_locks $OSC
6508
6509         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6510         local nums=$($cmd | wc -l)
6511
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6516
6517         if (( rpcs_before + glimpses != rpcs_after )); then
6518                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6519                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6520
6521                 if [[ $glimpses == 0 ]]; then
6522                         error "'$cmd' should not send glimpse RPCs to OST"
6523                 else
6524                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6525                 fi
6526         fi
6527 }
6528
6529 test_56ra() {
6530         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6531                 skip "MDS < 2.12.58 doesn't return LSOM data"
6532         local dir=$DIR/$tdir
6533         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6534
6535         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6536
6537         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6538         $LCTL set_param -n llite.*.statahead_agl=0
6539         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6540
6541         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6542         # open and close all files to ensure LSOM is updated
6543         cancel_lru_locks $OSC
6544         find $dir -type f | xargs cat > /dev/null
6545
6546         #   expect_found  glimpse_rpcs  command_to_run
6547         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6548         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6549         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6550         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6551
6552         echo "test" > $dir/$tfile
6553         echo "test2" > $dir/$tfile.2 && sync
6554         cancel_lru_locks $OSC
6555         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6556
6557         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6558         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6559         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6560         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6561
6562         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6563         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6564         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6565         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6566         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6567         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6568 }
6569 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6570
6571 test_56rb() {
6572         local dir=$DIR/$tdir
6573         local tmp=$TMP/$tfile.log
6574         local mdt_idx;
6575
6576         test_mkdir -p $dir || error "failed to mkdir $dir"
6577         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6578                 error "failed to setstripe $dir/$tfile"
6579         mdt_idx=$($LFS getdirstripe -i $dir)
6580         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6581
6582         stack_trap "rm -f $tmp" EXIT
6583         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6584         ! grep -q obd_uuid $tmp ||
6585                 error "failed to find --size +100K --ost 0 $dir"
6586         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6587         ! grep -q obd_uuid $tmp ||
6588                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6589 }
6590 run_test 56rb "check lfs find --size --ost/--mdt works"
6591
6592 test_56s() { # LU-611 #LU-9369
6593         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6594
6595         local dir=$DIR/$tdir
6596         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6597
6598         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6599         for i in $(seq $NUMDIRS); do
6600                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6601         done
6602
6603         local expected=$NUMDIRS
6604         local cmd="$LFS find -c $OSTCOUNT $dir"
6605         local nums=$($cmd | wc -l)
6606
6607         [ $nums -eq $expected ] || {
6608                 $LFS getstripe -R $dir
6609                 error "'$cmd' wrong: found $nums, expected $expected"
6610         }
6611
6612         expected=$((NUMDIRS + onestripe))
6613         cmd="$LFS find -stripe-count +0 -type f $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] || {
6616                 $LFS getstripe -R $dir
6617                 error "'$cmd' wrong: found $nums, expected $expected"
6618         }
6619
6620         expected=$onestripe
6621         cmd="$LFS find -stripe-count 1 -type f $dir"
6622         nums=$($cmd | wc -l)
6623         [ $nums -eq $expected ] || {
6624                 $LFS getstripe -R $dir
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626         }
6627
6628         cmd="$LFS find -stripe-count -2 -type f $dir"
6629         nums=$($cmd | wc -l)
6630         [ $nums -eq $expected ] || {
6631                 $LFS getstripe -R $dir
6632                 error "'$cmd' wrong: found $nums, expected $expected"
6633         }
6634
6635         expected=0
6636         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6637         nums=$($cmd | wc -l)
6638         [ $nums -eq $expected ] || {
6639                 $LFS getstripe -R $dir
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641         }
6642 }
6643 run_test 56s "check lfs find -stripe-count works"
6644
6645 test_56t() { # LU-611 #LU-9369
6646         local dir=$DIR/$tdir
6647
6648         setup_56 $dir 0 $NUMDIRS
6649         for i in $(seq $NUMDIRS); do
6650                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6651         done
6652
6653         local expected=$NUMDIRS
6654         local cmd="$LFS find -S 8M $dir"
6655         local nums=$($cmd | wc -l)
6656
6657         [ $nums -eq $expected ] || {
6658                 $LFS getstripe -R $dir
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660         }
6661         rm -rf $dir
6662
6663         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6664
6665         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6666
6667         expected=$(((NUMDIRS + 1) * NUMFILES))
6668         cmd="$LFS find -stripe-size 512k -type f $dir"
6669         nums=$($cmd | wc -l)
6670         [ $nums -eq $expected ] ||
6671                 error "'$cmd' wrong: found $nums, expected $expected"
6672
6673         cmd="$LFS find -stripe-size +320k -type f $dir"
6674         nums=$($cmd | wc -l)
6675         [ $nums -eq $expected ] ||
6676                 error "'$cmd' wrong: found $nums, expected $expected"
6677
6678         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6679         cmd="$LFS find -stripe-size +200k -type f $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] ||
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683
6684         cmd="$LFS find -stripe-size -640k -type f $dir"
6685         nums=$($cmd | wc -l)
6686         [ $nums -eq $expected ] ||
6687                 error "'$cmd' wrong: found $nums, expected $expected"
6688
6689         expected=4
6690         cmd="$LFS find -stripe-size 256k -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         cmd="$LFS find -stripe-size -320k -type f $dir"
6696         nums=$($cmd | wc -l)
6697         [ $nums -eq $expected ] ||
6698                 error "'$cmd' wrong: found $nums, expected $expected"
6699
6700         expected=0
6701         cmd="$LFS find -stripe-size 1024k -type f $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] ||
6704                 error "'$cmd' wrong: found $nums, expected $expected"
6705 }
6706 run_test 56t "check lfs find -stripe-size works"
6707
6708 test_56u() { # LU-611
6709         local dir=$DIR/$tdir
6710
6711         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6712
6713         if [[ $OSTCOUNT -gt 1 ]]; then
6714                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6715                 onestripe=4
6716         else
6717                 onestripe=0
6718         fi
6719
6720         local expected=$(((NUMDIRS + 1) * NUMFILES))
6721         local cmd="$LFS find -stripe-index 0 -type f $dir"
6722         local nums=$($cmd | wc -l)
6723
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726
6727         expected=$onestripe
6728         cmd="$LFS find -stripe-index 1 -type f $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732
6733         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6734         nums=$($cmd | wc -l)
6735         [ $nums -eq $expected ] ||
6736                 error "'$cmd' wrong: found $nums, expected $expected"
6737
6738         expected=0
6739         # This should produce an error and not return any files
6740         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6741         nums=$($cmd 2>/dev/null | wc -l)
6742         [ $nums -eq $expected ] ||
6743                 error "'$cmd' wrong: found $nums, expected $expected"
6744
6745         if [[ $OSTCOUNT -gt 1 ]]; then
6746                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6747                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6748                 nums=$($cmd | wc -l)
6749                 [ $nums -eq $expected ] ||
6750                         error "'$cmd' wrong: found $nums, expected $expected"
6751         fi
6752 }
6753 run_test 56u "check lfs find -stripe-index works"
6754
6755 test_56v() {
6756         local mdt_idx=0
6757         local dir=$DIR/$tdir
6758
6759         setup_56 $dir $NUMFILES $NUMDIRS
6760
6761         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6762         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6763
6764         for file in $($LFS find -m $UUID $dir); do
6765                 file_midx=$($LFS getstripe -m $file)
6766                 [ $file_midx -eq $mdt_idx ] ||
6767                         error "lfs find -m $UUID != getstripe -m $file_midx"
6768         done
6769 }
6770 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6771
6772 test_56w() {
6773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6775
6776         local dir=$DIR/$tdir
6777
6778         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6779
6780         local stripe_size=$($LFS getstripe -S -d $dir) ||
6781                 error "$LFS getstripe -S -d $dir failed"
6782         stripe_size=${stripe_size%% *}
6783
6784         local file_size=$((stripe_size * OSTCOUNT))
6785         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6786         local required_space=$((file_num * file_size))
6787         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6788                            head -n1)
6789         [[ $free_space -le $((required_space / 1024)) ]] &&
6790                 skip_env "need $required_space, have $free_space kbytes"
6791
6792         local dd_bs=65536
6793         local dd_count=$((file_size / dd_bs))
6794
6795         # write data into the files
6796         local i
6797         local j
6798         local file
6799
6800         for i in $(seq $NUMFILES); do
6801                 file=$dir/file$i
6802                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6803                         error "write data into $file failed"
6804         done
6805         for i in $(seq $NUMDIRS); do
6806                 for j in $(seq $NUMFILES); do
6807                         file=$dir/dir$i/file$j
6808                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6809                                 error "write data into $file failed"
6810                 done
6811         done
6812
6813         # $LFS_MIGRATE will fail if hard link migration is unsupported
6814         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6815                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6816                         error "creating links to $dir/dir1/file1 failed"
6817         fi
6818
6819         local expected=-1
6820
6821         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6822
6823         # lfs_migrate file
6824         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6825
6826         echo "$cmd"
6827         eval $cmd || error "$cmd failed"
6828
6829         check_stripe_count $dir/file1 $expected
6830
6831         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6832         then
6833                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6834                 # OST 1 if it is on OST 0. This file is small enough to
6835                 # be on only one stripe.
6836                 file=$dir/migr_1_ost
6837                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6838                         error "write data into $file failed"
6839                 local obdidx=$($LFS getstripe -i $file)
6840                 local oldmd5=$(md5sum $file)
6841                 local newobdidx=0
6842
6843                 [[ $obdidx -eq 0 ]] && newobdidx=1
6844                 cmd="$LFS migrate -i $newobdidx $file"
6845                 echo $cmd
6846                 eval $cmd || error "$cmd failed"
6847
6848                 local realobdix=$($LFS getstripe -i $file)
6849                 local newmd5=$(md5sum $file)
6850
6851                 [[ $newobdidx -ne $realobdix ]] &&
6852                         error "new OST is different (was=$obdidx, "\
6853                               "wanted=$newobdidx, got=$realobdix)"
6854                 [[ "$oldmd5" != "$newmd5" ]] &&
6855                         error "md5sum differ: $oldmd5, $newmd5"
6856         fi
6857
6858         # lfs_migrate dir
6859         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6860         echo "$cmd"
6861         eval $cmd || error "$cmd failed"
6862
6863         for j in $(seq $NUMFILES); do
6864                 check_stripe_count $dir/dir1/file$j $expected
6865         done
6866
6867         # lfs_migrate works with lfs find
6868         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6869              $LFS_MIGRATE -y -c $expected"
6870         echo "$cmd"
6871         eval $cmd || error "$cmd failed"
6872
6873         for i in $(seq 2 $NUMFILES); do
6874                 check_stripe_count $dir/file$i $expected
6875         done
6876         for i in $(seq 2 $NUMDIRS); do
6877                 for j in $(seq $NUMFILES); do
6878                 check_stripe_count $dir/dir$i/file$j $expected
6879                 done
6880         done
6881 }
6882 run_test 56w "check lfs_migrate -c stripe_count works"
6883
6884 test_56wb() {
6885         local file1=$DIR/$tdir/file1
6886         local create_pool=false
6887         local initial_pool=$($LFS getstripe -p $DIR)
6888         local pool_list=()
6889         local pool=""
6890
6891         echo -n "Creating test dir..."
6892         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6893         echo "done."
6894
6895         echo -n "Creating test file..."
6896         touch $file1 || error "cannot create file"
6897         echo "done."
6898
6899         echo -n "Detecting existing pools..."
6900         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6901
6902         if [ ${#pool_list[@]} -gt 0 ]; then
6903                 echo "${pool_list[@]}"
6904                 for thispool in "${pool_list[@]}"; do
6905                         if [[ -z "$initial_pool" ||
6906                               "$initial_pool" != "$thispool" ]]; then
6907                                 pool="$thispool"
6908                                 echo "Using existing pool '$pool'"
6909                                 break
6910                         fi
6911                 done
6912         else
6913                 echo "none detected."
6914         fi
6915         if [ -z "$pool" ]; then
6916                 pool=${POOL:-testpool}
6917                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6918                 echo -n "Creating pool '$pool'..."
6919                 create_pool=true
6920                 pool_add $pool &> /dev/null ||
6921                         error "pool_add failed"
6922                 echo "done."
6923
6924                 echo -n "Adding target to pool..."
6925                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6926                         error "pool_add_targets failed"
6927                 echo "done."
6928         fi
6929
6930         echo -n "Setting pool using -p option..."
6931         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6932                 error "migrate failed rc = $?"
6933         echo "done."
6934
6935         echo -n "Verifying test file is in pool after migrating..."
6936         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6937                 error "file was not migrated to pool $pool"
6938         echo "done."
6939
6940         echo -n "Removing test file from pool '$pool'..."
6941         # "lfs migrate $file" won't remove the file from the pool
6942         # until some striping information is changed.
6943         $LFS migrate -c 1 $file1 &> /dev/null ||
6944                 error "cannot remove from pool"
6945         [ "$($LFS getstripe -p $file1)" ] &&
6946                 error "pool still set"
6947         echo "done."
6948
6949         echo -n "Setting pool using --pool option..."
6950         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6951                 error "migrate failed rc = $?"
6952         echo "done."
6953
6954         # Clean up
6955         rm -f $file1
6956         if $create_pool; then
6957                 destroy_test_pools 2> /dev/null ||
6958                         error "destroy test pools failed"
6959         fi
6960 }
6961 run_test 56wb "check lfs_migrate pool support"
6962
6963 test_56wc() {
6964         local file1="$DIR/$tdir/file1"
6965         local parent_ssize
6966         local parent_scount
6967         local cur_ssize
6968         local cur_scount
6969         local orig_ssize
6970
6971         echo -n "Creating test dir..."
6972         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6973         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6974                 error "cannot set stripe by '-S 1M -c 1'"
6975         echo "done"
6976
6977         echo -n "Setting initial stripe for test file..."
6978         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6979                 error "cannot set stripe"
6980         cur_ssize=$($LFS getstripe -S "$file1")
6981         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6982         echo "done."
6983
6984         # File currently set to -S 512K -c 1
6985
6986         # Ensure -c and -S options are rejected when -R is set
6987         echo -n "Verifying incompatible options are detected..."
6988         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6989                 error "incompatible -c and -R options not detected"
6990         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6991                 error "incompatible -S and -R options not detected"
6992         echo "done."
6993
6994         # Ensure unrecognized options are passed through to 'lfs migrate'
6995         echo -n "Verifying -S option is passed through to lfs migrate..."
6996         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6997                 error "migration failed"
6998         cur_ssize=$($LFS getstripe -S "$file1")
6999         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7000         echo "done."
7001
7002         # File currently set to -S 1M -c 1
7003
7004         # Ensure long options are supported
7005         echo -n "Verifying long options supported..."
7006         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7007                 error "long option without argument not supported"
7008         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7009                 error "long option with argument not supported"
7010         cur_ssize=$($LFS getstripe -S "$file1")
7011         [ $cur_ssize -eq 524288 ] ||
7012                 error "migrate --stripe-size $cur_ssize != 524288"
7013         echo "done."
7014
7015         # File currently set to -S 512K -c 1
7016
7017         if [ "$OSTCOUNT" -gt 1 ]; then
7018                 echo -n "Verifying explicit stripe count can be set..."
7019                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7020                         error "migrate failed"
7021                 cur_scount=$($LFS getstripe -c "$file1")
7022                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7023                 echo "done."
7024         fi
7025
7026         # File currently set to -S 512K -c 1 or -S 512K -c 2
7027
7028         # Ensure parent striping is used if -R is set, and no stripe
7029         # count or size is specified
7030         echo -n "Setting stripe for parent directory..."
7031         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7032                 error "cannot set stripe '-S 2M -c 1'"
7033         echo "done."
7034
7035         echo -n "Verifying restripe option uses parent stripe settings..."
7036         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7037         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7038         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7039                 error "migrate failed"
7040         cur_ssize=$($LFS getstripe -S "$file1")
7041         [ $cur_ssize -eq $parent_ssize ] ||
7042                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7043         cur_scount=$($LFS getstripe -c "$file1")
7044         [ $cur_scount -eq $parent_scount ] ||
7045                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7046         echo "done."
7047
7048         # File currently set to -S 1M -c 1
7049
7050         # Ensure striping is preserved if -R is not set, and no stripe
7051         # count or size is specified
7052         echo -n "Verifying striping size preserved when not specified..."
7053         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7054         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7055                 error "cannot set stripe on parent directory"
7056         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7057                 error "migrate failed"
7058         cur_ssize=$($LFS getstripe -S "$file1")
7059         [ $cur_ssize -eq $orig_ssize ] ||
7060                 error "migrate by default $cur_ssize != $orig_ssize"
7061         echo "done."
7062
7063         # Ensure file name properly detected when final option has no argument
7064         echo -n "Verifying file name properly detected..."
7065         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7066                 error "file name interpreted as option argument"
7067         echo "done."
7068
7069         # Clean up
7070         rm -f "$file1"
7071 }
7072 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7073
7074 test_56wd() {
7075         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7076
7077         local file1=$DIR/$tdir/file1
7078
7079         echo -n "Creating test dir..."
7080         test_mkdir $DIR/$tdir || error "cannot create dir"
7081         echo "done."
7082
7083         echo -n "Creating test file..."
7084         touch $file1
7085         echo "done."
7086
7087         # Ensure 'lfs migrate' will fail by using a non-existent option,
7088         # and make sure rsync is not called to recover
7089         echo -n "Make sure --no-rsync option works..."
7090         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7091                 grep -q 'refusing to fall back to rsync' ||
7092                 error "rsync was called with --no-rsync set"
7093         echo "done."
7094
7095         # Ensure rsync is called without trying 'lfs migrate' first
7096         echo -n "Make sure --rsync option works..."
7097         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7098                 grep -q 'falling back to rsync' &&
7099                 error "lfs migrate was called with --rsync set"
7100         echo "done."
7101
7102         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7103         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7104                 grep -q 'at the same time' ||
7105                 error "--rsync and --no-rsync accepted concurrently"
7106         echo "done."
7107
7108         # Clean up
7109         rm -f $file1
7110 }
7111 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7112
7113 test_56we() {
7114         local td=$DIR/$tdir
7115         local tf=$td/$tfile
7116
7117         test_mkdir $td || error "cannot create $td"
7118         touch $tf || error "cannot touch $tf"
7119
7120         echo -n "Make sure --non-direct|-D works..."
7121         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7122                 grep -q "lfs migrate --non-direct" ||
7123                 error "--non-direct option cannot work correctly"
7124         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7125                 grep -q "lfs migrate -D" ||
7126                 error "-D option cannot work correctly"
7127         echo "done."
7128 }
7129 run_test 56we "check lfs_migrate --non-direct|-D support"
7130
7131 test_56x() {
7132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7133         check_swap_layouts_support
7134
7135         local dir=$DIR/$tdir
7136         local ref1=/etc/passwd
7137         local file1=$dir/file1
7138
7139         test_mkdir $dir || error "creating dir $dir"
7140         $LFS setstripe -c 2 $file1
7141         cp $ref1 $file1
7142         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7143         stripe=$($LFS getstripe -c $file1)
7144         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7145         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7146
7147         # clean up
7148         rm -f $file1
7149 }
7150 run_test 56x "lfs migration support"
7151
7152 test_56xa() {
7153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7154         check_swap_layouts_support
7155
7156         local dir=$DIR/$tdir/$testnum
7157
7158         test_mkdir -p $dir
7159
7160         local ref1=/etc/passwd
7161         local file1=$dir/file1
7162
7163         $LFS setstripe -c 2 $file1
7164         cp $ref1 $file1
7165         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7166
7167         local stripe=$($LFS getstripe -c $file1)
7168
7169         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7170         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7171
7172         # clean up
7173         rm -f $file1
7174 }
7175 run_test 56xa "lfs migration --block support"
7176
7177 check_migrate_links() {
7178         local dir="$1"
7179         local file1="$dir/file1"
7180         local begin="$2"
7181         local count="$3"
7182         local runas="$4"
7183         local total_count=$(($begin + $count - 1))
7184         local symlink_count=10
7185         local uniq_count=10
7186
7187         if [ ! -f "$file1" ]; then
7188                 echo -n "creating initial file..."
7189                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7190                         error "cannot setstripe initial file"
7191                 echo "done"
7192
7193                 echo -n "creating symlinks..."
7194                 for s in $(seq 1 $symlink_count); do
7195                         ln -s "$file1" "$dir/slink$s" ||
7196                                 error "cannot create symlinks"
7197                 done
7198                 echo "done"
7199
7200                 echo -n "creating nonlinked files..."
7201                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7202                         error "cannot create nonlinked files"
7203                 echo "done"
7204         fi
7205
7206         # create hard links
7207         if [ ! -f "$dir/file$total_count" ]; then
7208                 echo -n "creating hard links $begin:$total_count..."
7209                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7210                         /dev/null || error "cannot create hard links"
7211                 echo "done"
7212         fi
7213
7214         echo -n "checking number of hard links listed in xattrs..."
7215         local fid=$($LFS getstripe -F "$file1")
7216         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7217
7218         echo "${#paths[*]}"
7219         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7220                         skip "hard link list has unexpected size, skipping test"
7221         fi
7222         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7223                         error "link names should exceed xattrs size"
7224         fi
7225
7226         echo -n "migrating files..."
7227         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7228         local rc=$?
7229         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7230         echo "done"
7231
7232         # make sure all links have been properly migrated
7233         echo -n "verifying files..."
7234         fid=$($LFS getstripe -F "$file1") ||
7235                 error "cannot get fid for file $file1"
7236         for i in $(seq 2 $total_count); do
7237                 local fid2=$($LFS getstripe -F $dir/file$i)
7238
7239                 [ "$fid2" == "$fid" ] ||
7240                         error "migrated hard link has mismatched FID"
7241         done
7242
7243         # make sure hard links were properly detected, and migration was
7244         # performed only once for the entire link set; nonlinked files should
7245         # also be migrated
7246         local actual=$(grep -c 'done' <<< "$migrate_out")
7247         local expected=$(($uniq_count + 1))
7248
7249         [ "$actual" -eq  "$expected" ] ||
7250                 error "hard links individually migrated ($actual != $expected)"
7251
7252         # make sure the correct number of hard links are present
7253         local hardlinks=$(stat -c '%h' "$file1")
7254
7255         [ $hardlinks -eq $total_count ] ||
7256                 error "num hard links $hardlinks != $total_count"
7257         echo "done"
7258
7259         return 0
7260 }
7261
7262 test_56xb() {
7263         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7264                 skip "Need MDS version at least 2.10.55"
7265
7266         local dir="$DIR/$tdir"
7267
7268         test_mkdir "$dir" || error "cannot create dir $dir"
7269
7270         echo "testing lfs migrate mode when all links fit within xattrs"
7271         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7272
7273         echo "testing rsync mode when all links fit within xattrs"
7274         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7275
7276         echo "testing lfs migrate mode when all links do not fit within xattrs"
7277         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7278
7279         echo "testing rsync mode when all links do not fit within xattrs"
7280         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7281
7282         chown -R $RUNAS_ID $dir
7283         echo "testing non-root lfs migrate mode when not all links are in xattr"
7284         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7285
7286         # clean up
7287         rm -rf $dir
7288 }
7289 run_test 56xb "lfs migration hard link support"
7290
7291 test_56xc() {
7292         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7293
7294         local dir="$DIR/$tdir"
7295
7296         test_mkdir "$dir" || error "cannot create dir $dir"
7297
7298         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7299         echo -n "Setting initial stripe for 20MB test file..."
7300         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7301                 error "cannot setstripe 20MB file"
7302         echo "done"
7303         echo -n "Sizing 20MB test file..."
7304         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7305         echo "done"
7306         echo -n "Verifying small file autostripe count is 1..."
7307         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7308                 error "cannot migrate 20MB file"
7309         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7310                 error "cannot get stripe for $dir/20mb"
7311         [ $stripe_count -eq 1 ] ||
7312                 error "unexpected stripe count $stripe_count for 20MB file"
7313         rm -f "$dir/20mb"
7314         echo "done"
7315
7316         # Test 2: File is small enough to fit within the available space on
7317         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7318         # have at least an additional 1KB for each desired stripe for test 3
7319         echo -n "Setting stripe for 1GB test file..."
7320         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7321         echo "done"
7322         echo -n "Sizing 1GB test file..."
7323         # File size is 1GB + 3KB
7324         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7325         echo "done"
7326
7327         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7328         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7329         if (( avail > 524288 * OSTCOUNT )); then
7330                 echo -n "Migrating 1GB file..."
7331                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7332                         error "cannot migrate 1GB file"
7333                 echo "done"
7334                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7335                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7336                         error "cannot getstripe for 1GB file"
7337                 [ $stripe_count -eq 2 ] ||
7338                         error "unexpected stripe count $stripe_count != 2"
7339                 echo "done"
7340         fi
7341
7342         # Test 3: File is too large to fit within the available space on
7343         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7344         if [ $OSTCOUNT -ge 3 ]; then
7345                 # The required available space is calculated as
7346                 # file size (1GB + 3KB) / OST count (3).
7347                 local kb_per_ost=349526
7348
7349                 echo -n "Migrating 1GB file with limit..."
7350                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7351                         error "cannot migrate 1GB file with limit"
7352                 echo "done"
7353
7354                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7355                 echo -n "Verifying 1GB autostripe count with limited space..."
7356                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7357                         error "unexpected stripe count $stripe_count (min 3)"
7358                 echo "done"
7359         fi
7360
7361         # clean up
7362         rm -rf $dir
7363 }
7364 run_test 56xc "lfs migration autostripe"
7365
7366 test_56xd() {
7367         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7368
7369         local dir=$DIR/$tdir
7370         local f_mgrt=$dir/$tfile.mgrt
7371         local f_yaml=$dir/$tfile.yaml
7372         local f_copy=$dir/$tfile.copy
7373         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7374         local layout_copy="-c 2 -S 2M -i 1"
7375         local yamlfile=$dir/yamlfile
7376         local layout_before;
7377         local layout_after;
7378
7379         test_mkdir "$dir" || error "cannot create dir $dir"
7380         $LFS setstripe $layout_yaml $f_yaml ||
7381                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7382         $LFS getstripe --yaml $f_yaml > $yamlfile
7383         $LFS setstripe $layout_copy $f_copy ||
7384                 error "cannot setstripe $f_copy with layout $layout_copy"
7385         touch $f_mgrt
7386         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7387
7388         # 1. test option --yaml
7389         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7390                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7391         layout_before=$(get_layout_param $f_yaml)
7392         layout_after=$(get_layout_param $f_mgrt)
7393         [ "$layout_after" == "$layout_before" ] ||
7394                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7395
7396         # 2. test option --copy
7397         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7398                 error "cannot migrate $f_mgrt with --copy $f_copy"
7399         layout_before=$(get_layout_param $f_copy)
7400         layout_after=$(get_layout_param $f_mgrt)
7401         [ "$layout_after" == "$layout_before" ] ||
7402                 error "lfs_migrate --copy: $layout_after != $layout_before"
7403 }
7404 run_test 56xd "check lfs_migrate --yaml and --copy support"
7405
7406 test_56xe() {
7407         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7408
7409         local dir=$DIR/$tdir
7410         local f_comp=$dir/$tfile
7411         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7412         local layout_before=""
7413         local layout_after=""
7414
7415         test_mkdir "$dir" || error "cannot create dir $dir"
7416         $LFS setstripe $layout $f_comp ||
7417                 error "cannot setstripe $f_comp with layout $layout"
7418         layout_before=$(get_layout_param $f_comp)
7419         dd if=/dev/zero of=$f_comp bs=1M count=4
7420
7421         # 1. migrate a comp layout file by lfs_migrate
7422         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7423         layout_after=$(get_layout_param $f_comp)
7424         [ "$layout_before" == "$layout_after" ] ||
7425                 error "lfs_migrate: $layout_before != $layout_after"
7426
7427         # 2. migrate a comp layout file by lfs migrate
7428         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7429         layout_after=$(get_layout_param $f_comp)
7430         [ "$layout_before" == "$layout_after" ] ||
7431                 error "lfs migrate: $layout_before != $layout_after"
7432 }
7433 run_test 56xe "migrate a composite layout file"
7434
7435 test_56xf() {
7436         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7437
7438         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7439                 skip "Need server version at least 2.13.53"
7440
7441         local dir=$DIR/$tdir
7442         local f_comp=$dir/$tfile
7443         local layout="-E 1M -c1 -E -1 -c2"
7444         local fid_before=""
7445         local fid_after=""
7446
7447         test_mkdir "$dir" || error "cannot create dir $dir"
7448         $LFS setstripe $layout $f_comp ||
7449                 error "cannot setstripe $f_comp with layout $layout"
7450         fid_before=$($LFS getstripe --fid $f_comp)
7451         dd if=/dev/zero of=$f_comp bs=1M count=4
7452
7453         # 1. migrate a comp layout file to a comp layout
7454         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7455         fid_after=$($LFS getstripe --fid $f_comp)
7456         [ "$fid_before" == "$fid_after" ] ||
7457                 error "comp-to-comp migrate: $fid_before != $fid_after"
7458
7459         # 2. migrate a comp layout file to a plain layout
7460         $LFS migrate -c2 $f_comp ||
7461                 error "cannot migrate $f_comp by lfs migrate"
7462         fid_after=$($LFS getstripe --fid $f_comp)
7463         [ "$fid_before" == "$fid_after" ] ||
7464                 error "comp-to-plain migrate: $fid_before != $fid_after"
7465
7466         # 3. migrate a plain layout file to a comp layout
7467         $LFS migrate $layout $f_comp ||
7468                 error "cannot migrate $f_comp by lfs migrate"
7469         fid_after=$($LFS getstripe --fid $f_comp)
7470         [ "$fid_before" == "$fid_after" ] ||
7471                 error "plain-to-comp migrate: $fid_before != $fid_after"
7472 }
7473 run_test 56xf "FID is not lost during migration of a composite layout file"
7474
7475 test_56y() {
7476         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7477                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7478
7479         local res=""
7480         local dir=$DIR/$tdir
7481         local f1=$dir/file1
7482         local f2=$dir/file2
7483
7484         test_mkdir -p $dir || error "creating dir $dir"
7485         touch $f1 || error "creating std file $f1"
7486         $MULTIOP $f2 H2c || error "creating released file $f2"
7487
7488         # a directory can be raid0, so ask only for files
7489         res=$($LFS find $dir -L raid0 -type f | wc -l)
7490         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7491
7492         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7493         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7494
7495         # only files can be released, so no need to force file search
7496         res=$($LFS find $dir -L released)
7497         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7498
7499         res=$($LFS find $dir -type f \! -L released)
7500         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7501 }
7502 run_test 56y "lfs find -L raid0|released"
7503
7504 test_56z() { # LU-4824
7505         # This checks to make sure 'lfs find' continues after errors
7506         # There are two classes of errors that should be caught:
7507         # - If multiple paths are provided, all should be searched even if one
7508         #   errors out
7509         # - If errors are encountered during the search, it should not terminate
7510         #   early
7511         local dir=$DIR/$tdir
7512         local i
7513
7514         test_mkdir $dir
7515         for i in d{0..9}; do
7516                 test_mkdir $dir/$i
7517                 touch $dir/$i/$tfile
7518         done
7519         $LFS find $DIR/non_existent_dir $dir &&
7520                 error "$LFS find did not return an error"
7521         # Make a directory unsearchable. This should NOT be the last entry in
7522         # directory order.  Arbitrarily pick the 6th entry
7523         chmod 700 $($LFS find $dir -type d | sed '6!d')
7524
7525         $RUNAS $LFS find $DIR/non_existent $dir
7526         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7527
7528         # The user should be able to see 10 directories and 9 files
7529         (( count == 19 )) ||
7530                 error "$LFS find found $count != 19 entries after error"
7531 }
7532 run_test 56z "lfs find should continue after an error"
7533
7534 test_56aa() { # LU-5937
7535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7536
7537         local dir=$DIR/$tdir
7538
7539         mkdir $dir
7540         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7541
7542         createmany -o $dir/striped_dir/${tfile}- 1024
7543         local dirs=$($LFS find --size +8k $dir/)
7544
7545         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7546 }
7547 run_test 56aa "lfs find --size under striped dir"
7548
7549 test_56ab() { # LU-10705
7550         test_mkdir $DIR/$tdir
7551         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7552         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7553         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7554         # Flush writes to ensure valid blocks.  Need to be more thorough for
7555         # ZFS, since blocks are not allocated/returned to client immediately.
7556         sync_all_data
7557         wait_zfs_commit ost1 2
7558         cancel_lru_locks osc
7559         ls -ls $DIR/$tdir
7560
7561         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7562
7563         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7564
7565         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7566         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7567
7568         rm -f $DIR/$tdir/$tfile.[123]
7569 }
7570 run_test 56ab "lfs find --blocks"
7571
7572 test_56ba() {
7573         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7574                 skip "Need MDS version at least 2.10.50"
7575
7576         # Create composite files with one component
7577         local dir=$DIR/$tdir
7578
7579         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7580         # Create composite files with three components
7581         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7582         # Create non-composite files
7583         createmany -o $dir/${tfile}- 10
7584
7585         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7586
7587         [[ $nfiles == 10 ]] ||
7588                 error "lfs find -E 1M found $nfiles != 10 files"
7589
7590         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7591         [[ $nfiles == 25 ]] ||
7592                 error "lfs find ! -E 1M found $nfiles != 25 files"
7593
7594         # All files have a component that starts at 0
7595         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7596         [[ $nfiles == 35 ]] ||
7597                 error "lfs find --component-start 0 - $nfiles != 35 files"
7598
7599         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7600         [[ $nfiles == 15 ]] ||
7601                 error "lfs find --component-start 2M - $nfiles != 15 files"
7602
7603         # All files created here have a componenet that does not starts at 2M
7604         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7605         [[ $nfiles == 35 ]] ||
7606                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7607
7608         # Find files with a specified number of components
7609         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7610         [[ $nfiles == 15 ]] ||
7611                 error "lfs find --component-count 3 - $nfiles != 15 files"
7612
7613         # Remember non-composite files have a component count of zero
7614         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7615         [[ $nfiles == 10 ]] ||
7616                 error "lfs find --component-count 0 - $nfiles != 10 files"
7617
7618         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7619         [[ $nfiles == 20 ]] ||
7620                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7621
7622         # All files have a flag called "init"
7623         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7624         [[ $nfiles == 35 ]] ||
7625                 error "lfs find --component-flags init - $nfiles != 35 files"
7626
7627         # Multi-component files will have a component not initialized
7628         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7629         [[ $nfiles == 15 ]] ||
7630                 error "lfs find !--component-flags init - $nfiles != 15 files"
7631
7632         rm -rf $dir
7633
7634 }
7635 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7636
7637 test_56ca() {
7638         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7639                 skip "Need MDS version at least 2.10.57"
7640
7641         local td=$DIR/$tdir
7642         local tf=$td/$tfile
7643         local dir
7644         local nfiles
7645         local cmd
7646         local i
7647         local j
7648
7649         # create mirrored directories and mirrored files
7650         mkdir $td || error "mkdir $td failed"
7651         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7652         createmany -o $tf- 10 || error "create $tf- failed"
7653
7654         for i in $(seq 2); do
7655                 dir=$td/dir$i
7656                 mkdir $dir || error "mkdir $dir failed"
7657                 $LFS mirror create -N$((3 + i)) $dir ||
7658                         error "create mirrored dir $dir failed"
7659                 createmany -o $dir/$tfile- 10 ||
7660                         error "create $dir/$tfile- failed"
7661         done
7662
7663         # change the states of some mirrored files
7664         echo foo > $tf-6
7665         for i in $(seq 2); do
7666                 dir=$td/dir$i
7667                 for j in $(seq 4 9); do
7668                         echo foo > $dir/$tfile-$j
7669                 done
7670         done
7671
7672         # find mirrored files with specific mirror count
7673         cmd="$LFS find --mirror-count 3 --type f $td"
7674         nfiles=$($cmd | wc -l)
7675         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7676
7677         cmd="$LFS find ! --mirror-count 3 --type f $td"
7678         nfiles=$($cmd | wc -l)
7679         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7680
7681         cmd="$LFS find --mirror-count +2 --type f $td"
7682         nfiles=$($cmd | wc -l)
7683         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7684
7685         cmd="$LFS find --mirror-count -6 --type f $td"
7686         nfiles=$($cmd | wc -l)
7687         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7688
7689         # find mirrored files with specific file state
7690         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7691         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7692
7693         cmd="$LFS find --mirror-state=ro --type f $td"
7694         nfiles=$($cmd | wc -l)
7695         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7696
7697         cmd="$LFS find ! --mirror-state=ro --type f $td"
7698         nfiles=$($cmd | wc -l)
7699         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7700
7701         cmd="$LFS find --mirror-state=wp --type f $td"
7702         nfiles=$($cmd | wc -l)
7703         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7704
7705         cmd="$LFS find ! --mirror-state=sp --type f $td"
7706         nfiles=$($cmd | wc -l)
7707         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7708 }
7709 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7710
7711 test_57a() {
7712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7713         # note test will not do anything if MDS is not local
7714         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7715                 skip_env "ldiskfs only test"
7716         fi
7717         remote_mds_nodsh && skip "remote MDS with nodsh"
7718
7719         local MNTDEV="osd*.*MDT*.mntdev"
7720         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7721         [ -z "$DEV" ] && error "can't access $MNTDEV"
7722         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7723                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7724                         error "can't access $DEV"
7725                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7726                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7727                 rm $TMP/t57a.dump
7728         done
7729 }
7730 run_test 57a "verify MDS filesystem created with large inodes =="
7731
7732 test_57b() {
7733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7734         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7735                 skip_env "ldiskfs only test"
7736         fi
7737         remote_mds_nodsh && skip "remote MDS with nodsh"
7738
7739         local dir=$DIR/$tdir
7740         local filecount=100
7741         local file1=$dir/f1
7742         local fileN=$dir/f$filecount
7743
7744         rm -rf $dir || error "removing $dir"
7745         test_mkdir -c1 $dir
7746         local mdtidx=$($LFS getstripe -m $dir)
7747         local mdtname=MDT$(printf %04x $mdtidx)
7748         local facet=mds$((mdtidx + 1))
7749
7750         echo "mcreating $filecount files"
7751         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7752
7753         # verify that files do not have EAs yet
7754         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7755                 error "$file1 has an EA"
7756         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7757                 error "$fileN has an EA"
7758
7759         sync
7760         sleep 1
7761         df $dir  #make sure we get new statfs data
7762         local mdsfree=$(do_facet $facet \
7763                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7764         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7765         local file
7766
7767         echo "opening files to create objects/EAs"
7768         for file in $(seq -f $dir/f%g 1 $filecount); do
7769                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7770                         error "opening $file"
7771         done
7772
7773         # verify that files have EAs now
7774         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7775         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7776
7777         sleep 1  #make sure we get new statfs data
7778         df $dir
7779         local mdsfree2=$(do_facet $facet \
7780                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7781         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7782
7783         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7784                 if [ "$mdsfree" != "$mdsfree2" ]; then
7785                         error "MDC before $mdcfree != after $mdcfree2"
7786                 else
7787                         echo "MDC before $mdcfree != after $mdcfree2"
7788                         echo "unable to confirm if MDS has large inodes"
7789                 fi
7790         fi
7791         rm -rf $dir
7792 }
7793 run_test 57b "default LOV EAs are stored inside large inodes ==="
7794
7795 test_58() {
7796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7797         [ -z "$(which wiretest 2>/dev/null)" ] &&
7798                         skip_env "could not find wiretest"
7799
7800         wiretest
7801 }
7802 run_test 58 "verify cross-platform wire constants =============="
7803
7804 test_59() {
7805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7806
7807         echo "touch 130 files"
7808         createmany -o $DIR/f59- 130
7809         echo "rm 130 files"
7810         unlinkmany $DIR/f59- 130
7811         sync
7812         # wait for commitment of removal
7813         wait_delete_completed
7814 }
7815 run_test 59 "verify cancellation of llog records async ========="
7816
7817 TEST60_HEAD="test_60 run $RANDOM"
7818 test_60a() {
7819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7820         remote_mgs_nodsh && skip "remote MGS with nodsh"
7821         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7822                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7823                         skip_env "missing subtest run-llog.sh"
7824
7825         log "$TEST60_HEAD - from kernel mode"
7826         do_facet mgs "$LCTL dk > /dev/null"
7827         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7828         do_facet mgs $LCTL dk > $TMP/$tfile
7829
7830         # LU-6388: test llog_reader
7831         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7832         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7833         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7834                         skip_env "missing llog_reader"
7835         local fstype=$(facet_fstype mgs)
7836         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7837                 skip_env "Only for ldiskfs or zfs type mgs"
7838
7839         local mntpt=$(facet_mntpt mgs)
7840         local mgsdev=$(mgsdevname 1)
7841         local fid_list
7842         local fid
7843         local rec_list
7844         local rec
7845         local rec_type
7846         local obj_file
7847         local path
7848         local seq
7849         local oid
7850         local pass=true
7851
7852         #get fid and record list
7853         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7854                 tail -n 4))
7855         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7856                 tail -n 4))
7857         #remount mgs as ldiskfs or zfs type
7858         stop mgs || error "stop mgs failed"
7859         mount_fstype mgs || error "remount mgs failed"
7860         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7861                 fid=${fid_list[i]}
7862                 rec=${rec_list[i]}
7863                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7864                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7865                 oid=$((16#$oid))
7866
7867                 case $fstype in
7868                         ldiskfs )
7869                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7870                         zfs )
7871                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7872                 esac
7873                 echo "obj_file is $obj_file"
7874                 do_facet mgs $llog_reader $obj_file
7875
7876                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7877                         awk '{ print $3 }' | sed -e "s/^type=//g")
7878                 if [ $rec_type != $rec ]; then
7879                         echo "FAILED test_60a wrong record type $rec_type," \
7880                               "should be $rec"
7881                         pass=false
7882                         break
7883                 fi
7884
7885                 #check obj path if record type is LLOG_LOGID_MAGIC
7886                 if [ "$rec" == "1064553b" ]; then
7887                         path=$(do_facet mgs $llog_reader $obj_file |
7888                                 grep "path=" | awk '{ print $NF }' |
7889                                 sed -e "s/^path=//g")
7890                         if [ $obj_file != $mntpt/$path ]; then
7891                                 echo "FAILED test_60a wrong obj path" \
7892                                       "$montpt/$path, should be $obj_file"
7893                                 pass=false
7894                                 break
7895                         fi
7896                 fi
7897         done
7898         rm -f $TMP/$tfile
7899         #restart mgs before "error", otherwise it will block the next test
7900         stop mgs || error "stop mgs failed"
7901         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7902         $pass || error "test failed, see FAILED test_60a messages for specifics"
7903 }
7904 run_test 60a "llog_test run from kernel module and test llog_reader"
7905
7906 test_60b() { # bug 6411
7907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7908
7909         dmesg > $DIR/$tfile
7910         LLOG_COUNT=$(do_facet mgs dmesg |
7911                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7912                           /llog_[a-z]*.c:[0-9]/ {
7913                                 if (marker)
7914                                         from_marker++
7915                                 from_begin++
7916                           }
7917                           END {
7918                                 if (marker)
7919                                         print from_marker
7920                                 else
7921                                         print from_begin
7922                           }")
7923
7924         [[ $LLOG_COUNT -gt 120 ]] &&
7925                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7926 }
7927 run_test 60b "limit repeated messages from CERROR/CWARN"
7928
7929 test_60c() {
7930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7931
7932         echo "create 5000 files"
7933         createmany -o $DIR/f60c- 5000
7934 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7935         lctl set_param fail_loc=0x80000137
7936         unlinkmany $DIR/f60c- 5000
7937         lctl set_param fail_loc=0
7938 }
7939 run_test 60c "unlink file when mds full"
7940
7941 test_60d() {
7942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7943
7944         SAVEPRINTK=$(lctl get_param -n printk)
7945         # verify "lctl mark" is even working"
7946         MESSAGE="test message ID $RANDOM $$"
7947         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7948         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7949
7950         lctl set_param printk=0 || error "set lnet.printk failed"
7951         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7952         MESSAGE="new test message ID $RANDOM $$"
7953         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7954         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7955         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7956
7957         lctl set_param -n printk="$SAVEPRINTK"
7958 }
7959 run_test 60d "test printk console message masking"
7960
7961 test_60e() {
7962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7963         remote_mds_nodsh && skip "remote MDS with nodsh"
7964
7965         touch $DIR/$tfile
7966 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7967         do_facet mds1 lctl set_param fail_loc=0x15b
7968         rm $DIR/$tfile
7969 }
7970 run_test 60e "no space while new llog is being created"
7971
7972 test_60g() {
7973         local pid
7974         local i
7975
7976         test_mkdir -c $MDSCOUNT $DIR/$tdir
7977
7978         (
7979                 local index=0
7980                 while true; do
7981                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7982                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7983                                 2>/dev/null
7984                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7985                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7986                         index=$((index + 1))
7987                 done
7988         ) &
7989
7990         pid=$!
7991
7992         for i in {0..100}; do
7993                 # define OBD_FAIL_OSD_TXN_START    0x19a
7994                 local index=$((i % MDSCOUNT + 1))
7995
7996                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7997                         > /dev/null
7998                 sleep 0.01
7999         done
8000
8001         kill -9 $pid
8002
8003         for i in $(seq $MDSCOUNT); do
8004                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8005         done
8006
8007         mkdir $DIR/$tdir/new || error "mkdir failed"
8008         rmdir $DIR/$tdir/new || error "rmdir failed"
8009
8010         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8011                 -t namespace
8012         for i in $(seq $MDSCOUNT); do
8013                 wait_update_facet mds$i "$LCTL get_param -n \
8014                         mdd.$(facet_svc mds$i).lfsck_namespace |
8015                         awk '/^status/ { print \\\$2 }'" "completed"
8016         done
8017
8018         ls -R $DIR/$tdir || error "ls failed"
8019         rm -rf $DIR/$tdir || error "rmdir failed"
8020 }
8021 run_test 60g "transaction abort won't cause MDT hung"
8022
8023 test_60h() {
8024         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8025                 skip "Need MDS version at least 2.12.52"
8026         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8027
8028         local f
8029
8030         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8031         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8032         for fail_loc in 0x80000188 0x80000189; do
8033                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8034                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8035                         error "mkdir $dir-$fail_loc failed"
8036                 for i in {0..10}; do
8037                         # create may fail on missing stripe
8038                         echo $i > $DIR/$tdir-$fail_loc/$i
8039                 done
8040                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8041                         error "getdirstripe $tdir-$fail_loc failed"
8042                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8043                         error "migrate $tdir-$fail_loc failed"
8044                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8045                         error "getdirstripe $tdir-$fail_loc failed"
8046                 pushd $DIR/$tdir-$fail_loc
8047                 for f in *; do
8048                         echo $f | cmp $f - || error "$f data mismatch"
8049                 done
8050                 popd
8051                 rm -rf $DIR/$tdir-$fail_loc
8052         done
8053 }
8054 run_test 60h "striped directory with missing stripes can be accessed"
8055
8056 test_61a() {
8057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8058
8059         f="$DIR/f61"
8060         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8061         cancel_lru_locks osc
8062         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8063         sync
8064 }
8065 run_test 61a "mmap() writes don't make sync hang ================"
8066
8067 test_61b() {
8068         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8069 }
8070 run_test 61b "mmap() of unstriped file is successful"
8071
8072 # bug 2330 - insufficient obd_match error checking causes LBUG
8073 test_62() {
8074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8075
8076         f="$DIR/f62"
8077         echo foo > $f
8078         cancel_lru_locks osc
8079         lctl set_param fail_loc=0x405
8080         cat $f && error "cat succeeded, expect -EIO"
8081         lctl set_param fail_loc=0
8082 }
8083 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8084 # match every page all of the time.
8085 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8086
8087 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8088 # Though this test is irrelevant anymore, it helped to reveal some
8089 # other grant bugs (LU-4482), let's keep it.
8090 test_63a() {   # was test_63
8091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8092
8093         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8094
8095         for i in `seq 10` ; do
8096                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8097                 sleep 5
8098                 kill $!
8099                 sleep 1
8100         done
8101
8102         rm -f $DIR/f63 || true
8103 }
8104 run_test 63a "Verify oig_wait interruption does not crash ======="
8105
8106 # bug 2248 - async write errors didn't return to application on sync
8107 # bug 3677 - async write errors left page locked
8108 test_63b() {
8109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8110
8111         debugsave
8112         lctl set_param debug=-1
8113
8114         # ensure we have a grant to do async writes
8115         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8116         rm $DIR/$tfile
8117
8118         sync    # sync lest earlier test intercept the fail_loc
8119
8120         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8121         lctl set_param fail_loc=0x80000406
8122         $MULTIOP $DIR/$tfile Owy && \
8123                 error "sync didn't return ENOMEM"
8124         sync; sleep 2; sync     # do a real sync this time to flush page
8125         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8126                 error "locked page left in cache after async error" || true
8127         debugrestore
8128 }
8129 run_test 63b "async write errors should be returned to fsync ==="
8130
8131 test_64a () {
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133
8134         lfs df $DIR
8135         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8136 }
8137 run_test 64a "verify filter grant calculations (in kernel) ====="
8138
8139 test_64b () {
8140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8141
8142         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8143 }
8144 run_test 64b "check out-of-space detection on client"
8145
8146 test_64c() {
8147         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8148 }
8149 run_test 64c "verify grant shrink"
8150
8151 import_param() {
8152         local tgt=$1
8153         local param=$2
8154
8155         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8156 }
8157
8158 # this does exactly what osc_request.c:osc_announce_cached() does in
8159 # order to calculate max amount of grants to ask from server
8160 want_grant() {
8161         local tgt=$1
8162
8163         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8164         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8165
8166         ((rpc_in_flight++));
8167         nrpages=$((nrpages * rpc_in_flight))
8168
8169         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8170
8171         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8172
8173         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8174         local undirty=$((nrpages * PAGE_SIZE))
8175
8176         local max_extent_pages
8177         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8178         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8179         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8180         local grant_extent_tax
8181         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8182
8183         undirty=$((undirty + nrextents * grant_extent_tax))
8184
8185         echo $undirty
8186 }
8187
8188 # this is size of unit for grant allocation. It should be equal to
8189 # what tgt_grant.c:tgt_grant_chunk() calculates
8190 grant_chunk() {
8191         local tgt=$1
8192         local max_brw_size
8193         local grant_extent_tax
8194
8195         max_brw_size=$(import_param $tgt max_brw_size)
8196
8197         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8198
8199         echo $(((max_brw_size + grant_extent_tax) * 2))
8200 }
8201
8202 test_64d() {
8203         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8204                 skip "OST < 2.10.55 doesn't limit grants enough"
8205
8206         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8207
8208         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8209                 skip "no grant_param connect flag"
8210
8211         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8212
8213         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8214         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8215
8216
8217         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8218         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8219
8220         $LFS setstripe $DIR/$tfile -i 0 -c 1
8221         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8222         ddpid=$!
8223
8224         while kill -0 $ddpid; do
8225                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8226
8227                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8228                         kill $ddpid
8229                         error "cur_grant $cur_grant > $max_cur_granted"
8230                 fi
8231
8232                 sleep 1
8233         done
8234 }
8235 run_test 64d "check grant limit exceed"
8236
8237 check_grants() {
8238         local tgt=$1
8239         local expected=$2
8240         local msg=$3
8241         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8242
8243         ((cur_grants == expected)) ||
8244                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8245 }
8246
8247 round_up_p2() {
8248         echo $((($1 + $2 - 1) & ~($2 - 1)))
8249 }
8250
8251 test_64e() {
8252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8253         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8254                 skip "Need OSS version at least 2.11.56"
8255
8256         # Remount client to reset grant
8257         remount_client $MOUNT || error "failed to remount client"
8258         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8259
8260         local init_grants=$(import_param $osc_tgt initial_grant)
8261
8262         check_grants $osc_tgt $init_grants "init grants"
8263
8264         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8265         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8266         local gbs=$(import_param $osc_tgt grant_block_size)
8267
8268         # write random number of bytes from max_brw_size / 4 to max_brw_size
8269         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8270         # align for direct io
8271         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8272         # round to grant consumption unit
8273         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8274
8275         local grants=$((wb_round_up + extent_tax))
8276
8277         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8278
8279         # define OBD_FAIL_TGT_NO_GRANT 0x725
8280         # make the server not grant more back
8281         do_facet ost1 $LCTL set_param fail_loc=0x725
8282         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8283
8284         do_facet ost1 $LCTL set_param fail_loc=0
8285
8286         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8287
8288         rm -f $DIR/$tfile || error "rm failed"
8289
8290         # Remount client to reset grant
8291         remount_client $MOUNT || error "failed to remount client"
8292         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8293
8294         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8295
8296         # define OBD_FAIL_TGT_NO_GRANT 0x725
8297         # make the server not grant more back
8298         do_facet ost1 $LCTL set_param fail_loc=0x725
8299         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8300         do_facet ost1 $LCTL set_param fail_loc=0
8301
8302         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8303 }
8304 run_test 64e "check grant consumption (no grant allocation)"
8305
8306 test_64f() {
8307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8308
8309         # Remount client to reset grant
8310         remount_client $MOUNT || error "failed to remount client"
8311         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8312
8313         local init_grants=$(import_param $osc_tgt initial_grant)
8314         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8315         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8316         local gbs=$(import_param $osc_tgt grant_block_size)
8317         local chunk=$(grant_chunk $osc_tgt)
8318
8319         # write random number of bytes from max_brw_size / 4 to max_brw_size
8320         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8321         # align for direct io
8322         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8323         # round to grant consumption unit
8324         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8325
8326         local grants=$((wb_round_up + extent_tax))
8327
8328         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8329         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8330                 error "error writing to $DIR/$tfile"
8331
8332         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8333                 "direct io with grant allocation"
8334
8335         rm -f $DIR/$tfile || error "rm failed"
8336
8337         # Remount client to reset grant
8338         remount_client $MOUNT || error "failed to remount client"
8339         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8340
8341         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8342
8343         local cmd="oO_WRONLY:w${write_bytes}_yc"
8344
8345         $MULTIOP $DIR/$tfile $cmd &
8346         MULTIPID=$!
8347         sleep 1
8348
8349         check_grants $osc_tgt $((init_grants - grants)) \
8350                 "buffered io, not write rpc"
8351
8352         kill -USR1 $MULTIPID
8353         wait
8354
8355         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8356                 "buffered io, one RPC"
8357 }
8358 run_test 64f "check grant consumption (with grant allocation)"
8359
8360 # bug 1414 - set/get directories' stripe info
8361 test_65a() {
8362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8363
8364         test_mkdir $DIR/$tdir
8365         touch $DIR/$tdir/f1
8366         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8367 }
8368 run_test 65a "directory with no stripe info"
8369
8370 test_65b() {
8371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8372
8373         test_mkdir $DIR/$tdir
8374         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8375
8376         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8377                                                 error "setstripe"
8378         touch $DIR/$tdir/f2
8379         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8380 }
8381 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8382
8383 test_65c() {
8384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8385         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8386
8387         test_mkdir $DIR/$tdir
8388         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8389
8390         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8391                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8392         touch $DIR/$tdir/f3
8393         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8394 }
8395 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8396
8397 test_65d() {
8398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8399
8400         test_mkdir $DIR/$tdir
8401         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8402         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8403
8404         if [[ $STRIPECOUNT -le 0 ]]; then
8405                 sc=1
8406         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8407                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8408                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8409         else
8410                 sc=$(($STRIPECOUNT - 1))
8411         fi
8412         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8413         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8414         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8415                 error "lverify failed"
8416 }
8417 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8418
8419 test_65e() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421
8422         test_mkdir $DIR/$tdir
8423
8424         $LFS setstripe $DIR/$tdir || error "setstripe"
8425         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8426                                         error "no stripe info failed"
8427         touch $DIR/$tdir/f6
8428         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8429 }
8430 run_test 65e "directory setstripe defaults"
8431
8432 test_65f() {
8433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8434
8435         test_mkdir $DIR/${tdir}f
8436         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8437                 error "setstripe succeeded" || true
8438 }
8439 run_test 65f "dir setstripe permission (should return error) ==="
8440
8441 test_65g() {
8442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8443
8444         test_mkdir $DIR/$tdir
8445         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8446
8447         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8448                 error "setstripe -S failed"
8449         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8450         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8451                 error "delete default stripe failed"
8452 }
8453 run_test 65g "directory setstripe -d"
8454
8455 test_65h() {
8456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8457
8458         test_mkdir $DIR/$tdir
8459         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8460
8461         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8462                 error "setstripe -S failed"
8463         test_mkdir $DIR/$tdir/dd1
8464         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8465                 error "stripe info inherit failed"
8466 }
8467 run_test 65h "directory stripe info inherit ===================="
8468
8469 test_65i() {
8470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8471
8472         save_layout_restore_at_exit $MOUNT
8473
8474         # bug6367: set non-default striping on root directory
8475         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8476
8477         # bug12836: getstripe on -1 default directory striping
8478         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8479
8480         # bug12836: getstripe -v on -1 default directory striping
8481         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8482
8483         # bug12836: new find on -1 default directory striping
8484         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8485 }
8486 run_test 65i "various tests to set root directory striping"
8487
8488 test_65j() { # bug6367
8489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8490
8491         sync; sleep 1
8492
8493         # if we aren't already remounting for each test, do so for this test
8494         if [ "$I_MOUNTED" = "yes" ]; then
8495                 cleanup || error "failed to unmount"
8496                 setup
8497         fi
8498
8499         save_layout_restore_at_exit $MOUNT
8500
8501         $LFS setstripe -d $MOUNT || error "setstripe failed"
8502 }
8503 run_test 65j "set default striping on root directory (bug 6367)="
8504
8505 cleanup_65k() {
8506         rm -rf $DIR/$tdir
8507         wait_delete_completed
8508         do_facet $SINGLEMDS "lctl set_param -n \
8509                 osp.$ost*MDT0000.max_create_count=$max_count"
8510         do_facet $SINGLEMDS "lctl set_param -n \
8511                 osp.$ost*MDT0000.create_count=$count"
8512         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8513         echo $INACTIVE_OSC "is Activate"
8514
8515         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8516 }
8517
8518 test_65k() { # bug11679
8519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8521         remote_mds_nodsh && skip "remote MDS with nodsh"
8522
8523         local disable_precreate=true
8524         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8525                 disable_precreate=false
8526
8527         echo "Check OST status: "
8528         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8529                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8530
8531         for OSC in $MDS_OSCS; do
8532                 echo $OSC "is active"
8533                 do_facet $SINGLEMDS lctl --device %$OSC activate
8534         done
8535
8536         for INACTIVE_OSC in $MDS_OSCS; do
8537                 local ost=$(osc_to_ost $INACTIVE_OSC)
8538                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8539                                lov.*md*.target_obd |
8540                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8541
8542                 mkdir -p $DIR/$tdir
8543                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8544                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8545
8546                 echo "Deactivate: " $INACTIVE_OSC
8547                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8548
8549                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8550                               osp.$ost*MDT0000.create_count")
8551                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8552                                   osp.$ost*MDT0000.max_create_count")
8553                 $disable_precreate &&
8554                         do_facet $SINGLEMDS "lctl set_param -n \
8555                                 osp.$ost*MDT0000.max_create_count=0"
8556
8557                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8558                         [ -f $DIR/$tdir/$idx ] && continue
8559                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8560                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8561                                 { cleanup_65k;
8562                                   error "setstripe $idx should succeed"; }
8563                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8564                 done
8565                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8566                 rmdir $DIR/$tdir
8567
8568                 do_facet $SINGLEMDS "lctl set_param -n \
8569                         osp.$ost*MDT0000.max_create_count=$max_count"
8570                 do_facet $SINGLEMDS "lctl set_param -n \
8571                         osp.$ost*MDT0000.create_count=$count"
8572                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8573                 echo $INACTIVE_OSC "is Activate"
8574
8575                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8576         done
8577 }
8578 run_test 65k "validate manual striping works properly with deactivated OSCs"
8579
8580 test_65l() { # bug 12836
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         test_mkdir -p $DIR/$tdir/test_dir
8584         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8585         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8586 }
8587 run_test 65l "lfs find on -1 stripe dir ========================"
8588
8589 test_65m() {
8590         local layout=$(save_layout $MOUNT)
8591         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8592                 restore_layout $MOUNT $layout
8593                 error "setstripe should fail by non-root users"
8594         }
8595         true
8596 }
8597 run_test 65m "normal user can't set filesystem default stripe"
8598
8599 test_65n() {
8600         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8601         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8602                 skip "Need MDS version at least 2.12.50"
8603         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8604
8605         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8606         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8607         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8608
8609         local root_layout=$(save_layout $MOUNT)
8610         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8611
8612         # new subdirectory under root directory should not inherit
8613         # the default layout from root
8614         local dir1=$MOUNT/$tdir-1
8615         mkdir $dir1 || error "mkdir $dir1 failed"
8616         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8617                 error "$dir1 shouldn't have LOV EA"
8618
8619         # delete the default layout on root directory
8620         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8621
8622         local dir2=$MOUNT/$tdir-2
8623         mkdir $dir2 || error "mkdir $dir2 failed"
8624         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8625                 error "$dir2 shouldn't have LOV EA"
8626
8627         # set a new striping pattern on root directory
8628         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8629         local new_def_stripe_size=$((def_stripe_size * 2))
8630         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8631                 error "set stripe size on $MOUNT failed"
8632
8633         # new file created in $dir2 should inherit the new stripe size from
8634         # the filesystem default
8635         local file2=$dir2/$tfile-2
8636         touch $file2 || error "touch $file2 failed"
8637
8638         local file2_stripe_size=$($LFS getstripe -S $file2)
8639         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8640         {
8641                 echo "file2_stripe_size: '$file2_stripe_size'"
8642                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8643                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8644         }
8645
8646         local dir3=$MOUNT/$tdir-3
8647         mkdir $dir3 || error "mkdir $dir3 failed"
8648         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8649         # the root layout, which is the actual default layout that will be used
8650         # when new files are created in $dir3.
8651         local dir3_layout=$(get_layout_param $dir3)
8652         local root_dir_layout=$(get_layout_param $MOUNT)
8653         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8654         {
8655                 echo "dir3_layout: '$dir3_layout'"
8656                 echo "root_dir_layout: '$root_dir_layout'"
8657                 error "$dir3 should show the default layout from $MOUNT"
8658         }
8659
8660         # set OST pool on root directory
8661         local pool=$TESTNAME
8662         pool_add $pool || error "add $pool failed"
8663         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8664                 error "add targets to $pool failed"
8665
8666         $LFS setstripe -p $pool $MOUNT ||
8667                 error "set OST pool on $MOUNT failed"
8668
8669         # new file created in $dir3 should inherit the pool from
8670         # the filesystem default
8671         local file3=$dir3/$tfile-3
8672         touch $file3 || error "touch $file3 failed"
8673
8674         local file3_pool=$($LFS getstripe -p $file3)
8675         [[ "$file3_pool" = "$pool" ]] ||
8676                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8677
8678         local dir4=$MOUNT/$tdir-4
8679         mkdir $dir4 || error "mkdir $dir4 failed"
8680         local dir4_layout=$(get_layout_param $dir4)
8681         root_dir_layout=$(get_layout_param $MOUNT)
8682         echo "$LFS getstripe -d $dir4"
8683         $LFS getstripe -d $dir4
8684         echo "$LFS getstripe -d $MOUNT"
8685         $LFS getstripe -d $MOUNT
8686         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8687         {
8688                 echo "dir4_layout: '$dir4_layout'"
8689                 echo "root_dir_layout: '$root_dir_layout'"
8690                 error "$dir4 should show the default layout from $MOUNT"
8691         }
8692
8693         # new file created in $dir4 should inherit the pool from
8694         # the filesystem default
8695         local file4=$dir4/$tfile-4
8696         touch $file4 || error "touch $file4 failed"
8697
8698         local file4_pool=$($LFS getstripe -p $file4)
8699         [[ "$file4_pool" = "$pool" ]] ||
8700                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8701
8702         # new subdirectory under non-root directory should inherit
8703         # the default layout from its parent directory
8704         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8705                 error "set directory layout on $dir4 failed"
8706
8707         local dir5=$dir4/$tdir-5
8708         mkdir $dir5 || error "mkdir $dir5 failed"
8709
8710         dir4_layout=$(get_layout_param $dir4)
8711         local dir5_layout=$(get_layout_param $dir5)
8712         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8713         {
8714                 echo "dir4_layout: '$dir4_layout'"
8715                 echo "dir5_layout: '$dir5_layout'"
8716                 error "$dir5 should inherit the default layout from $dir4"
8717         }
8718
8719         # though subdir under ROOT doesn't inherit default layout, but
8720         # its sub dir/file should be created with default layout.
8721         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8722         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8723                 skip "Need MDS version at least 2.12.59"
8724
8725         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8726         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8727         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8728
8729         if [ $default_lmv_hash == "none" ]; then
8730                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8731         else
8732                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8733                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8734         fi
8735
8736         $LFS setdirstripe -D -c 2 $MOUNT ||
8737                 error "setdirstripe -D -c 2 failed"
8738         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8739         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8740         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8741 }
8742 run_test 65n "don't inherit default layout from root for new subdirectories"
8743
8744 # bug 2543 - update blocks count on client
8745 test_66() {
8746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8747
8748         COUNT=${COUNT:-8}
8749         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8750         sync; sync_all_data; sync; sync_all_data
8751         cancel_lru_locks osc
8752         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8753         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8754 }
8755 run_test 66 "update inode blocks count on client ==============="
8756
8757 meminfo() {
8758         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8759 }
8760
8761 swap_used() {
8762         swapon -s | awk '($1 == "'$1'") { print $4 }'
8763 }
8764
8765 # bug5265, obdfilter oa2dentry return -ENOENT
8766 # #define OBD_FAIL_SRV_ENOENT 0x217
8767 test_69() {
8768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8769         remote_ost_nodsh && skip "remote OST with nodsh"
8770
8771         f="$DIR/$tfile"
8772         $LFS setstripe -c 1 -i 0 $f
8773
8774         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8775
8776         do_facet ost1 lctl set_param fail_loc=0x217
8777         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8778         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8779
8780         do_facet ost1 lctl set_param fail_loc=0
8781         $DIRECTIO write $f 0 2 || error "write error"
8782
8783         cancel_lru_locks osc
8784         $DIRECTIO read $f 0 1 || error "read error"
8785
8786         do_facet ost1 lctl set_param fail_loc=0x217
8787         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8788
8789         do_facet ost1 lctl set_param fail_loc=0
8790         rm -f $f
8791 }
8792 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8793
8794 test_71() {
8795         test_mkdir $DIR/$tdir
8796         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8797         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8798 }
8799 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8800
8801 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8803         [ "$RUNAS_ID" = "$UID" ] &&
8804                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8805         # Check that testing environment is properly set up. Skip if not
8806         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8807                 skip_env "User $RUNAS_ID does not exist - skipping"
8808
8809         touch $DIR/$tfile
8810         chmod 777 $DIR/$tfile
8811         chmod ug+s $DIR/$tfile
8812         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8813                 error "$RUNAS dd $DIR/$tfile failed"
8814         # See if we are still setuid/sgid
8815         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8816                 error "S/gid is not dropped on write"
8817         # Now test that MDS is updated too
8818         cancel_lru_locks mdc
8819         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8820                 error "S/gid is not dropped on MDS"
8821         rm -f $DIR/$tfile
8822 }
8823 run_test 72a "Test that remove suid works properly (bug5695) ===="
8824
8825 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8826         local perm
8827
8828         [ "$RUNAS_ID" = "$UID" ] &&
8829                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8830         [ "$RUNAS_ID" -eq 0 ] &&
8831                 skip_env "RUNAS_ID = 0 -- skipping"
8832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8833         # Check that testing environment is properly set up. Skip if not
8834         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8835                 skip_env "User $RUNAS_ID does not exist - skipping"
8836
8837         touch $DIR/${tfile}-f{g,u}
8838         test_mkdir $DIR/${tfile}-dg
8839         test_mkdir $DIR/${tfile}-du
8840         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8841         chmod g+s $DIR/${tfile}-{f,d}g
8842         chmod u+s $DIR/${tfile}-{f,d}u
8843         for perm in 777 2777 4777; do
8844                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8845                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8846                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8847                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8848         done
8849         true
8850 }
8851 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8852
8853 # bug 3462 - multiple simultaneous MDC requests
8854 test_73() {
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856
8857         test_mkdir $DIR/d73-1
8858         test_mkdir $DIR/d73-2
8859         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8860         pid1=$!
8861
8862         lctl set_param fail_loc=0x80000129
8863         $MULTIOP $DIR/d73-1/f73-2 Oc &
8864         sleep 1
8865         lctl set_param fail_loc=0
8866
8867         $MULTIOP $DIR/d73-2/f73-3 Oc &
8868         pid3=$!
8869
8870         kill -USR1 $pid1
8871         wait $pid1 || return 1
8872
8873         sleep 25
8874
8875         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8876         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8877         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8878
8879         rm -rf $DIR/d73-*
8880 }
8881 run_test 73 "multiple MDC requests (should not deadlock)"
8882
8883 test_74a() { # bug 6149, 6184
8884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8885
8886         touch $DIR/f74a
8887         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8888         #
8889         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8890         # will spin in a tight reconnection loop
8891         $LCTL set_param fail_loc=0x8000030e
8892         # get any lock that won't be difficult - lookup works.
8893         ls $DIR/f74a
8894         $LCTL set_param fail_loc=0
8895         rm -f $DIR/f74a
8896         true
8897 }
8898 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8899
8900 test_74b() { # bug 13310
8901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8902
8903         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8904         #
8905         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8906         # will spin in a tight reconnection loop
8907         $LCTL set_param fail_loc=0x8000030e
8908         # get a "difficult" lock
8909         touch $DIR/f74b
8910         $LCTL set_param fail_loc=0
8911         rm -f $DIR/f74b
8912         true
8913 }
8914 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8915
8916 test_74c() {
8917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8918
8919         #define OBD_FAIL_LDLM_NEW_LOCK
8920         $LCTL set_param fail_loc=0x319
8921         touch $DIR/$tfile && error "touch successful"
8922         $LCTL set_param fail_loc=0
8923         true
8924 }
8925 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8926
8927 slab_lic=/sys/kernel/slab/lustre_inode_cache
8928 num_objects() {
8929         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8930         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8931                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8932 }
8933
8934 test_76a() { # Now for b=20433, added originally in b=1443
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         cancel_lru_locks osc
8938         # there may be some slab objects cached per core
8939         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8940         local before=$(num_objects)
8941         local count=$((512 * cpus))
8942         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8943         local margin=$((count / 10))
8944         if [[ -f $slab_lic/aliases ]]; then
8945                 local aliases=$(cat $slab_lic/aliases)
8946                 (( aliases > 0 )) && margin=$((margin * aliases))
8947         fi
8948
8949         echo "before slab objects: $before"
8950         for i in $(seq $count); do
8951                 touch $DIR/$tfile
8952                 rm -f $DIR/$tfile
8953         done
8954         cancel_lru_locks osc
8955         local after=$(num_objects)
8956         echo "created: $count, after slab objects: $after"
8957         # shared slab counts are not very accurate, allow significant margin
8958         # the main goal is that the cache growth is not permanently > $count
8959         while (( after > before + margin )); do
8960                 sleep 1
8961                 after=$(num_objects)
8962                 wait=$((wait + 1))
8963                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8964                 if (( wait > 60 )); then
8965                         error "inode slab grew from $before+$margin to $after"
8966                 fi
8967         done
8968 }
8969 run_test 76a "confirm clients recycle inodes properly ===="
8970
8971 test_76b() {
8972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8973         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8974
8975         local count=512
8976         local before=$(num_objects)
8977
8978         for i in $(seq $count); do
8979                 mkdir $DIR/$tdir
8980                 rmdir $DIR/$tdir
8981         done
8982
8983         local after=$(num_objects)
8984         local wait=0
8985
8986         while (( after > before )); do
8987                 sleep 1
8988                 after=$(num_objects)
8989                 wait=$((wait + 1))
8990                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8991                 if (( wait > 60 )); then
8992                         error "inode slab grew from $before to $after"
8993                 fi
8994         done
8995
8996         echo "slab objects before: $before, after: $after"
8997 }
8998 run_test 76b "confirm clients recycle directory inodes properly ===="
8999
9000 export ORIG_CSUM=""
9001 set_checksums()
9002 {
9003         # Note: in sptlrpc modes which enable its own bulk checksum, the
9004         # original crc32_le bulk checksum will be automatically disabled,
9005         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9006         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9007         # In this case set_checksums() will not be no-op, because sptlrpc
9008         # bulk checksum will be enabled all through the test.
9009
9010         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9011         lctl set_param -n osc.*.checksums $1
9012         return 0
9013 }
9014
9015 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9016                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9017 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9018                              tr -d [] | head -n1)}
9019 set_checksum_type()
9020 {
9021         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9022         rc=$?
9023         log "set checksum type to $1, rc = $rc"
9024         return $rc
9025 }
9026
9027 get_osc_checksum_type()
9028 {
9029         # arugment 1: OST name, like OST0000
9030         ost=$1
9031         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9032                         sed 's/.*\[\(.*\)\].*/\1/g')
9033         rc=$?
9034         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9035         echo $checksum_type
9036 }
9037
9038 F77_TMP=$TMP/f77-temp
9039 F77SZ=8
9040 setup_f77() {
9041         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9042                 error "error writing to $F77_TMP"
9043 }
9044
9045 test_77a() { # bug 10889
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047         $GSS && skip_env "could not run with gss"
9048
9049         [ ! -f $F77_TMP ] && setup_f77
9050         set_checksums 1
9051         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9052         set_checksums 0
9053         rm -f $DIR/$tfile
9054 }
9055 run_test 77a "normal checksum read/write operation"
9056
9057 test_77b() { # bug 10889
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059         $GSS && skip_env "could not run with gss"
9060
9061         [ ! -f $F77_TMP ] && setup_f77
9062         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9063         $LCTL set_param fail_loc=0x80000409
9064         set_checksums 1
9065
9066         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9067                 error "dd error: $?"
9068         $LCTL set_param fail_loc=0
9069
9070         for algo in $CKSUM_TYPES; do
9071                 cancel_lru_locks osc
9072                 set_checksum_type $algo
9073                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9074                 $LCTL set_param fail_loc=0x80000408
9075                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9076                 $LCTL set_param fail_loc=0
9077         done
9078         set_checksums 0
9079         set_checksum_type $ORIG_CSUM_TYPE
9080         rm -f $DIR/$tfile
9081 }
9082 run_test 77b "checksum error on client write, read"
9083
9084 cleanup_77c() {
9085         trap 0
9086         set_checksums 0
9087         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9088         $check_ost &&
9089                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9090         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9091         $check_ost && [ -n "$ost_file_prefix" ] &&
9092                 do_facet ost1 rm -f ${ost_file_prefix}\*
9093 }
9094
9095 test_77c() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097         $GSS && skip_env "could not run with gss"
9098         remote_ost_nodsh && skip "remote OST with nodsh"
9099
9100         local bad1
9101         local osc_file_prefix
9102         local osc_file
9103         local check_ost=false
9104         local ost_file_prefix
9105         local ost_file
9106         local orig_cksum
9107         local dump_cksum
9108         local fid
9109
9110         # ensure corruption will occur on first OSS/OST
9111         $LFS setstripe -i 0 $DIR/$tfile
9112
9113         [ ! -f $F77_TMP ] && setup_f77
9114         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9115                 error "dd write error: $?"
9116         fid=$($LFS path2fid $DIR/$tfile)
9117
9118         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9119         then
9120                 check_ost=true
9121                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9122                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9123         else
9124                 echo "OSS do not support bulk pages dump upon error"
9125         fi
9126
9127         osc_file_prefix=$($LCTL get_param -n debug_path)
9128         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9129
9130         trap cleanup_77c EXIT
9131
9132         set_checksums 1
9133         # enable bulk pages dump upon error on Client
9134         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9135         # enable bulk pages dump upon error on OSS
9136         $check_ost &&
9137                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9138
9139         # flush Client cache to allow next read to reach OSS
9140         cancel_lru_locks osc
9141
9142         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9143         $LCTL set_param fail_loc=0x80000408
9144         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9145         $LCTL set_param fail_loc=0
9146
9147         rm -f $DIR/$tfile
9148
9149         # check cksum dump on Client
9150         osc_file=$(ls ${osc_file_prefix}*)
9151         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9152         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9153         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9154         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9155         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9156                      cksum)
9157         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9158         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9159                 error "dump content does not match on Client"
9160
9161         $check_ost || skip "No need to check cksum dump on OSS"
9162
9163         # check cksum dump on OSS
9164         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9165         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9166         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9167         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9168         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9169                 error "dump content does not match on OSS"
9170
9171         cleanup_77c
9172 }
9173 run_test 77c "checksum error on client read with debug"
9174
9175 test_77d() { # bug 10889
9176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9177         $GSS && skip_env "could not run with gss"
9178
9179         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9180         $LCTL set_param fail_loc=0x80000409
9181         set_checksums 1
9182         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9183                 error "direct write: rc=$?"
9184         $LCTL set_param fail_loc=0
9185         set_checksums 0
9186
9187         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9188         $LCTL set_param fail_loc=0x80000408
9189         set_checksums 1
9190         cancel_lru_locks osc
9191         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9192                 error "direct read: rc=$?"
9193         $LCTL set_param fail_loc=0
9194         set_checksums 0
9195 }
9196 run_test 77d "checksum error on OST direct write, read"
9197
9198 test_77f() { # bug 10889
9199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9200         $GSS && skip_env "could not run with gss"
9201
9202         set_checksums 1
9203         for algo in $CKSUM_TYPES; do
9204                 cancel_lru_locks osc
9205                 set_checksum_type $algo
9206                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9207                 $LCTL set_param fail_loc=0x409
9208                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9209                         error "direct write succeeded"
9210                 $LCTL set_param fail_loc=0
9211         done
9212         set_checksum_type $ORIG_CSUM_TYPE
9213         set_checksums 0
9214 }
9215 run_test 77f "repeat checksum error on write (expect error)"
9216
9217 test_77g() { # bug 10889
9218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9219         $GSS && skip_env "could not run with gss"
9220         remote_ost_nodsh && skip "remote OST with nodsh"
9221
9222         [ ! -f $F77_TMP ] && setup_f77
9223
9224         local file=$DIR/$tfile
9225         stack_trap "rm -f $file" EXIT
9226
9227         $LFS setstripe -c 1 -i 0 $file
9228         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9229         do_facet ost1 lctl set_param fail_loc=0x8000021a
9230         set_checksums 1
9231         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9232                 error "write error: rc=$?"
9233         do_facet ost1 lctl set_param fail_loc=0
9234         set_checksums 0
9235
9236         cancel_lru_locks osc
9237         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9238         do_facet ost1 lctl set_param fail_loc=0x8000021b
9239         set_checksums 1
9240         cmp $F77_TMP $file || error "file compare failed"
9241         do_facet ost1 lctl set_param fail_loc=0
9242         set_checksums 0
9243 }
9244 run_test 77g "checksum error on OST write, read"
9245
9246 test_77k() { # LU-10906
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248         $GSS && skip_env "could not run with gss"
9249
9250         local cksum_param="osc.$FSNAME*.checksums"
9251         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9252         local checksum
9253         local i
9254
9255         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9256         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9257         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9258
9259         for i in 0 1; do
9260                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9261                         error "failed to set checksum=$i on MGS"
9262                 wait_update $HOSTNAME "$get_checksum" $i
9263                 #remount
9264                 echo "remount client, checksum should be $i"
9265                 remount_client $MOUNT || error "failed to remount client"
9266                 checksum=$(eval $get_checksum)
9267                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9268         done
9269         # remove persistent param to avoid races with checksum mountopt below
9270         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9271                 error "failed to delete checksum on MGS"
9272
9273         for opt in "checksum" "nochecksum"; do
9274                 #remount with mount option
9275                 echo "remount client with option $opt, checksum should be $i"
9276                 umount_client $MOUNT || error "failed to umount client"
9277                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9278                         error "failed to mount client with option '$opt'"
9279                 checksum=$(eval $get_checksum)
9280                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9281                 i=$((i - 1))
9282         done
9283
9284         remount_client $MOUNT || error "failed to remount client"
9285 }
9286 run_test 77k "enable/disable checksum correctly"
9287
9288 test_77l() {
9289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9290         $GSS && skip_env "could not run with gss"
9291
9292         set_checksums 1
9293         stack_trap "set_checksums $ORIG_CSUM" EXIT
9294         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9295
9296         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9297
9298         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9299         for algo in $CKSUM_TYPES; do
9300                 set_checksum_type $algo || error "fail to set checksum type $algo"
9301                 osc_algo=$(get_osc_checksum_type OST0000)
9302                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9303
9304                 # no locks, no reqs to let the connection idle
9305                 cancel_lru_locks osc
9306                 lru_resize_disable osc
9307                 wait_osc_import_state client ost1 IDLE
9308
9309                 # ensure ost1 is connected
9310                 stat $DIR/$tfile >/dev/null || error "can't stat"
9311                 wait_osc_import_state client ost1 FULL
9312
9313                 osc_algo=$(get_osc_checksum_type OST0000)
9314                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9315         done
9316         return 0
9317 }
9318 run_test 77l "preferred checksum type is remembered after reconnected"
9319
9320 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9321 rm -f $F77_TMP
9322 unset F77_TMP
9323
9324 cleanup_test_78() {
9325         trap 0
9326         rm -f $DIR/$tfile
9327 }
9328
9329 test_78() { # bug 10901
9330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9331         remote_ost || skip_env "local OST"
9332
9333         NSEQ=5
9334         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9335         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9336         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9337         echo "MemTotal: $MEMTOTAL"
9338
9339         # reserve 256MB of memory for the kernel and other running processes,
9340         # and then take 1/2 of the remaining memory for the read/write buffers.
9341         if [ $MEMTOTAL -gt 512 ] ;then
9342                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9343         else
9344                 # for those poor memory-starved high-end clusters...
9345                 MEMTOTAL=$((MEMTOTAL / 2))
9346         fi
9347         echo "Mem to use for directio: $MEMTOTAL"
9348
9349         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9350         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9351         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9352         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9353                 head -n1)
9354         echo "Smallest OST: $SMALLESTOST"
9355         [[ $SMALLESTOST -lt 10240 ]] &&
9356                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9357
9358         trap cleanup_test_78 EXIT
9359
9360         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9361                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9362
9363         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9364         echo "File size: $F78SIZE"
9365         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9366         for i in $(seq 1 $NSEQ); do
9367                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9368                 echo directIO rdwr round $i of $NSEQ
9369                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9370         done
9371
9372         cleanup_test_78
9373 }
9374 run_test 78 "handle large O_DIRECT writes correctly ============"
9375
9376 test_79() { # bug 12743
9377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9378
9379         wait_delete_completed
9380
9381         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9382         BKFREE=$(calc_osc_kbytes kbytesfree)
9383         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9384
9385         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9386         DFTOTAL=`echo $STRING | cut -d, -f1`
9387         DFUSED=`echo $STRING  | cut -d, -f2`
9388         DFAVAIL=`echo $STRING | cut -d, -f3`
9389         DFFREE=$(($DFTOTAL - $DFUSED))
9390
9391         ALLOWANCE=$((64 * $OSTCOUNT))
9392
9393         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9394            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9395                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9396         fi
9397         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9398            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9399                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9400         fi
9401         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9402            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9403                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9404         fi
9405 }
9406 run_test 79 "df report consistency check ======================="
9407
9408 test_80() { # bug 10718
9409         remote_ost_nodsh && skip "remote OST with nodsh"
9410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9411
9412         # relax strong synchronous semantics for slow backends like ZFS
9413         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9414                 local soc="obdfilter.*.sync_lock_cancel"
9415                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9416
9417                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9418                 if [ -z "$save" ]; then
9419                         soc="obdfilter.*.sync_on_lock_cancel"
9420                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9421                 fi
9422
9423                 if [ "$save" != "never" ]; then
9424                         local hosts=$(comma_list $(osts_nodes))
9425
9426                         do_nodes $hosts $LCTL set_param $soc=never
9427                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9428                 fi
9429         fi
9430
9431         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9432         sync; sleep 1; sync
9433         local before=$(date +%s)
9434         cancel_lru_locks osc
9435         local after=$(date +%s)
9436         local diff=$((after - before))
9437         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9438
9439         rm -f $DIR/$tfile
9440 }
9441 run_test 80 "Page eviction is equally fast at high offsets too"
9442
9443 test_81a() { # LU-456
9444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9445         remote_ost_nodsh && skip "remote OST with nodsh"
9446
9447         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9448         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9449         do_facet ost1 lctl set_param fail_loc=0x80000228
9450
9451         # write should trigger a retry and success
9452         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9453         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9454         RC=$?
9455         if [ $RC -ne 0 ] ; then
9456                 error "write should success, but failed for $RC"
9457         fi
9458 }
9459 run_test 81a "OST should retry write when get -ENOSPC ==============="
9460
9461 test_81b() { # LU-456
9462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9463         remote_ost_nodsh && skip "remote OST with nodsh"
9464
9465         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9466         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9467         do_facet ost1 lctl set_param fail_loc=0x228
9468
9469         # write should retry several times and return -ENOSPC finally
9470         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9471         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9472         RC=$?
9473         ENOSPC=28
9474         if [ $RC -ne $ENOSPC ] ; then
9475                 error "dd should fail for -ENOSPC, but succeed."
9476         fi
9477 }
9478 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9479
9480 test_99() {
9481         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9482
9483         test_mkdir $DIR/$tdir.cvsroot
9484         chown $RUNAS_ID $DIR/$tdir.cvsroot
9485
9486         cd $TMP
9487         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9488
9489         cd /etc/init.d
9490         # some versions of cvs import exit(1) when asked to import links or
9491         # files they can't read.  ignore those files.
9492         local toignore=$(find . -type l -printf '-I %f\n' -o \
9493                          ! -perm /4 -printf '-I %f\n')
9494         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9495                 $tdir.reposname vtag rtag
9496
9497         cd $DIR
9498         test_mkdir $DIR/$tdir.reposname
9499         chown $RUNAS_ID $DIR/$tdir.reposname
9500         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9501
9502         cd $DIR/$tdir.reposname
9503         $RUNAS touch foo99
9504         $RUNAS cvs add -m 'addmsg' foo99
9505         $RUNAS cvs update
9506         $RUNAS cvs commit -m 'nomsg' foo99
9507         rm -fr $DIR/$tdir.cvsroot
9508 }
9509 run_test 99 "cvs strange file/directory operations"
9510
9511 test_100() {
9512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9513         [[ "$NETTYPE" =~ tcp ]] ||
9514                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9515         remote_ost_nodsh && skip "remote OST with nodsh"
9516         remote_mds_nodsh && skip "remote MDS with nodsh"
9517         remote_servers ||
9518                 skip "useless for local single node setup"
9519
9520         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9521                 [ "$PROT" != "tcp" ] && continue
9522                 RPORT=$(echo $REMOTE | cut -d: -f2)
9523                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9524
9525                 rc=0
9526                 LPORT=`echo $LOCAL | cut -d: -f2`
9527                 if [ $LPORT -ge 1024 ]; then
9528                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9529                         netstat -tna
9530                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9531                 fi
9532         done
9533         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9534 }
9535 run_test 100 "check local port using privileged port ==========="
9536
9537 function get_named_value()
9538 {
9539     local tag
9540
9541     tag=$1
9542     while read ;do
9543         line=$REPLY
9544         case $line in
9545         $tag*)
9546             echo $line | sed "s/^$tag[ ]*//"
9547             break
9548             ;;
9549         esac
9550     done
9551 }
9552
9553 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9554                    awk '/^max_cached_mb/ { print $2 }')
9555
9556 cleanup_101a() {
9557         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9558         trap 0
9559 }
9560
9561 test_101a() {
9562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9563
9564         local s
9565         local discard
9566         local nreads=10000
9567         local cache_limit=32
9568
9569         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9570         trap cleanup_101a EXIT
9571         $LCTL set_param -n llite.*.read_ahead_stats 0
9572         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9573
9574         #
9575         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9576         #
9577         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9578         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9579
9580         discard=0
9581         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9582                 get_named_value 'read but discarded' | cut -d" " -f1); do
9583                         discard=$(($discard + $s))
9584         done
9585         cleanup_101a
9586
9587         $LCTL get_param osc.*-osc*.rpc_stats
9588         $LCTL get_param llite.*.read_ahead_stats
9589
9590         # Discard is generally zero, but sometimes a few random reads line up
9591         # and trigger larger readahead, which is wasted & leads to discards.
9592         if [[ $(($discard)) -gt $nreads ]]; then
9593                 error "too many ($discard) discarded pages"
9594         fi
9595         rm -f $DIR/$tfile || true
9596 }
9597 run_test 101a "check read-ahead for random reads"
9598
9599 setup_test101bc() {
9600         test_mkdir $DIR/$tdir
9601         local ssize=$1
9602         local FILE_LENGTH=$2
9603         STRIPE_OFFSET=0
9604
9605         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9606
9607         local list=$(comma_list $(osts_nodes))
9608         set_osd_param $list '' read_cache_enable 0
9609         set_osd_param $list '' writethrough_cache_enable 0
9610
9611         trap cleanup_test101bc EXIT
9612         # prepare the read-ahead file
9613         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9614
9615         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9616                                 count=$FILE_SIZE_MB 2> /dev/null
9617
9618 }
9619
9620 cleanup_test101bc() {
9621         trap 0
9622         rm -rf $DIR/$tdir
9623         rm -f $DIR/$tfile
9624
9625         local list=$(comma_list $(osts_nodes))
9626         set_osd_param $list '' read_cache_enable 1
9627         set_osd_param $list '' writethrough_cache_enable 1
9628 }
9629
9630 calc_total() {
9631         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9632 }
9633
9634 ra_check_101() {
9635         local READ_SIZE=$1
9636         local STRIPE_SIZE=$2
9637         local FILE_LENGTH=$3
9638         local RA_INC=1048576
9639         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9640         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9641                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9642         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9643                         get_named_value 'read but discarded' |
9644                         cut -d" " -f1 | calc_total)
9645         if [[ $DISCARD -gt $discard_limit ]]; then
9646                 $LCTL get_param llite.*.read_ahead_stats
9647                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9648         else
9649                 echo "Read-ahead success for size ${READ_SIZE}"
9650         fi
9651 }
9652
9653 test_101b() {
9654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9655         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9656
9657         local STRIPE_SIZE=1048576
9658         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9659
9660         if [ $SLOW == "yes" ]; then
9661                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9662         else
9663                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9664         fi
9665
9666         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9667
9668         # prepare the read-ahead file
9669         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9670         cancel_lru_locks osc
9671         for BIDX in 2 4 8 16 32 64 128 256
9672         do
9673                 local BSIZE=$((BIDX*4096))
9674                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9675                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9676                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9677                 $LCTL set_param -n llite.*.read_ahead_stats 0
9678                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9679                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9680                 cancel_lru_locks osc
9681                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9682         done
9683         cleanup_test101bc
9684         true
9685 }
9686 run_test 101b "check stride-io mode read-ahead ================="
9687
9688 test_101c() {
9689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9690
9691         local STRIPE_SIZE=1048576
9692         local FILE_LENGTH=$((STRIPE_SIZE*100))
9693         local nreads=10000
9694         local rsize=65536
9695         local osc_rpc_stats
9696
9697         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9698
9699         cancel_lru_locks osc
9700         $LCTL set_param osc.*.rpc_stats 0
9701         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9702         $LCTL get_param osc.*.rpc_stats
9703         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9704                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9705                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9706                 local size
9707
9708                 if [ $lines -le 20 ]; then
9709                         echo "continue debug"
9710                         continue
9711                 fi
9712                 for size in 1 2 4 8; do
9713                         local rpc=$(echo "$stats" |
9714                                     awk '($1 == "'$size':") {print $2; exit; }')
9715                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9716                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9717                 done
9718                 echo "$osc_rpc_stats check passed!"
9719         done
9720         cleanup_test101bc
9721         true
9722 }
9723 run_test 101c "check stripe_size aligned read-ahead ================="
9724
9725 test_101d() {
9726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9727
9728         local file=$DIR/$tfile
9729         local sz_MB=${FILESIZE_101d:-80}
9730         local ra_MB=${READAHEAD_MB:-40}
9731
9732         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9733         [ $free_MB -lt $sz_MB ] &&
9734                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9735
9736         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9737         $LFS setstripe -c -1 $file || error "setstripe failed"
9738
9739         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9740         echo Cancel LRU locks on lustre client to flush the client cache
9741         cancel_lru_locks osc
9742
9743         echo Disable read-ahead
9744         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9745         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9746         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9747         $LCTL get_param -n llite.*.max_read_ahead_mb
9748
9749         echo "Reading the test file $file with read-ahead disabled"
9750         local sz_KB=$((sz_MB * 1024 / 4))
9751         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9752         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9753         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9754                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9755
9756         echo "Cancel LRU locks on lustre client to flush the client cache"
9757         cancel_lru_locks osc
9758         echo Enable read-ahead with ${ra_MB}MB
9759         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9760
9761         echo "Reading the test file $file with read-ahead enabled"
9762         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9763                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9764
9765         echo "read-ahead disabled time read $raOFF"
9766         echo "read-ahead enabled time read $raON"
9767
9768         rm -f $file
9769         wait_delete_completed
9770
9771         # use awk for this check instead of bash because it handles decimals
9772         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9773                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9774 }
9775 run_test 101d "file read with and without read-ahead enabled"
9776
9777 test_101e() {
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779
9780         local file=$DIR/$tfile
9781         local size_KB=500  #KB
9782         local count=100
9783         local bsize=1024
9784
9785         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9786         local need_KB=$((count * size_KB))
9787         [[ $free_KB -le $need_KB ]] &&
9788                 skip_env "Need free space $need_KB, have $free_KB"
9789
9790         echo "Creating $count ${size_KB}K test files"
9791         for ((i = 0; i < $count; i++)); do
9792                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9793         done
9794
9795         echo "Cancel LRU locks on lustre client to flush the client cache"
9796         cancel_lru_locks $OSC
9797
9798         echo "Reset readahead stats"
9799         $LCTL set_param -n llite.*.read_ahead_stats 0
9800
9801         for ((i = 0; i < $count; i++)); do
9802                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9803         done
9804
9805         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9806                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9807
9808         for ((i = 0; i < $count; i++)); do
9809                 rm -rf $file.$i 2>/dev/null
9810         done
9811
9812         #10000 means 20% reads are missing in readahead
9813         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9814 }
9815 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9816
9817 test_101f() {
9818         which iozone || skip_env "no iozone installed"
9819
9820         local old_debug=$($LCTL get_param debug)
9821         old_debug=${old_debug#*=}
9822         $LCTL set_param debug="reada mmap"
9823
9824         # create a test file
9825         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9826
9827         echo Cancel LRU locks on lustre client to flush the client cache
9828         cancel_lru_locks osc
9829
9830         echo Reset readahead stats
9831         $LCTL set_param -n llite.*.read_ahead_stats 0
9832
9833         echo mmap read the file with small block size
9834         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9835                 > /dev/null 2>&1
9836
9837         echo checking missing pages
9838         $LCTL get_param llite.*.read_ahead_stats
9839         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9840                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9841
9842         $LCTL set_param debug="$old_debug"
9843         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9844         rm -f $DIR/$tfile
9845 }
9846 run_test 101f "check mmap read performance"
9847
9848 test_101g_brw_size_test() {
9849         local mb=$1
9850         local pages=$((mb * 1048576 / PAGE_SIZE))
9851         local file=$DIR/$tfile
9852
9853         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9854                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9855         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9856                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9857                         return 2
9858         done
9859
9860         stack_trap "rm -f $file" EXIT
9861         $LCTL set_param -n osc.*.rpc_stats=0
9862
9863         # 10 RPCs should be enough for the test
9864         local count=10
9865         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9866                 { error "dd write ${mb} MB blocks failed"; return 3; }
9867         cancel_lru_locks osc
9868         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9869                 { error "dd write ${mb} MB blocks failed"; return 4; }
9870
9871         # calculate number of full-sized read and write RPCs
9872         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9873                 sed -n '/pages per rpc/,/^$/p' |
9874                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9875                 END { print reads,writes }'))
9876         # allow one extra full-sized read RPC for async readahead
9877         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9878                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9879         [[ ${rpcs[1]} == $count ]] ||
9880                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9881 }
9882
9883 test_101g() {
9884         remote_ost_nodsh && skip "remote OST with nodsh"
9885
9886         local rpcs
9887         local osts=$(get_facets OST)
9888         local list=$(comma_list $(osts_nodes))
9889         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9890         local brw_size="obdfilter.*.brw_size"
9891
9892         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9893
9894         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9895
9896         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9897                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9898                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9899            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9900                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9901                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9902
9903                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9904                         suffix="M"
9905
9906                 if [[ $orig_mb -lt 16 ]]; then
9907                         save_lustre_params $osts "$brw_size" > $p
9908                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9909                                 error "set 16MB RPC size failed"
9910
9911                         echo "remount client to enable new RPC size"
9912                         remount_client $MOUNT || error "remount_client failed"
9913                 fi
9914
9915                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9916                 # should be able to set brw_size=12, but no rpc_stats for that
9917                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9918         fi
9919
9920         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9921
9922         if [[ $orig_mb -lt 16 ]]; then
9923                 restore_lustre_params < $p
9924                 remount_client $MOUNT || error "remount_client restore failed"
9925         fi
9926
9927         rm -f $p $DIR/$tfile
9928 }
9929 run_test 101g "Big bulk(4/16 MiB) readahead"
9930
9931 test_101h() {
9932         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9933
9934         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9935                 error "dd 70M file failed"
9936         echo Cancel LRU locks on lustre client to flush the client cache
9937         cancel_lru_locks osc
9938
9939         echo "Reset readahead stats"
9940         $LCTL set_param -n llite.*.read_ahead_stats 0
9941
9942         echo "Read 10M of data but cross 64M bundary"
9943         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9944         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9945                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9946         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9947         rm -f $p $DIR/$tfile
9948 }
9949 run_test 101h "Readahead should cover current read window"
9950
9951 test_101i() {
9952         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9953                 error "dd 10M file failed"
9954
9955         local max_per_file_mb=$($LCTL get_param -n \
9956                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9957         cancel_lru_locks osc
9958         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9959         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9960                 error "set max_read_ahead_per_file_mb to 1 failed"
9961
9962         echo "Reset readahead stats"
9963         $LCTL set_param llite.*.read_ahead_stats=0
9964
9965         dd if=$DIR/$tfile of=/dev/null bs=2M
9966
9967         $LCTL get_param llite.*.read_ahead_stats
9968         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9969                      awk '/misses/ { print $2 }')
9970         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9971         rm -f $DIR/$tfile
9972 }
9973 run_test 101i "allow current readahead to exceed reservation"
9974
9975 test_101j() {
9976         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9977                 error "setstripe $DIR/$tfile failed"
9978         local file_size=$((1048576 * 16))
9979         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9980         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9981
9982         echo Disable read-ahead
9983         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9984
9985         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9986         for blk in $PAGE_SIZE 1048576 $file_size; do
9987                 cancel_lru_locks osc
9988                 echo "Reset readahead stats"
9989                 $LCTL set_param -n llite.*.read_ahead_stats=0
9990                 local count=$(($file_size / $blk))
9991                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9992                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9993                              get_named_value 'failed to fast read' |
9994                              cut -d" " -f1 | calc_total)
9995                 $LCTL get_param -n llite.*.read_ahead_stats
9996                 [ $miss -eq $count ] || error "expected $count got $miss"
9997         done
9998
9999         rm -f $p $DIR/$tfile
10000 }
10001 run_test 101j "A complete read block should be submitted when no RA"
10002
10003 setup_test102() {
10004         test_mkdir $DIR/$tdir
10005         chown $RUNAS_ID $DIR/$tdir
10006         STRIPE_SIZE=65536
10007         STRIPE_OFFSET=1
10008         STRIPE_COUNT=$OSTCOUNT
10009         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10010
10011         trap cleanup_test102 EXIT
10012         cd $DIR
10013         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10014         cd $DIR/$tdir
10015         for num in 1 2 3 4; do
10016                 for count in $(seq 1 $STRIPE_COUNT); do
10017                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10018                                 local size=`expr $STRIPE_SIZE \* $num`
10019                                 local file=file"$num-$idx-$count"
10020                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10021                         done
10022                 done
10023         done
10024
10025         cd $DIR
10026         $1 tar cf $TMP/f102.tar $tdir --xattrs
10027 }
10028
10029 cleanup_test102() {
10030         trap 0
10031         rm -f $TMP/f102.tar
10032         rm -rf $DIR/d0.sanity/d102
10033 }
10034
10035 test_102a() {
10036         [ "$UID" != 0 ] && skip "must run as root"
10037         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10038                 skip_env "must have user_xattr"
10039
10040         [ -z "$(which setfattr 2>/dev/null)" ] &&
10041                 skip_env "could not find setfattr"
10042
10043         local testfile=$DIR/$tfile
10044
10045         touch $testfile
10046         echo "set/get xattr..."
10047         setfattr -n trusted.name1 -v value1 $testfile ||
10048                 error "setfattr -n trusted.name1=value1 $testfile failed"
10049         getfattr -n trusted.name1 $testfile 2> /dev/null |
10050           grep "trusted.name1=.value1" ||
10051                 error "$testfile missing trusted.name1=value1"
10052
10053         setfattr -n user.author1 -v author1 $testfile ||
10054                 error "setfattr -n user.author1=author1 $testfile failed"
10055         getfattr -n user.author1 $testfile 2> /dev/null |
10056           grep "user.author1=.author1" ||
10057                 error "$testfile missing trusted.author1=author1"
10058
10059         echo "listxattr..."
10060         setfattr -n trusted.name2 -v value2 $testfile ||
10061                 error "$testfile unable to set trusted.name2"
10062         setfattr -n trusted.name3 -v value3 $testfile ||
10063                 error "$testfile unable to set trusted.name3"
10064         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10065             grep "trusted.name" | wc -l) -eq 3 ] ||
10066                 error "$testfile missing 3 trusted.name xattrs"
10067
10068         setfattr -n user.author2 -v author2 $testfile ||
10069                 error "$testfile unable to set user.author2"
10070         setfattr -n user.author3 -v author3 $testfile ||
10071                 error "$testfile unable to set user.author3"
10072         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10073             grep "user.author" | wc -l) -eq 3 ] ||
10074                 error "$testfile missing 3 user.author xattrs"
10075
10076         echo "remove xattr..."
10077         setfattr -x trusted.name1 $testfile ||
10078                 error "$testfile error deleting trusted.name1"
10079         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10080                 error "$testfile did not delete trusted.name1 xattr"
10081
10082         setfattr -x user.author1 $testfile ||
10083                 error "$testfile error deleting user.author1"
10084         echo "set lustre special xattr ..."
10085         $LFS setstripe -c1 $testfile
10086         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10087                 awk -F "=" '/trusted.lov/ { print $2 }' )
10088         setfattr -n "trusted.lov" -v $lovea $testfile ||
10089                 error "$testfile doesn't ignore setting trusted.lov again"
10090         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10091                 error "$testfile allow setting invalid trusted.lov"
10092         rm -f $testfile
10093 }
10094 run_test 102a "user xattr test =================================="
10095
10096 check_102b_layout() {
10097         local layout="$*"
10098         local testfile=$DIR/$tfile
10099
10100         echo "test layout '$layout'"
10101         $LFS setstripe $layout $testfile || error "setstripe failed"
10102         $LFS getstripe -y $testfile
10103
10104         echo "get/set/list trusted.lov xattr ..." # b=10930
10105         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10106         [[ "$value" =~ "trusted.lov" ]] ||
10107                 error "can't get trusted.lov from $testfile"
10108         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10109                 error "getstripe failed"
10110
10111         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10112
10113         value=$(cut -d= -f2 <<<$value)
10114         # LU-13168: truncated xattr should fail if short lov_user_md header
10115         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10116                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10117         for len in $lens; do
10118                 echo "setfattr $len $testfile.2"
10119                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10120                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10121         done
10122         local stripe_size=$($LFS getstripe -S $testfile.2)
10123         local stripe_count=$($LFS getstripe -c $testfile.2)
10124         [[ $stripe_size -eq 65536 ]] ||
10125                 error "stripe size $stripe_size != 65536"
10126         [[ $stripe_count -eq $stripe_count_orig ]] ||
10127                 error "stripe count $stripe_count != $stripe_count_orig"
10128         rm $testfile $testfile.2
10129 }
10130
10131 test_102b() {
10132         [ -z "$(which setfattr 2>/dev/null)" ] &&
10133                 skip_env "could not find setfattr"
10134         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10135
10136         # check plain layout
10137         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10138
10139         # and also check composite layout
10140         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10141
10142 }
10143 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10144
10145 test_102c() {
10146         [ -z "$(which setfattr 2>/dev/null)" ] &&
10147                 skip_env "could not find setfattr"
10148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10149
10150         # b10930: get/set/list lustre.lov xattr
10151         echo "get/set/list lustre.lov xattr ..."
10152         test_mkdir $DIR/$tdir
10153         chown $RUNAS_ID $DIR/$tdir
10154         local testfile=$DIR/$tdir/$tfile
10155         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10156                 error "setstripe failed"
10157         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10158                 error "getstripe failed"
10159         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10160         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10161
10162         local testfile2=${testfile}2
10163         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10164                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10165
10166         $RUNAS $MCREATE $testfile2
10167         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10168         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10169         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10170         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10171         [ $stripe_count -eq $STRIPECOUNT ] ||
10172                 error "stripe count $stripe_count != $STRIPECOUNT"
10173 }
10174 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10175
10176 compare_stripe_info1() {
10177         local stripe_index_all_zero=true
10178
10179         for num in 1 2 3 4; do
10180                 for count in $(seq 1 $STRIPE_COUNT); do
10181                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10182                                 local size=$((STRIPE_SIZE * num))
10183                                 local file=file"$num-$offset-$count"
10184                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10185                                 [[ $stripe_size -ne $size ]] &&
10186                                     error "$file: size $stripe_size != $size"
10187                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10188                                 # allow fewer stripes to be created, ORI-601
10189                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10190                                     error "$file: count $stripe_count != $count"
10191                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10192                                 [[ $stripe_index -ne 0 ]] &&
10193                                         stripe_index_all_zero=false
10194                         done
10195                 done
10196         done
10197         $stripe_index_all_zero &&
10198                 error "all files are being extracted starting from OST index 0"
10199         return 0
10200 }
10201
10202 have_xattrs_include() {
10203         tar --help | grep -q xattrs-include &&
10204                 echo --xattrs-include="lustre.*"
10205 }
10206
10207 test_102d() {
10208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10209         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10210
10211         XINC=$(have_xattrs_include)
10212         setup_test102
10213         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10214         cd $DIR/$tdir/$tdir
10215         compare_stripe_info1
10216 }
10217 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10218
10219 test_102f() {
10220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10221         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10222
10223         XINC=$(have_xattrs_include)
10224         setup_test102
10225         test_mkdir $DIR/$tdir.restore
10226         cd $DIR
10227         tar cf - --xattrs $tdir | tar xf - \
10228                 -C $DIR/$tdir.restore --xattrs $XINC
10229         cd $DIR/$tdir.restore/$tdir
10230         compare_stripe_info1
10231 }
10232 run_test 102f "tar copy files, not keep osts"
10233
10234 grow_xattr() {
10235         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10236                 skip "must have user_xattr"
10237         [ -z "$(which setfattr 2>/dev/null)" ] &&
10238                 skip_env "could not find setfattr"
10239         [ -z "$(which getfattr 2>/dev/null)" ] &&
10240                 skip_env "could not find getfattr"
10241
10242         local xsize=${1:-1024}  # in bytes
10243         local file=$DIR/$tfile
10244         local value="$(generate_string $xsize)"
10245         local xbig=trusted.big
10246         local toobig=$2
10247
10248         touch $file
10249         log "save $xbig on $file"
10250         if [ -z "$toobig" ]
10251         then
10252                 setfattr -n $xbig -v $value $file ||
10253                         error "saving $xbig on $file failed"
10254         else
10255                 setfattr -n $xbig -v $value $file &&
10256                         error "saving $xbig on $file succeeded"
10257                 return 0
10258         fi
10259
10260         local orig=$(get_xattr_value $xbig $file)
10261         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10262
10263         local xsml=trusted.sml
10264         log "save $xsml on $file"
10265         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10266
10267         local new=$(get_xattr_value $xbig $file)
10268         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10269
10270         log "grow $xsml on $file"
10271         setfattr -n $xsml -v "$value" $file ||
10272                 error "growing $xsml on $file failed"
10273
10274         new=$(get_xattr_value $xbig $file)
10275         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10276         log "$xbig still valid after growing $xsml"
10277
10278         rm -f $file
10279 }
10280
10281 test_102h() { # bug 15777
10282         grow_xattr 1024
10283 }
10284 run_test 102h "grow xattr from inside inode to external block"
10285
10286 test_102ha() {
10287         large_xattr_enabled || skip_env "ea_inode feature disabled"
10288
10289         echo "setting xattr of max xattr size: $(max_xattr_size)"
10290         grow_xattr $(max_xattr_size)
10291
10292         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10293         echo "This should fail:"
10294         grow_xattr $(($(max_xattr_size) + 10)) 1
10295 }
10296 run_test 102ha "grow xattr from inside inode to external inode"
10297
10298 test_102i() { # bug 17038
10299         [ -z "$(which getfattr 2>/dev/null)" ] &&
10300                 skip "could not find getfattr"
10301
10302         touch $DIR/$tfile
10303         ln -s $DIR/$tfile $DIR/${tfile}link
10304         getfattr -n trusted.lov $DIR/$tfile ||
10305                 error "lgetxattr on $DIR/$tfile failed"
10306         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10307                 grep -i "no such attr" ||
10308                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10309         rm -f $DIR/$tfile $DIR/${tfile}link
10310 }
10311 run_test 102i "lgetxattr test on symbolic link ============"
10312
10313 test_102j() {
10314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10315         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10316
10317         XINC=$(have_xattrs_include)
10318         setup_test102 "$RUNAS"
10319         chown $RUNAS_ID $DIR/$tdir
10320         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10321         cd $DIR/$tdir/$tdir
10322         compare_stripe_info1 "$RUNAS"
10323 }
10324 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10325
10326 test_102k() {
10327         [ -z "$(which setfattr 2>/dev/null)" ] &&
10328                 skip "could not find setfattr"
10329
10330         touch $DIR/$tfile
10331         # b22187 just check that does not crash for regular file.
10332         setfattr -n trusted.lov $DIR/$tfile
10333         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10334         local test_kdir=$DIR/$tdir
10335         test_mkdir $test_kdir
10336         local default_size=$($LFS getstripe -S $test_kdir)
10337         local default_count=$($LFS getstripe -c $test_kdir)
10338         local default_offset=$($LFS getstripe -i $test_kdir)
10339         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10340                 error 'dir setstripe failed'
10341         setfattr -n trusted.lov $test_kdir
10342         local stripe_size=$($LFS getstripe -S $test_kdir)
10343         local stripe_count=$($LFS getstripe -c $test_kdir)
10344         local stripe_offset=$($LFS getstripe -i $test_kdir)
10345         [ $stripe_size -eq $default_size ] ||
10346                 error "stripe size $stripe_size != $default_size"
10347         [ $stripe_count -eq $default_count ] ||
10348                 error "stripe count $stripe_count != $default_count"
10349         [ $stripe_offset -eq $default_offset ] ||
10350                 error "stripe offset $stripe_offset != $default_offset"
10351         rm -rf $DIR/$tfile $test_kdir
10352 }
10353 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10354
10355 test_102l() {
10356         [ -z "$(which getfattr 2>/dev/null)" ] &&
10357                 skip "could not find getfattr"
10358
10359         # LU-532 trusted. xattr is invisible to non-root
10360         local testfile=$DIR/$tfile
10361
10362         touch $testfile
10363
10364         echo "listxattr as user..."
10365         chown $RUNAS_ID $testfile
10366         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10367             grep -q "trusted" &&
10368                 error "$testfile trusted xattrs are user visible"
10369
10370         return 0;
10371 }
10372 run_test 102l "listxattr size test =================================="
10373
10374 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10375         local path=$DIR/$tfile
10376         touch $path
10377
10378         listxattr_size_check $path || error "listattr_size_check $path failed"
10379 }
10380 run_test 102m "Ensure listxattr fails on small bufffer ========"
10381
10382 cleanup_test102
10383
10384 getxattr() { # getxattr path name
10385         # Return the base64 encoding of the value of xattr name on path.
10386         local path=$1
10387         local name=$2
10388
10389         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10390         # file: $path
10391         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10392         #
10393         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10394
10395         getfattr --absolute-names --encoding=base64 --name=$name $path |
10396                 awk -F= -v name=$name '$1 == name {
10397                         print substr($0, index($0, "=") + 1);
10398         }'
10399 }
10400
10401 test_102n() { # LU-4101 mdt: protect internal xattrs
10402         [ -z "$(which setfattr 2>/dev/null)" ] &&
10403                 skip "could not find setfattr"
10404         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10405         then
10406                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10407         fi
10408
10409         local file0=$DIR/$tfile.0
10410         local file1=$DIR/$tfile.1
10411         local xattr0=$TMP/$tfile.0
10412         local xattr1=$TMP/$tfile.1
10413         local namelist="lov lma lmv link fid version som hsm"
10414         local name
10415         local value
10416
10417         rm -rf $file0 $file1 $xattr0 $xattr1
10418         touch $file0 $file1
10419
10420         # Get 'before' xattrs of $file1.
10421         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10422
10423         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10424                 namelist+=" lfsck_namespace"
10425         for name in $namelist; do
10426                 # Try to copy xattr from $file0 to $file1.
10427                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10428
10429                 setfattr --name=trusted.$name --value="$value" $file1 ||
10430                         error "setxattr 'trusted.$name' failed"
10431
10432                 # Try to set a garbage xattr.
10433                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10434
10435                 if [[ x$name == "xlov" ]]; then
10436                         setfattr --name=trusted.lov --value="$value" $file1 &&
10437                         error "setxattr invalid 'trusted.lov' success"
10438                 else
10439                         setfattr --name=trusted.$name --value="$value" $file1 ||
10440                                 error "setxattr invalid 'trusted.$name' failed"
10441                 fi
10442
10443                 # Try to remove the xattr from $file1. We don't care if this
10444                 # appears to succeed or fail, we just don't want there to be
10445                 # any changes or crashes.
10446                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10447         done
10448
10449         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10450         then
10451                 name="lfsck_ns"
10452                 # Try to copy xattr from $file0 to $file1.
10453                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10454
10455                 setfattr --name=trusted.$name --value="$value" $file1 ||
10456                         error "setxattr 'trusted.$name' failed"
10457
10458                 # Try to set a garbage xattr.
10459                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10460
10461                 setfattr --name=trusted.$name --value="$value" $file1 ||
10462                         error "setxattr 'trusted.$name' failed"
10463
10464                 # Try to remove the xattr from $file1. We don't care if this
10465                 # appears to succeed or fail, we just don't want there to be
10466                 # any changes or crashes.
10467                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10468         fi
10469
10470         # Get 'after' xattrs of file1.
10471         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10472
10473         if ! diff $xattr0 $xattr1; then
10474                 error "before and after xattrs of '$file1' differ"
10475         fi
10476
10477         rm -rf $file0 $file1 $xattr0 $xattr1
10478
10479         return 0
10480 }
10481 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10482
10483 test_102p() { # LU-4703 setxattr did not check ownership
10484         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10485                 skip "MDS needs to be at least 2.5.56"
10486
10487         local testfile=$DIR/$tfile
10488
10489         touch $testfile
10490
10491         echo "setfacl as user..."
10492         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10493         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10494
10495         echo "setfattr as user..."
10496         setfacl -m "u:$RUNAS_ID:---" $testfile
10497         $RUNAS setfattr -x system.posix_acl_access $testfile
10498         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10499 }
10500 run_test 102p "check setxattr(2) correctly fails without permission"
10501
10502 test_102q() {
10503         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10504                 skip "MDS needs to be at least 2.6.92"
10505
10506         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10507 }
10508 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10509
10510 test_102r() {
10511         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10512                 skip "MDS needs to be at least 2.6.93"
10513
10514         touch $DIR/$tfile || error "touch"
10515         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10516         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10517         rm $DIR/$tfile || error "rm"
10518
10519         #normal directory
10520         mkdir -p $DIR/$tdir || error "mkdir"
10521         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10522         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10523         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10524                 error "$testfile error deleting user.author1"
10525         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10526                 grep "user.$(basename $tdir)" &&
10527                 error "$tdir did not delete user.$(basename $tdir)"
10528         rmdir $DIR/$tdir || error "rmdir"
10529
10530         #striped directory
10531         test_mkdir $DIR/$tdir
10532         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10533         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10534         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10535                 error "$testfile error deleting user.author1"
10536         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10537                 grep "user.$(basename $tdir)" &&
10538                 error "$tdir did not delete user.$(basename $tdir)"
10539         rmdir $DIR/$tdir || error "rm striped dir"
10540 }
10541 run_test 102r "set EAs with empty values"
10542
10543 test_102s() {
10544         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10545                 skip "MDS needs to be at least 2.11.52"
10546
10547         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10548
10549         save_lustre_params client "llite.*.xattr_cache" > $save
10550
10551         for cache in 0 1; do
10552                 lctl set_param llite.*.xattr_cache=$cache
10553
10554                 rm -f $DIR/$tfile
10555                 touch $DIR/$tfile || error "touch"
10556                 for prefix in lustre security system trusted user; do
10557                         # Note getxattr() may fail with 'Operation not
10558                         # supported' or 'No such attribute' depending
10559                         # on prefix and cache.
10560                         getfattr -n $prefix.n102s $DIR/$tfile &&
10561                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10562                 done
10563         done
10564
10565         restore_lustre_params < $save
10566 }
10567 run_test 102s "getting nonexistent xattrs should fail"
10568
10569 test_102t() {
10570         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10571                 skip "MDS needs to be at least 2.11.52"
10572
10573         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10574
10575         save_lustre_params client "llite.*.xattr_cache" > $save
10576
10577         for cache in 0 1; do
10578                 lctl set_param llite.*.xattr_cache=$cache
10579
10580                 for buf_size in 0 256; do
10581                         rm -f $DIR/$tfile
10582                         touch $DIR/$tfile || error "touch"
10583                         setfattr -n user.multiop $DIR/$tfile
10584                         $MULTIOP $DIR/$tfile oa$buf_size ||
10585                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10586                 done
10587         done
10588
10589         restore_lustre_params < $save
10590 }
10591 run_test 102t "zero length xattr values handled correctly"
10592
10593 run_acl_subtest()
10594 {
10595     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10596     return $?
10597 }
10598
10599 test_103a() {
10600         [ "$UID" != 0 ] && skip "must run as root"
10601         $GSS && skip_env "could not run under gss"
10602         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10603                 skip_env "must have acl enabled"
10604         [ -z "$(which setfacl 2>/dev/null)" ] &&
10605                 skip_env "could not find setfacl"
10606         remote_mds_nodsh && skip "remote MDS with nodsh"
10607
10608         gpasswd -a daemon bin                           # LU-5641
10609         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10610
10611         declare -a identity_old
10612
10613         for num in $(seq $MDSCOUNT); do
10614                 switch_identity $num true || identity_old[$num]=$?
10615         done
10616
10617         SAVE_UMASK=$(umask)
10618         umask 0022
10619         mkdir -p $DIR/$tdir
10620         cd $DIR/$tdir
10621
10622         echo "performing cp ..."
10623         run_acl_subtest cp || error "run_acl_subtest cp failed"
10624         echo "performing getfacl-noacl..."
10625         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10626         echo "performing misc..."
10627         run_acl_subtest misc || error  "misc test failed"
10628         echo "performing permissions..."
10629         run_acl_subtest permissions || error "permissions failed"
10630         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10631         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10632                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10633                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10634         then
10635                 echo "performing permissions xattr..."
10636                 run_acl_subtest permissions_xattr ||
10637                         error "permissions_xattr failed"
10638         fi
10639         echo "performing setfacl..."
10640         run_acl_subtest setfacl || error  "setfacl test failed"
10641
10642         # inheritance test got from HP
10643         echo "performing inheritance..."
10644         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10645         chmod +x make-tree || error "chmod +x failed"
10646         run_acl_subtest inheritance || error "inheritance test failed"
10647         rm -f make-tree
10648
10649         echo "LU-974 ignore umask when acl is enabled..."
10650         run_acl_subtest 974 || error "LU-974 umask test failed"
10651         if [ $MDSCOUNT -ge 2 ]; then
10652                 run_acl_subtest 974_remote ||
10653                         error "LU-974 umask test failed under remote dir"
10654         fi
10655
10656         echo "LU-2561 newly created file is same size as directory..."
10657         if [ "$mds1_FSTYPE" != "zfs" ]; then
10658                 run_acl_subtest 2561 || error "LU-2561 test failed"
10659         else
10660                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10661         fi
10662
10663         run_acl_subtest 4924 || error "LU-4924 test failed"
10664
10665         cd $SAVE_PWD
10666         umask $SAVE_UMASK
10667
10668         for num in $(seq $MDSCOUNT); do
10669                 if [ "${identity_old[$num]}" = 1 ]; then
10670                         switch_identity $num false || identity_old[$num]=$?
10671                 fi
10672         done
10673 }
10674 run_test 103a "acl test"
10675
10676 test_103b() {
10677         declare -a pids
10678         local U
10679
10680         for U in {0..511}; do
10681                 {
10682                 local O=$(printf "%04o" $U)
10683
10684                 umask $(printf "%04o" $((511 ^ $O)))
10685                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10686                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10687
10688                 (( $S == ($O & 0666) )) ||
10689                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10690
10691                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10692                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10693                 (( $S == ($O & 0666) )) ||
10694                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10695
10696                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10697                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10698                 (( $S == ($O & 0666) )) ||
10699                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10700                 rm -f $DIR/$tfile.[smp]$0
10701                 } &
10702                 local pid=$!
10703
10704                 # limit the concurrently running threads to 64. LU-11878
10705                 local idx=$((U % 64))
10706                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10707                 pids[idx]=$pid
10708         done
10709         wait
10710 }
10711 run_test 103b "umask lfs setstripe"
10712
10713 test_103c() {
10714         mkdir -p $DIR/$tdir
10715         cp -rp $DIR/$tdir $DIR/$tdir.bak
10716
10717         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10718                 error "$DIR/$tdir shouldn't contain default ACL"
10719         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10720                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10721         true
10722 }
10723 run_test 103c "'cp -rp' won't set empty acl"
10724
10725 test_103e() {
10726         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10727                 skip "MDS needs to be at least 2.13.59"
10728
10729         mkdir -p $DIR/$tdir
10730         # one default ACL will be created for the file owner
10731         for U in {2..256}; do
10732                 setfacl -m default:user:$U:rwx $DIR/$tdir
10733                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10734                 touch $DIR/$tdir/$tfile.$U ||
10735                         error "failed to create $tfile.$U with $numacl ACLs"
10736         done
10737 }
10738 run_test 103e "inheritance of big amount of default ACLs"
10739
10740 test_104a() {
10741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10742
10743         touch $DIR/$tfile
10744         lfs df || error "lfs df failed"
10745         lfs df -ih || error "lfs df -ih failed"
10746         lfs df -h $DIR || error "lfs df -h $DIR failed"
10747         lfs df -i $DIR || error "lfs df -i $DIR failed"
10748         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10749         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10750
10751         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10752         lctl --device %$OSC deactivate
10753         lfs df || error "lfs df with deactivated OSC failed"
10754         lctl --device %$OSC activate
10755         # wait the osc back to normal
10756         wait_osc_import_ready client ost
10757
10758         lfs df || error "lfs df with reactivated OSC failed"
10759         rm -f $DIR/$tfile
10760 }
10761 run_test 104a "lfs df [-ih] [path] test ========================="
10762
10763 test_104b() {
10764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10765         [ $RUNAS_ID -eq $UID ] &&
10766                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10767
10768         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10769                         grep "Permission denied" | wc -l)))
10770         if [ $denied_cnt -ne 0 ]; then
10771                 error "lfs check servers test failed"
10772         fi
10773 }
10774 run_test 104b "$RUNAS lfs check servers test ===================="
10775
10776 test_105a() {
10777         # doesn't work on 2.4 kernels
10778         touch $DIR/$tfile
10779         if $(flock_is_enabled); then
10780                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10781         else
10782                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10783         fi
10784         rm -f $DIR/$tfile
10785 }
10786 run_test 105a "flock when mounted without -o flock test ========"
10787
10788 test_105b() {
10789         touch $DIR/$tfile
10790         if $(flock_is_enabled); then
10791                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10792         else
10793                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10794         fi
10795         rm -f $DIR/$tfile
10796 }
10797 run_test 105b "fcntl when mounted without -o flock test ========"
10798
10799 test_105c() {
10800         touch $DIR/$tfile
10801         if $(flock_is_enabled); then
10802                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10803         else
10804                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10805         fi
10806         rm -f $DIR/$tfile
10807 }
10808 run_test 105c "lockf when mounted without -o flock test"
10809
10810 test_105d() { # bug 15924
10811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10812
10813         test_mkdir $DIR/$tdir
10814         flock_is_enabled || skip_env "mount w/o flock enabled"
10815         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10816         $LCTL set_param fail_loc=0x80000315
10817         flocks_test 2 $DIR/$tdir
10818 }
10819 run_test 105d "flock race (should not freeze) ========"
10820
10821 test_105e() { # bug 22660 && 22040
10822         flock_is_enabled || skip_env "mount w/o flock enabled"
10823
10824         touch $DIR/$tfile
10825         flocks_test 3 $DIR/$tfile
10826 }
10827 run_test 105e "Two conflicting flocks from same process"
10828
10829 test_106() { #bug 10921
10830         test_mkdir $DIR/$tdir
10831         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10832         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10833 }
10834 run_test 106 "attempt exec of dir followed by chown of that dir"
10835
10836 test_107() {
10837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10838
10839         CDIR=`pwd`
10840         local file=core
10841
10842         cd $DIR
10843         rm -f $file
10844
10845         local save_pattern=$(sysctl -n kernel.core_pattern)
10846         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10847         sysctl -w kernel.core_pattern=$file
10848         sysctl -w kernel.core_uses_pid=0
10849
10850         ulimit -c unlimited
10851         sleep 60 &
10852         SLEEPPID=$!
10853
10854         sleep 1
10855
10856         kill -s 11 $SLEEPPID
10857         wait $SLEEPPID
10858         if [ -e $file ]; then
10859                 size=`stat -c%s $file`
10860                 [ $size -eq 0 ] && error "Fail to create core file $file"
10861         else
10862                 error "Fail to create core file $file"
10863         fi
10864         rm -f $file
10865         sysctl -w kernel.core_pattern=$save_pattern
10866         sysctl -w kernel.core_uses_pid=$save_uses_pid
10867         cd $CDIR
10868 }
10869 run_test 107 "Coredump on SIG"
10870
10871 test_110() {
10872         test_mkdir $DIR/$tdir
10873         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10874         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10875                 error "mkdir with 256 char should fail, but did not"
10876         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10877                 error "create with 255 char failed"
10878         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10879                 error "create with 256 char should fail, but did not"
10880
10881         ls -l $DIR/$tdir
10882         rm -rf $DIR/$tdir
10883 }
10884 run_test 110 "filename length checking"
10885
10886 #
10887 # Purpose: To verify dynamic thread (OSS) creation.
10888 #
10889 test_115() {
10890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10891         remote_ost_nodsh && skip "remote OST with nodsh"
10892
10893         # Lustre does not stop service threads once they are started.
10894         # Reset number of running threads to default.
10895         stopall
10896         setupall
10897
10898         local OSTIO_pre
10899         local save_params="$TMP/sanity-$TESTNAME.parameters"
10900
10901         # Get ll_ost_io count before I/O
10902         OSTIO_pre=$(do_facet ost1 \
10903                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10904         # Exit if lustre is not running (ll_ost_io not running).
10905         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10906
10907         echo "Starting with $OSTIO_pre threads"
10908         local thread_max=$((OSTIO_pre * 2))
10909         local rpc_in_flight=$((thread_max * 2))
10910         # Number of I/O Process proposed to be started.
10911         local nfiles
10912         local facets=$(get_facets OST)
10913
10914         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10915         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10916
10917         # Set in_flight to $rpc_in_flight
10918         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10919                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10920         nfiles=${rpc_in_flight}
10921         # Set ost thread_max to $thread_max
10922         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10923
10924         # 5 Minutes should be sufficient for max number of OSS
10925         # threads(thread_max) to be created.
10926         local timeout=300
10927
10928         # Start I/O.
10929         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10930         test_mkdir $DIR/$tdir
10931         for i in $(seq $nfiles); do
10932                 local file=$DIR/$tdir/${tfile}-$i
10933                 $LFS setstripe -c -1 -i 0 $file
10934                 ($WTL $file $timeout)&
10935         done
10936
10937         # I/O Started - Wait for thread_started to reach thread_max or report
10938         # error if thread_started is more than thread_max.
10939         echo "Waiting for thread_started to reach thread_max"
10940         local thread_started=0
10941         local end_time=$((SECONDS + timeout))
10942
10943         while [ $SECONDS -le $end_time ] ; do
10944                 echo -n "."
10945                 # Get ost i/o thread_started count.
10946                 thread_started=$(do_facet ost1 \
10947                         "$LCTL get_param \
10948                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10949                 # Break out if thread_started is equal/greater than thread_max
10950                 if [[ $thread_started -ge $thread_max ]]; then
10951                         echo ll_ost_io thread_started $thread_started, \
10952                                 equal/greater than thread_max $thread_max
10953                         break
10954                 fi
10955                 sleep 1
10956         done
10957
10958         # Cleanup - We have the numbers, Kill i/o jobs if running.
10959         jobcount=($(jobs -p))
10960         for i in $(seq 0 $((${#jobcount[@]}-1)))
10961         do
10962                 kill -9 ${jobcount[$i]}
10963                 if [ $? -ne 0 ] ; then
10964                         echo Warning: \
10965                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10966                 fi
10967         done
10968
10969         # Cleanup files left by WTL binary.
10970         for i in $(seq $nfiles); do
10971                 local file=$DIR/$tdir/${tfile}-$i
10972                 rm -rf $file
10973                 if [ $? -ne 0 ] ; then
10974                         echo "Warning: Failed to delete file $file"
10975                 fi
10976         done
10977
10978         restore_lustre_params <$save_params
10979         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10980
10981         # Error out if no new thread has started or Thread started is greater
10982         # than thread max.
10983         if [[ $thread_started -le $OSTIO_pre ||
10984                         $thread_started -gt $thread_max ]]; then
10985                 error "ll_ost_io: thread_started $thread_started" \
10986                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10987                       "No new thread started or thread started greater " \
10988                       "than thread_max."
10989         fi
10990 }
10991 run_test 115 "verify dynamic thread creation===================="
10992
10993 free_min_max () {
10994         wait_delete_completed
10995         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10996         echo "OST kbytes available: ${AVAIL[@]}"
10997         MAXV=${AVAIL[0]}
10998         MAXI=0
10999         MINV=${AVAIL[0]}
11000         MINI=0
11001         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11002                 #echo OST $i: ${AVAIL[i]}kb
11003                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11004                         MAXV=${AVAIL[i]}
11005                         MAXI=$i
11006                 fi
11007                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11008                         MINV=${AVAIL[i]}
11009                         MINI=$i
11010                 fi
11011         done
11012         echo "Min free space: OST $MINI: $MINV"
11013         echo "Max free space: OST $MAXI: $MAXV"
11014 }
11015
11016 test_116a() { # was previously test_116()
11017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11019         remote_mds_nodsh && skip "remote MDS with nodsh"
11020
11021         echo -n "Free space priority "
11022         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11023                 head -n1
11024         declare -a AVAIL
11025         free_min_max
11026
11027         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11028         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11029         trap simple_cleanup_common EXIT
11030
11031         # Check if we need to generate uneven OSTs
11032         test_mkdir -p $DIR/$tdir/OST${MINI}
11033         local FILL=$((MINV / 4))
11034         local DIFF=$((MAXV - MINV))
11035         local DIFF2=$((DIFF * 100 / MINV))
11036
11037         local threshold=$(do_facet $SINGLEMDS \
11038                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11039         threshold=${threshold%%%}
11040         echo -n "Check for uneven OSTs: "
11041         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11042
11043         if [[ $DIFF2 -gt $threshold ]]; then
11044                 echo "ok"
11045                 echo "Don't need to fill OST$MINI"
11046         else
11047                 # generate uneven OSTs. Write 2% over the QOS threshold value
11048                 echo "no"
11049                 DIFF=$((threshold - DIFF2 + 2))
11050                 DIFF2=$((MINV * DIFF / 100))
11051                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11052                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11053                         error "setstripe failed"
11054                 DIFF=$((DIFF2 / 2048))
11055                 i=0
11056                 while [ $i -lt $DIFF ]; do
11057                         i=$((i + 1))
11058                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11059                                 bs=2M count=1 2>/dev/null
11060                         echo -n .
11061                 done
11062                 echo .
11063                 sync
11064                 sleep_maxage
11065                 free_min_max
11066         fi
11067
11068         DIFF=$((MAXV - MINV))
11069         DIFF2=$((DIFF * 100 / MINV))
11070         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11071         if [ $DIFF2 -gt $threshold ]; then
11072                 echo "ok"
11073         else
11074                 echo "failed - QOS mode won't be used"
11075                 simple_cleanup_common
11076                 skip "QOS imbalance criteria not met"
11077         fi
11078
11079         MINI1=$MINI
11080         MINV1=$MINV
11081         MAXI1=$MAXI
11082         MAXV1=$MAXV
11083
11084         # now fill using QOS
11085         $LFS setstripe -c 1 $DIR/$tdir
11086         FILL=$((FILL / 200))
11087         if [ $FILL -gt 600 ]; then
11088                 FILL=600
11089         fi
11090         echo "writing $FILL files to QOS-assigned OSTs"
11091         i=0
11092         while [ $i -lt $FILL ]; do
11093                 i=$((i + 1))
11094                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11095                         count=1 2>/dev/null
11096                 echo -n .
11097         done
11098         echo "wrote $i 200k files"
11099         sync
11100         sleep_maxage
11101
11102         echo "Note: free space may not be updated, so measurements might be off"
11103         free_min_max
11104         DIFF2=$((MAXV - MINV))
11105         echo "free space delta: orig $DIFF final $DIFF2"
11106         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11107         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11108         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11109         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11110         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11111         if [[ $DIFF -gt 0 ]]; then
11112                 FILL=$((DIFF2 * 100 / DIFF - 100))
11113                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11114         fi
11115
11116         # Figure out which files were written where
11117         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11118                awk '/'$MINI1': / {print $2; exit}')
11119         echo $UUID
11120         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11121         echo "$MINC files created on smaller OST $MINI1"
11122         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11123                awk '/'$MAXI1': / {print $2; exit}')
11124         echo $UUID
11125         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11126         echo "$MAXC files created on larger OST $MAXI1"
11127         if [[ $MINC -gt 0 ]]; then
11128                 FILL=$((MAXC * 100 / MINC - 100))
11129                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11130         fi
11131         [[ $MAXC -gt $MINC ]] ||
11132                 error_ignore LU-9 "stripe QOS didn't balance free space"
11133         simple_cleanup_common
11134 }
11135 run_test 116a "stripe QOS: free space balance ==================="
11136
11137 test_116b() { # LU-2093
11138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11139         remote_mds_nodsh && skip "remote MDS with nodsh"
11140
11141 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11142         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11143                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11144         [ -z "$old_rr" ] && skip "no QOS"
11145         do_facet $SINGLEMDS lctl set_param \
11146                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11147         mkdir -p $DIR/$tdir
11148         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11149         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11150         do_facet $SINGLEMDS lctl set_param fail_loc=0
11151         rm -rf $DIR/$tdir
11152         do_facet $SINGLEMDS lctl set_param \
11153                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11154 }
11155 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11156
11157 test_117() # bug 10891
11158 {
11159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11160
11161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11162         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11163         lctl set_param fail_loc=0x21e
11164         > $DIR/$tfile || error "truncate failed"
11165         lctl set_param fail_loc=0
11166         echo "Truncate succeeded."
11167         rm -f $DIR/$tfile
11168 }
11169 run_test 117 "verify osd extend =========="
11170
11171 NO_SLOW_RESENDCOUNT=4
11172 export OLD_RESENDCOUNT=""
11173 set_resend_count () {
11174         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11175         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11176         lctl set_param -n $PROC_RESENDCOUNT $1
11177         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11178 }
11179
11180 # for reduce test_118* time (b=14842)
11181 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11182
11183 # Reset async IO behavior after error case
11184 reset_async() {
11185         FILE=$DIR/reset_async
11186
11187         # Ensure all OSCs are cleared
11188         $LFS setstripe -c -1 $FILE
11189         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11190         sync
11191         rm $FILE
11192 }
11193
11194 test_118a() #bug 11710
11195 {
11196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11197
11198         reset_async
11199
11200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11201         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11202         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11203
11204         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11205                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11206                 return 1;
11207         fi
11208         rm -f $DIR/$tfile
11209 }
11210 run_test 118a "verify O_SYNC works =========="
11211
11212 test_118b()
11213 {
11214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11215         remote_ost_nodsh && skip "remote OST with nodsh"
11216
11217         reset_async
11218
11219         #define OBD_FAIL_SRV_ENOENT 0x217
11220         set_nodes_failloc "$(osts_nodes)" 0x217
11221         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11222         RC=$?
11223         set_nodes_failloc "$(osts_nodes)" 0
11224         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11225         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11226                     grep -c writeback)
11227
11228         if [[ $RC -eq 0 ]]; then
11229                 error "Must return error due to dropped pages, rc=$RC"
11230                 return 1;
11231         fi
11232
11233         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11234                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11235                 return 1;
11236         fi
11237
11238         echo "Dirty pages not leaked on ENOENT"
11239
11240         # Due to the above error the OSC will issue all RPCs syncronously
11241         # until a subsequent RPC completes successfully without error.
11242         $MULTIOP $DIR/$tfile Ow4096yc
11243         rm -f $DIR/$tfile
11244
11245         return 0
11246 }
11247 run_test 118b "Reclaim dirty pages on fatal error =========="
11248
11249 test_118c()
11250 {
11251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11252
11253         # for 118c, restore the original resend count, LU-1940
11254         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11255                                 set_resend_count $OLD_RESENDCOUNT
11256         remote_ost_nodsh && skip "remote OST with nodsh"
11257
11258         reset_async
11259
11260         #define OBD_FAIL_OST_EROFS               0x216
11261         set_nodes_failloc "$(osts_nodes)" 0x216
11262
11263         # multiop should block due to fsync until pages are written
11264         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11265         MULTIPID=$!
11266         sleep 1
11267
11268         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11269                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11270         fi
11271
11272         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11273                     grep -c writeback)
11274         if [[ $WRITEBACK -eq 0 ]]; then
11275                 error "No page in writeback, writeback=$WRITEBACK"
11276         fi
11277
11278         set_nodes_failloc "$(osts_nodes)" 0
11279         wait $MULTIPID
11280         RC=$?
11281         if [[ $RC -ne 0 ]]; then
11282                 error "Multiop fsync failed, rc=$RC"
11283         fi
11284
11285         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11286         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11287                     grep -c writeback)
11288         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11289                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11290         fi
11291
11292         rm -f $DIR/$tfile
11293         echo "Dirty pages flushed via fsync on EROFS"
11294         return 0
11295 }
11296 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11297
11298 # continue to use small resend count to reduce test_118* time (b=14842)
11299 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11300
11301 test_118d()
11302 {
11303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11304         remote_ost_nodsh && skip "remote OST with nodsh"
11305
11306         reset_async
11307
11308         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11309         set_nodes_failloc "$(osts_nodes)" 0x214
11310         # multiop should block due to fsync until pages are written
11311         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11312         MULTIPID=$!
11313         sleep 1
11314
11315         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11316                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11317         fi
11318
11319         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11320                     grep -c writeback)
11321         if [[ $WRITEBACK -eq 0 ]]; then
11322                 error "No page in writeback, writeback=$WRITEBACK"
11323         fi
11324
11325         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11326         set_nodes_failloc "$(osts_nodes)" 0
11327
11328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11330                     grep -c writeback)
11331         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11332                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11333         fi
11334
11335         rm -f $DIR/$tfile
11336         echo "Dirty pages gaurenteed flushed via fsync"
11337         return 0
11338 }
11339 run_test 118d "Fsync validation inject a delay of the bulk =========="
11340
11341 test_118f() {
11342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11343
11344         reset_async
11345
11346         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11347         lctl set_param fail_loc=0x8000040a
11348
11349         # Should simulate EINVAL error which is fatal
11350         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11351         RC=$?
11352         if [[ $RC -eq 0 ]]; then
11353                 error "Must return error due to dropped pages, rc=$RC"
11354         fi
11355
11356         lctl set_param fail_loc=0x0
11357
11358         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11359         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11360         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11361                     grep -c writeback)
11362         if [[ $LOCKED -ne 0 ]]; then
11363                 error "Locked pages remain in cache, locked=$LOCKED"
11364         fi
11365
11366         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11367                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11368         fi
11369
11370         rm -f $DIR/$tfile
11371         echo "No pages locked after fsync"
11372
11373         reset_async
11374         return 0
11375 }
11376 run_test 118f "Simulate unrecoverable OSC side error =========="
11377
11378 test_118g() {
11379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11380
11381         reset_async
11382
11383         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11384         lctl set_param fail_loc=0x406
11385
11386         # simulate local -ENOMEM
11387         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11388         RC=$?
11389
11390         lctl set_param fail_loc=0
11391         if [[ $RC -eq 0 ]]; then
11392                 error "Must return error due to dropped pages, rc=$RC"
11393         fi
11394
11395         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11396         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11397         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11398                         grep -c writeback)
11399         if [[ $LOCKED -ne 0 ]]; then
11400                 error "Locked pages remain in cache, locked=$LOCKED"
11401         fi
11402
11403         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11404                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11405         fi
11406
11407         rm -f $DIR/$tfile
11408         echo "No pages locked after fsync"
11409
11410         reset_async
11411         return 0
11412 }
11413 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11414
11415 test_118h() {
11416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11417         remote_ost_nodsh && skip "remote OST with nodsh"
11418
11419         reset_async
11420
11421         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11422         set_nodes_failloc "$(osts_nodes)" 0x20e
11423         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11424         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11425         RC=$?
11426
11427         set_nodes_failloc "$(osts_nodes)" 0
11428         if [[ $RC -eq 0 ]]; then
11429                 error "Must return error due to dropped pages, rc=$RC"
11430         fi
11431
11432         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11433         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11434         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11435                     grep -c writeback)
11436         if [[ $LOCKED -ne 0 ]]; then
11437                 error "Locked pages remain in cache, locked=$LOCKED"
11438         fi
11439
11440         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11441                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11442         fi
11443
11444         rm -f $DIR/$tfile
11445         echo "No pages locked after fsync"
11446
11447         return 0
11448 }
11449 run_test 118h "Verify timeout in handling recoverables errors  =========="
11450
11451 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11452
11453 test_118i() {
11454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11455         remote_ost_nodsh && skip "remote OST with nodsh"
11456
11457         reset_async
11458
11459         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11460         set_nodes_failloc "$(osts_nodes)" 0x20e
11461
11462         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11463         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11464         PID=$!
11465         sleep 5
11466         set_nodes_failloc "$(osts_nodes)" 0
11467
11468         wait $PID
11469         RC=$?
11470         if [[ $RC -ne 0 ]]; then
11471                 error "got error, but should be not, rc=$RC"
11472         fi
11473
11474         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11475         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11476         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11477         if [[ $LOCKED -ne 0 ]]; then
11478                 error "Locked pages remain in cache, locked=$LOCKED"
11479         fi
11480
11481         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11482                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11483         fi
11484
11485         rm -f $DIR/$tfile
11486         echo "No pages locked after fsync"
11487
11488         return 0
11489 }
11490 run_test 118i "Fix error before timeout in recoverable error  =========="
11491
11492 [ "$SLOW" = "no" ] && set_resend_count 4
11493
11494 test_118j() {
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496         remote_ost_nodsh && skip "remote OST with nodsh"
11497
11498         reset_async
11499
11500         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11501         set_nodes_failloc "$(osts_nodes)" 0x220
11502
11503         # return -EIO from OST
11504         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11505         RC=$?
11506         set_nodes_failloc "$(osts_nodes)" 0x0
11507         if [[ $RC -eq 0 ]]; then
11508                 error "Must return error due to dropped pages, rc=$RC"
11509         fi
11510
11511         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11512         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11513         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11514         if [[ $LOCKED -ne 0 ]]; then
11515                 error "Locked pages remain in cache, locked=$LOCKED"
11516         fi
11517
11518         # in recoverable error on OST we want resend and stay until it finished
11519         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11520                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11521         fi
11522
11523         rm -f $DIR/$tfile
11524         echo "No pages locked after fsync"
11525
11526         return 0
11527 }
11528 run_test 118j "Simulate unrecoverable OST side error =========="
11529
11530 test_118k()
11531 {
11532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11533         remote_ost_nodsh && skip "remote OSTs with nodsh"
11534
11535         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11536         set_nodes_failloc "$(osts_nodes)" 0x20e
11537         test_mkdir $DIR/$tdir
11538
11539         for ((i=0;i<10;i++)); do
11540                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11541                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11542                 SLEEPPID=$!
11543                 sleep 0.500s
11544                 kill $SLEEPPID
11545                 wait $SLEEPPID
11546         done
11547
11548         set_nodes_failloc "$(osts_nodes)" 0
11549         rm -rf $DIR/$tdir
11550 }
11551 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11552
11553 test_118l() # LU-646
11554 {
11555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11556
11557         test_mkdir $DIR/$tdir
11558         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11559         rm -rf $DIR/$tdir
11560 }
11561 run_test 118l "fsync dir"
11562
11563 test_118m() # LU-3066
11564 {
11565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11566
11567         test_mkdir $DIR/$tdir
11568         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11569         rm -rf $DIR/$tdir
11570 }
11571 run_test 118m "fdatasync dir ========="
11572
11573 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11574
11575 test_118n()
11576 {
11577         local begin
11578         local end
11579
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         remote_ost_nodsh && skip "remote OSTs with nodsh"
11582
11583         # Sleep to avoid a cached response.
11584         #define OBD_STATFS_CACHE_SECONDS 1
11585         sleep 2
11586
11587         # Inject a 10 second delay in the OST_STATFS handler.
11588         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11589         set_nodes_failloc "$(osts_nodes)" 0x242
11590
11591         begin=$SECONDS
11592         stat --file-system $MOUNT > /dev/null
11593         end=$SECONDS
11594
11595         set_nodes_failloc "$(osts_nodes)" 0
11596
11597         if ((end - begin > 20)); then
11598             error "statfs took $((end - begin)) seconds, expected 10"
11599         fi
11600 }
11601 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11602
11603 test_119a() # bug 11737
11604 {
11605         BSIZE=$((512 * 1024))
11606         directio write $DIR/$tfile 0 1 $BSIZE
11607         # We ask to read two blocks, which is more than a file size.
11608         # directio will indicate an error when requested and actual
11609         # sizes aren't equeal (a normal situation in this case) and
11610         # print actual read amount.
11611         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11612         if [ "$NOB" != "$BSIZE" ]; then
11613                 error "read $NOB bytes instead of $BSIZE"
11614         fi
11615         rm -f $DIR/$tfile
11616 }
11617 run_test 119a "Short directIO read must return actual read amount"
11618
11619 test_119b() # bug 11737
11620 {
11621         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11622
11623         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11625         sync
11626         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11627                 error "direct read failed"
11628         rm -f $DIR/$tfile
11629 }
11630 run_test 119b "Sparse directIO read must return actual read amount"
11631
11632 test_119c() # bug 13099
11633 {
11634         BSIZE=1048576
11635         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11636         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11637         rm -f $DIR/$tfile
11638 }
11639 run_test 119c "Testing for direct read hitting hole"
11640
11641 test_119d() # bug 15950
11642 {
11643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11644
11645         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11646         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11647         BSIZE=1048576
11648         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11649         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11650         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11651         lctl set_param fail_loc=0x40d
11652         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11653         pid_dio=$!
11654         sleep 1
11655         cat $DIR/$tfile > /dev/null &
11656         lctl set_param fail_loc=0
11657         pid_reads=$!
11658         wait $pid_dio
11659         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11660         sleep 2
11661         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11662         error "the read rpcs have not completed in 2s"
11663         rm -f $DIR/$tfile
11664         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11665 }
11666 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11667
11668 test_120a() {
11669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11670         remote_mds_nodsh && skip "remote MDS with nodsh"
11671         test_mkdir -i0 -c1 $DIR/$tdir
11672         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11673                 skip_env "no early lock cancel on server"
11674
11675         lru_resize_disable mdc
11676         lru_resize_disable osc
11677         cancel_lru_locks mdc
11678         # asynchronous object destroy at MDT could cause bl ast to client
11679         cancel_lru_locks osc
11680
11681         stat $DIR/$tdir > /dev/null
11682         can1=$(do_facet mds1 \
11683                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11684                awk '/ldlm_cancel/ {print $2}')
11685         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11686                awk '/ldlm_bl_callback/ {print $2}')
11687         test_mkdir -i0 -c1 $DIR/$tdir/d1
11688         can2=$(do_facet mds1 \
11689                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11690                awk '/ldlm_cancel/ {print $2}')
11691         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11692                awk '/ldlm_bl_callback/ {print $2}')
11693         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11694         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11695         lru_resize_enable mdc
11696         lru_resize_enable osc
11697 }
11698 run_test 120a "Early Lock Cancel: mkdir test"
11699
11700 test_120b() {
11701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11702         remote_mds_nodsh && skip "remote MDS with nodsh"
11703         test_mkdir $DIR/$tdir
11704         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11705                 skip_env "no early lock cancel on server"
11706
11707         lru_resize_disable mdc
11708         lru_resize_disable osc
11709         cancel_lru_locks mdc
11710         stat $DIR/$tdir > /dev/null
11711         can1=$(do_facet $SINGLEMDS \
11712                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11713                awk '/ldlm_cancel/ {print $2}')
11714         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11715                awk '/ldlm_bl_callback/ {print $2}')
11716         touch $DIR/$tdir/f1
11717         can2=$(do_facet $SINGLEMDS \
11718                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11719                awk '/ldlm_cancel/ {print $2}')
11720         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11721                awk '/ldlm_bl_callback/ {print $2}')
11722         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11723         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11724         lru_resize_enable mdc
11725         lru_resize_enable osc
11726 }
11727 run_test 120b "Early Lock Cancel: create test"
11728
11729 test_120c() {
11730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11731         remote_mds_nodsh && skip "remote MDS with nodsh"
11732         test_mkdir -i0 -c1 $DIR/$tdir
11733         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11734                 skip "no early lock cancel on server"
11735
11736         lru_resize_disable mdc
11737         lru_resize_disable osc
11738         test_mkdir -i0 -c1 $DIR/$tdir/d1
11739         test_mkdir -i0 -c1 $DIR/$tdir/d2
11740         touch $DIR/$tdir/d1/f1
11741         cancel_lru_locks mdc
11742         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11743         can1=$(do_facet mds1 \
11744                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11745                awk '/ldlm_cancel/ {print $2}')
11746         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11747                awk '/ldlm_bl_callback/ {print $2}')
11748         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11749         can2=$(do_facet mds1 \
11750                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11751                awk '/ldlm_cancel/ {print $2}')
11752         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11753                awk '/ldlm_bl_callback/ {print $2}')
11754         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11755         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11756         lru_resize_enable mdc
11757         lru_resize_enable osc
11758 }
11759 run_test 120c "Early Lock Cancel: link test"
11760
11761 test_120d() {
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763         remote_mds_nodsh && skip "remote MDS with nodsh"
11764         test_mkdir -i0 -c1 $DIR/$tdir
11765         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11766                 skip_env "no early lock cancel on server"
11767
11768         lru_resize_disable mdc
11769         lru_resize_disable osc
11770         touch $DIR/$tdir
11771         cancel_lru_locks mdc
11772         stat $DIR/$tdir > /dev/null
11773         can1=$(do_facet mds1 \
11774                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11775                awk '/ldlm_cancel/ {print $2}')
11776         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11777                awk '/ldlm_bl_callback/ {print $2}')
11778         chmod a+x $DIR/$tdir
11779         can2=$(do_facet mds1 \
11780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11781                awk '/ldlm_cancel/ {print $2}')
11782         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11783                awk '/ldlm_bl_callback/ {print $2}')
11784         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11785         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11786         lru_resize_enable mdc
11787         lru_resize_enable osc
11788 }
11789 run_test 120d "Early Lock Cancel: setattr test"
11790
11791 test_120e() {
11792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11793         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11794                 skip_env "no early lock cancel on server"
11795         remote_mds_nodsh && skip "remote MDS with nodsh"
11796
11797         local dlmtrace_set=false
11798
11799         test_mkdir -i0 -c1 $DIR/$tdir
11800         lru_resize_disable mdc
11801         lru_resize_disable osc
11802         ! $LCTL get_param debug | grep -q dlmtrace &&
11803                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11804         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11805         cancel_lru_locks mdc
11806         cancel_lru_locks osc
11807         dd if=$DIR/$tdir/f1 of=/dev/null
11808         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11809         # XXX client can not do early lock cancel of OST lock
11810         # during unlink (LU-4206), so cancel osc lock now.
11811         sleep 2
11812         cancel_lru_locks osc
11813         can1=$(do_facet mds1 \
11814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11815                awk '/ldlm_cancel/ {print $2}')
11816         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11817                awk '/ldlm_bl_callback/ {print $2}')
11818         unlink $DIR/$tdir/f1
11819         sleep 5
11820         can2=$(do_facet mds1 \
11821                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11822                awk '/ldlm_cancel/ {print $2}')
11823         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11824                awk '/ldlm_bl_callback/ {print $2}')
11825         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11826                 $LCTL dk $TMP/cancel.debug.txt
11827         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11828                 $LCTL dk $TMP/blocking.debug.txt
11829         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11830         lru_resize_enable mdc
11831         lru_resize_enable osc
11832 }
11833 run_test 120e "Early Lock Cancel: unlink test"
11834
11835 test_120f() {
11836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11837         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11838                 skip_env "no early lock cancel on server"
11839         remote_mds_nodsh && skip "remote MDS with nodsh"
11840
11841         test_mkdir -i0 -c1 $DIR/$tdir
11842         lru_resize_disable mdc
11843         lru_resize_disable osc
11844         test_mkdir -i0 -c1 $DIR/$tdir/d1
11845         test_mkdir -i0 -c1 $DIR/$tdir/d2
11846         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11847         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11848         cancel_lru_locks mdc
11849         cancel_lru_locks osc
11850         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11851         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11852         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11853         # XXX client can not do early lock cancel of OST lock
11854         # during rename (LU-4206), so cancel osc lock now.
11855         sleep 2
11856         cancel_lru_locks osc
11857         can1=$(do_facet mds1 \
11858                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11859                awk '/ldlm_cancel/ {print $2}')
11860         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11861                awk '/ldlm_bl_callback/ {print $2}')
11862         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11863         sleep 5
11864         can2=$(do_facet mds1 \
11865                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11866                awk '/ldlm_cancel/ {print $2}')
11867         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11868                awk '/ldlm_bl_callback/ {print $2}')
11869         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11870         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11871         lru_resize_enable mdc
11872         lru_resize_enable osc
11873 }
11874 run_test 120f "Early Lock Cancel: rename test"
11875
11876 test_120g() {
11877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11878         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11879                 skip_env "no early lock cancel on server"
11880         remote_mds_nodsh && skip "remote MDS with nodsh"
11881
11882         lru_resize_disable mdc
11883         lru_resize_disable osc
11884         count=10000
11885         echo create $count files
11886         test_mkdir $DIR/$tdir
11887         cancel_lru_locks mdc
11888         cancel_lru_locks osc
11889         t0=$(date +%s)
11890
11891         can0=$(do_facet $SINGLEMDS \
11892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11893                awk '/ldlm_cancel/ {print $2}')
11894         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11895                awk '/ldlm_bl_callback/ {print $2}')
11896         createmany -o $DIR/$tdir/f $count
11897         sync
11898         can1=$(do_facet $SINGLEMDS \
11899                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11900                awk '/ldlm_cancel/ {print $2}')
11901         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11902                awk '/ldlm_bl_callback/ {print $2}')
11903         t1=$(date +%s)
11904         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11905         echo rm $count files
11906         rm -r $DIR/$tdir
11907         sync
11908         can2=$(do_facet $SINGLEMDS \
11909                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11910                awk '/ldlm_cancel/ {print $2}')
11911         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11912                awk '/ldlm_bl_callback/ {print $2}')
11913         t2=$(date +%s)
11914         echo total: $count removes in $((t2-t1))
11915         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11916         sleep 2
11917         # wait for commitment of removal
11918         lru_resize_enable mdc
11919         lru_resize_enable osc
11920 }
11921 run_test 120g "Early Lock Cancel: performance test"
11922
11923 test_121() { #bug #10589
11924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11925
11926         rm -rf $DIR/$tfile
11927         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11928 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11929         lctl set_param fail_loc=0x310
11930         cancel_lru_locks osc > /dev/null
11931         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11932         lctl set_param fail_loc=0
11933         [[ $reads -eq $writes ]] ||
11934                 error "read $reads blocks, must be $writes blocks"
11935 }
11936 run_test 121 "read cancel race ========="
11937
11938 test_123a_base() { # was test 123, statahead(bug 11401)
11939         local lsx="$1"
11940
11941         SLOWOK=0
11942         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11943                 log "testing UP system. Performance may be lower than expected."
11944                 SLOWOK=1
11945         fi
11946
11947         rm -rf $DIR/$tdir
11948         test_mkdir $DIR/$tdir
11949         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11950         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11951         MULT=10
11952         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11953                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11954
11955                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11956                 lctl set_param -n llite.*.statahead_max 0
11957                 lctl get_param llite.*.statahead_max
11958                 cancel_lru_locks mdc
11959                 cancel_lru_locks osc
11960                 stime=$(date +%s)
11961                 time $lsx $DIR/$tdir | wc -l
11962                 etime=$(date +%s)
11963                 delta=$((etime - stime))
11964                 log "$lsx $i files without statahead: $delta sec"
11965                 lctl set_param llite.*.statahead_max=$max
11966
11967                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11968                         grep "statahead wrong:" | awk '{print $3}')
11969                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11970                 cancel_lru_locks mdc
11971                 cancel_lru_locks osc
11972                 stime=$(date +%s)
11973                 time $lsx $DIR/$tdir | wc -l
11974                 etime=$(date +%s)
11975                 delta_sa=$((etime - stime))
11976                 log "$lsx $i files with statahead: $delta_sa sec"
11977                 lctl get_param -n llite.*.statahead_stats
11978                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11979                         grep "statahead wrong:" | awk '{print $3}')
11980
11981                 [[ $swrong -lt $ewrong ]] &&
11982                         log "statahead was stopped, maybe too many locks held!"
11983                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11984
11985                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11986                         max=$(lctl get_param -n llite.*.statahead_max |
11987                                 head -n 1)
11988                         lctl set_param -n llite.*.statahead_max 0
11989                         lctl get_param llite.*.statahead_max
11990                         cancel_lru_locks mdc
11991                         cancel_lru_locks osc
11992                         stime=$(date +%s)
11993                         time $lsx $DIR/$tdir | wc -l
11994                         etime=$(date +%s)
11995                         delta=$((etime - stime))
11996                         log "$lsx $i files again without statahead: $delta sec"
11997                         lctl set_param llite.*.statahead_max=$max
11998                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11999                                 if [  $SLOWOK -eq 0 ]; then
12000                                         error "$lsx $i files is slower with statahead!"
12001                                 else
12002                                         log "$lsx $i files is slower with statahead!"
12003                                 fi
12004                                 break
12005                         fi
12006                 fi
12007
12008                 [ $delta -gt 20 ] && break
12009                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12010                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12011         done
12012         log "$lsx done"
12013
12014         stime=$(date +%s)
12015         rm -r $DIR/$tdir
12016         sync
12017         etime=$(date +%s)
12018         delta=$((etime - stime))
12019         log "rm -r $DIR/$tdir/: $delta seconds"
12020         log "rm done"
12021         lctl get_param -n llite.*.statahead_stats
12022 }
12023
12024 test_123aa() {
12025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12026
12027         test_123a_base "ls -l"
12028 }
12029 run_test 123aa "verify statahead work"
12030
12031 test_123ab() {
12032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12033
12034         statx_supported || skip_env "Test must be statx() syscall supported"
12035
12036         test_123a_base "$STATX -l"
12037 }
12038 run_test 123ab "verify statahead work by using statx"
12039
12040 test_123ac() {
12041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12042
12043         statx_supported || skip_env "Test must be statx() syscall supported"
12044
12045         local rpcs_before
12046         local rpcs_after
12047         local agl_before
12048         local agl_after
12049
12050         cancel_lru_locks $OSC
12051         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12052         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12053                 awk '/agl.total:/ {print $3}')
12054         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12055         test_123a_base "$STATX --cached=always -D"
12056         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12057                 awk '/agl.total:/ {print $3}')
12058         [ $agl_before -eq $agl_after ] ||
12059                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12060         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12061         [ $rpcs_after -eq $rpcs_before ] ||
12062                 error "$STATX should not send glimpse RPCs to $OSC"
12063 }
12064 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12065
12066 test_123b () { # statahead(bug 15027)
12067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12068
12069         test_mkdir $DIR/$tdir
12070         createmany -o $DIR/$tdir/$tfile-%d 1000
12071
12072         cancel_lru_locks mdc
12073         cancel_lru_locks osc
12074
12075 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12076         lctl set_param fail_loc=0x80000803
12077         ls -lR $DIR/$tdir > /dev/null
12078         log "ls done"
12079         lctl set_param fail_loc=0x0
12080         lctl get_param -n llite.*.statahead_stats
12081         rm -r $DIR/$tdir
12082         sync
12083
12084 }
12085 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12086
12087 test_123c() {
12088         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12089
12090         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12091         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12092         touch $DIR/$tdir.1/{1..3}
12093         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12094
12095         remount_client $MOUNT
12096
12097         $MULTIOP $DIR/$tdir.0 Q
12098
12099         # let statahead to complete
12100         ls -l $DIR/$tdir.0 > /dev/null
12101
12102         testid=$(echo $TESTNAME | tr '_' ' ')
12103         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12104                 error "statahead warning" || true
12105 }
12106 run_test 123c "Can not initialize inode warning on DNE statahead"
12107
12108 test_124a() {
12109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12110         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12111                 skip_env "no lru resize on server"
12112
12113         local NR=2000
12114
12115         test_mkdir $DIR/$tdir
12116
12117         log "create $NR files at $DIR/$tdir"
12118         createmany -o $DIR/$tdir/f $NR ||
12119                 error "failed to create $NR files in $DIR/$tdir"
12120
12121         cancel_lru_locks mdc
12122         ls -l $DIR/$tdir > /dev/null
12123
12124         local NSDIR=""
12125         local LRU_SIZE=0
12126         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12127                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12128                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12129                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12130                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12131                         log "NSDIR=$NSDIR"
12132                         log "NS=$(basename $NSDIR)"
12133                         break
12134                 fi
12135         done
12136
12137         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12138                 skip "Not enough cached locks created!"
12139         fi
12140         log "LRU=$LRU_SIZE"
12141
12142         local SLEEP=30
12143
12144         # We know that lru resize allows one client to hold $LIMIT locks
12145         # for 10h. After that locks begin to be killed by client.
12146         local MAX_HRS=10
12147         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12148         log "LIMIT=$LIMIT"
12149         if [ $LIMIT -lt $LRU_SIZE ]; then
12150                 skip "Limit is too small $LIMIT"
12151         fi
12152
12153         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12154         # killing locks. Some time was spent for creating locks. This means
12155         # that up to the moment of sleep finish we must have killed some of
12156         # them (10-100 locks). This depends on how fast ther were created.
12157         # Many of them were touched in almost the same moment and thus will
12158         # be killed in groups.
12159         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12160
12161         # Use $LRU_SIZE_B here to take into account real number of locks
12162         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12163         local LRU_SIZE_B=$LRU_SIZE
12164         log "LVF=$LVF"
12165         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12166         log "OLD_LVF=$OLD_LVF"
12167         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12168
12169         # Let's make sure that we really have some margin. Client checks
12170         # cached locks every 10 sec.
12171         SLEEP=$((SLEEP+20))
12172         log "Sleep ${SLEEP} sec"
12173         local SEC=0
12174         while ((SEC<$SLEEP)); do
12175                 echo -n "..."
12176                 sleep 5
12177                 SEC=$((SEC+5))
12178                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12179                 echo -n "$LRU_SIZE"
12180         done
12181         echo ""
12182         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12183         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12184
12185         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12186                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12187                 unlinkmany $DIR/$tdir/f $NR
12188                 return
12189         }
12190
12191         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12192         log "unlink $NR files at $DIR/$tdir"
12193         unlinkmany $DIR/$tdir/f $NR
12194 }
12195 run_test 124a "lru resize ======================================="
12196
12197 get_max_pool_limit()
12198 {
12199         local limit=$($LCTL get_param \
12200                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12201         local max=0
12202         for l in $limit; do
12203                 if [[ $l -gt $max ]]; then
12204                         max=$l
12205                 fi
12206         done
12207         echo $max
12208 }
12209
12210 test_124b() {
12211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12212         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12213                 skip_env "no lru resize on server"
12214
12215         LIMIT=$(get_max_pool_limit)
12216
12217         NR=$(($(default_lru_size)*20))
12218         if [[ $NR -gt $LIMIT ]]; then
12219                 log "Limit lock number by $LIMIT locks"
12220                 NR=$LIMIT
12221         fi
12222
12223         IFree=$(mdsrate_inodes_available)
12224         if [ $IFree -lt $NR ]; then
12225                 log "Limit lock number by $IFree inodes"
12226                 NR=$IFree
12227         fi
12228
12229         lru_resize_disable mdc
12230         test_mkdir -p $DIR/$tdir/disable_lru_resize
12231
12232         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12233         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12234         cancel_lru_locks mdc
12235         stime=`date +%s`
12236         PID=""
12237         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12238         PID="$PID $!"
12239         sleep 2
12240         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12241         PID="$PID $!"
12242         sleep 2
12243         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12244         PID="$PID $!"
12245         wait $PID
12246         etime=`date +%s`
12247         nolruresize_delta=$((etime-stime))
12248         log "ls -la time: $nolruresize_delta seconds"
12249         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12250         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12251
12252         lru_resize_enable mdc
12253         test_mkdir -p $DIR/$tdir/enable_lru_resize
12254
12255         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12256         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12257         cancel_lru_locks mdc
12258         stime=`date +%s`
12259         PID=""
12260         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12261         PID="$PID $!"
12262         sleep 2
12263         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12264         PID="$PID $!"
12265         sleep 2
12266         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12267         PID="$PID $!"
12268         wait $PID
12269         etime=`date +%s`
12270         lruresize_delta=$((etime-stime))
12271         log "ls -la time: $lruresize_delta seconds"
12272         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12273
12274         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12275                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12276         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12277                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12278         else
12279                 log "lru resize performs the same with no lru resize"
12280         fi
12281         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12282 }
12283 run_test 124b "lru resize (performance test) ======================="
12284
12285 test_124c() {
12286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12287         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12288                 skip_env "no lru resize on server"
12289
12290         # cache ununsed locks on client
12291         local nr=100
12292         cancel_lru_locks mdc
12293         test_mkdir $DIR/$tdir
12294         createmany -o $DIR/$tdir/f $nr ||
12295                 error "failed to create $nr files in $DIR/$tdir"
12296         ls -l $DIR/$tdir > /dev/null
12297
12298         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12299         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12300         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12301         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12302         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12303
12304         # set lru_max_age to 1 sec
12305         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12306         echo "sleep $((recalc_p * 2)) seconds..."
12307         sleep $((recalc_p * 2))
12308
12309         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12310         # restore lru_max_age
12311         $LCTL set_param -n $nsdir.lru_max_age $max_age
12312         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12313         unlinkmany $DIR/$tdir/f $nr
12314 }
12315 run_test 124c "LRUR cancel very aged locks"
12316
12317 test_124d() {
12318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12319         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12320                 skip_env "no lru resize on server"
12321
12322         # cache ununsed locks on client
12323         local nr=100
12324
12325         lru_resize_disable mdc
12326         stack_trap "lru_resize_enable mdc" EXIT
12327
12328         cancel_lru_locks mdc
12329
12330         # asynchronous object destroy at MDT could cause bl ast to client
12331         test_mkdir $DIR/$tdir
12332         createmany -o $DIR/$tdir/f $nr ||
12333                 error "failed to create $nr files in $DIR/$tdir"
12334         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12335
12336         ls -l $DIR/$tdir > /dev/null
12337
12338         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12339         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12340         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12341         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12342
12343         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12344
12345         # set lru_max_age to 1 sec
12346         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12347         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12348
12349         echo "sleep $((recalc_p * 2)) seconds..."
12350         sleep $((recalc_p * 2))
12351
12352         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12353
12354         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12355 }
12356 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12357
12358 test_125() { # 13358
12359         $LCTL get_param -n llite.*.client_type | grep -q local ||
12360                 skip "must run as local client"
12361         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12362                 skip_env "must have acl enabled"
12363         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12364
12365         test_mkdir $DIR/$tdir
12366         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12367         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12368         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12369 }
12370 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12371
12372 test_126() { # bug 12829/13455
12373         $GSS && skip_env "must run as gss disabled"
12374         $LCTL get_param -n llite.*.client_type | grep -q local ||
12375                 skip "must run as local client"
12376         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12377
12378         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12379         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12380         rm -f $DIR/$tfile
12381         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12382 }
12383 run_test 126 "check that the fsgid provided by the client is taken into account"
12384
12385 test_127a() { # bug 15521
12386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12387         local name count samp unit min max sum sumsq
12388
12389         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12390         echo "stats before reset"
12391         $LCTL get_param osc.*.stats
12392         $LCTL set_param osc.*.stats=0
12393         local fsize=$((2048 * 1024))
12394
12395         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12396         cancel_lru_locks osc
12397         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12398
12399         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12400         stack_trap "rm -f $TMP/$tfile.tmp"
12401         while read name count samp unit min max sum sumsq; do
12402                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12403                 [ ! $min ] && error "Missing min value for $name proc entry"
12404                 eval $name=$count || error "Wrong proc format"
12405
12406                 case $name in
12407                 read_bytes|write_bytes)
12408                         [[ "$unit" =~ "bytes" ]] ||
12409                                 error "unit is not 'bytes': $unit"
12410                         (( $min >= 4096 )) || error "min is too small: $min"
12411                         (( $min <= $fsize )) || error "min is too big: $min"
12412                         (( $max >= 4096 )) || error "max is too small: $max"
12413                         (( $max <= $fsize )) || error "max is too big: $max"
12414                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12415                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12416                                 error "sumsquare is too small: $sumsq"
12417                         (( $sumsq <= $fsize * $fsize )) ||
12418                                 error "sumsquare is too big: $sumsq"
12419                         ;;
12420                 ost_read|ost_write)
12421                         [[ "$unit" =~ "usec" ]] ||
12422                                 error "unit is not 'usec': $unit"
12423                         ;;
12424                 *)      ;;
12425                 esac
12426         done < $DIR/$tfile.tmp
12427
12428         #check that we actually got some stats
12429         [ "$read_bytes" ] || error "Missing read_bytes stats"
12430         [ "$write_bytes" ] || error "Missing write_bytes stats"
12431         [ "$read_bytes" != 0 ] || error "no read done"
12432         [ "$write_bytes" != 0 ] || error "no write done"
12433 }
12434 run_test 127a "verify the client stats are sane"
12435
12436 test_127b() { # bug LU-333
12437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12438         local name count samp unit min max sum sumsq
12439
12440         echo "stats before reset"
12441         $LCTL get_param llite.*.stats
12442         $LCTL set_param llite.*.stats=0
12443
12444         # perform 2 reads and writes so MAX is different from SUM.
12445         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12446         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12447         cancel_lru_locks osc
12448         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12449         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12450
12451         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12452         stack_trap "rm -f $TMP/$tfile.tmp"
12453         while read name count samp unit min max sum sumsq; do
12454                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12455                 eval $name=$count || error "Wrong proc format"
12456
12457                 case $name in
12458                 read_bytes|write_bytes)
12459                         [[ "$unit" =~ "bytes" ]] ||
12460                                 error "unit is not 'bytes': $unit"
12461                         (( $count == 2 )) || error "count is not 2: $count"
12462                         (( $min == $PAGE_SIZE )) ||
12463                                 error "min is not $PAGE_SIZE: $min"
12464                         (( $max == $PAGE_SIZE )) ||
12465                                 error "max is not $PAGE_SIZE: $max"
12466                         (( $sum == $PAGE_SIZE * 2 )) ||
12467                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12468                         ;;
12469                 read|write)
12470                         [[ "$unit" =~ "usec" ]] ||
12471                                 error "unit is not 'usec': $unit"
12472                         ;;
12473                 *)      ;;
12474                 esac
12475         done < $TMP/$tfile.tmp
12476
12477         #check that we actually got some stats
12478         [ "$read_bytes" ] || error "Missing read_bytes stats"
12479         [ "$write_bytes" ] || error "Missing write_bytes stats"
12480         [ "$read_bytes" != 0 ] || error "no read done"
12481         [ "$write_bytes" != 0 ] || error "no write done"
12482 }
12483 run_test 127b "verify the llite client stats are sane"
12484
12485 test_127c() { # LU-12394
12486         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12487         local size
12488         local bsize
12489         local reads
12490         local writes
12491         local count
12492
12493         $LCTL set_param llite.*.extents_stats=1
12494         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12495
12496         # Use two stripes so there is enough space in default config
12497         $LFS setstripe -c 2 $DIR/$tfile
12498
12499         # Extent stats start at 0-4K and go in power of two buckets
12500         # LL_HIST_START = 12 --> 2^12 = 4K
12501         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12502         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12503         # small configs
12504         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12505                 do
12506                 # Write and read, 2x each, second time at a non-zero offset
12507                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12508                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12509                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12510                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12511                 rm -f $DIR/$tfile
12512         done
12513
12514         $LCTL get_param llite.*.extents_stats
12515
12516         count=2
12517         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12518                 do
12519                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12520                                 grep -m 1 $bsize)
12521                 reads=$(echo $bucket | awk '{print $5}')
12522                 writes=$(echo $bucket | awk '{print $9}')
12523                 [ "$reads" -eq $count ] ||
12524                         error "$reads reads in < $bsize bucket, expect $count"
12525                 [ "$writes" -eq $count ] ||
12526                         error "$writes writes in < $bsize bucket, expect $count"
12527         done
12528
12529         # Test mmap write and read
12530         $LCTL set_param llite.*.extents_stats=c
12531         size=512
12532         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12533         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12534         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12535
12536         $LCTL get_param llite.*.extents_stats
12537
12538         count=$(((size*1024) / PAGE_SIZE))
12539
12540         bsize=$((2 * PAGE_SIZE / 1024))K
12541
12542         bucket=$($LCTL get_param -n llite.*.extents_stats |
12543                         grep -m 1 $bsize)
12544         reads=$(echo $bucket | awk '{print $5}')
12545         writes=$(echo $bucket | awk '{print $9}')
12546         # mmap writes fault in the page first, creating an additonal read
12547         [ "$reads" -eq $((2 * count)) ] ||
12548                 error "$reads reads in < $bsize bucket, expect $count"
12549         [ "$writes" -eq $count ] ||
12550                 error "$writes writes in < $bsize bucket, expect $count"
12551 }
12552 run_test 127c "test llite extent stats with regular & mmap i/o"
12553
12554 test_128() { # bug 15212
12555         touch $DIR/$tfile
12556         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12557                 find $DIR/$tfile
12558                 find $DIR/$tfile
12559         EOF
12560
12561         result=$(grep error $TMP/$tfile.log)
12562         rm -f $DIR/$tfile $TMP/$tfile.log
12563         [ -z "$result" ] ||
12564                 error "consecutive find's under interactive lfs failed"
12565 }
12566 run_test 128 "interactive lfs for 2 consecutive find's"
12567
12568 set_dir_limits () {
12569         local mntdev
12570         local canondev
12571         local node
12572
12573         local ldproc=/proc/fs/ldiskfs
12574         local facets=$(get_facets MDS)
12575
12576         for facet in ${facets//,/ }; do
12577                 canondev=$(ldiskfs_canon \
12578                            *.$(convert_facet2label $facet).mntdev $facet)
12579                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12580                         ldproc=/sys/fs/ldiskfs
12581                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12582                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12583         done
12584 }
12585
12586 check_mds_dmesg() {
12587         local facets=$(get_facets MDS)
12588         for facet in ${facets//,/ }; do
12589                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12590         done
12591         return 1
12592 }
12593
12594 test_129() {
12595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12596         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12597                 skip "Need MDS version with at least 2.5.56"
12598         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12599                 skip_env "ldiskfs only test"
12600         fi
12601         remote_mds_nodsh && skip "remote MDS with nodsh"
12602
12603         local ENOSPC=28
12604         local has_warning=false
12605
12606         rm -rf $DIR/$tdir
12607         mkdir -p $DIR/$tdir
12608
12609         # block size of mds1
12610         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12611         set_dir_limits $maxsize $((maxsize * 6 / 8))
12612         stack_trap "set_dir_limits 0 0"
12613         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12614         local dirsize=$(stat -c%s "$DIR/$tdir")
12615         local nfiles=0
12616         while (( $dirsize <= $maxsize )); do
12617                 $MCREATE $DIR/$tdir/file_base_$nfiles
12618                 rc=$?
12619                 # check two errors:
12620                 # ENOSPC for ext4 max_dir_size, which has been used since
12621                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12622                 if (( rc == ENOSPC )); then
12623                         set_dir_limits 0 0
12624                         echo "rc=$rc returned as expected after $nfiles files"
12625
12626                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12627                                 error "create failed w/o dir size limit"
12628
12629                         # messages may be rate limited if test is run repeatedly
12630                         check_mds_dmesg '"is approaching max"' ||
12631                                 echo "warning message should be output"
12632                         check_mds_dmesg '"has reached max"' ||
12633                                 echo "reached message should be output"
12634
12635                         dirsize=$(stat -c%s "$DIR/$tdir")
12636
12637                         [[ $dirsize -ge $maxsize ]] && return 0
12638                         error "dirsize $dirsize < $maxsize after $nfiles files"
12639                 elif (( rc != 0 )); then
12640                         break
12641                 fi
12642                 nfiles=$((nfiles + 1))
12643                 dirsize=$(stat -c%s "$DIR/$tdir")
12644         done
12645
12646         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12647 }
12648 run_test 129 "test directory size limit ========================"
12649
12650 OLDIFS="$IFS"
12651 cleanup_130() {
12652         trap 0
12653         IFS="$OLDIFS"
12654 }
12655
12656 test_130a() {
12657         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12658         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12659
12660         trap cleanup_130 EXIT RETURN
12661
12662         local fm_file=$DIR/$tfile
12663         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12664         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12665                 error "dd failed for $fm_file"
12666
12667         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12668         filefrag -ves $fm_file
12669         RC=$?
12670         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12671                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12672         [ $RC != 0 ] && error "filefrag $fm_file failed"
12673
12674         filefrag_op=$(filefrag -ve -k $fm_file |
12675                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12676         lun=$($LFS getstripe -i $fm_file)
12677
12678         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12679         IFS=$'\n'
12680         tot_len=0
12681         for line in $filefrag_op
12682         do
12683                 frag_lun=`echo $line | cut -d: -f5`
12684                 ext_len=`echo $line | cut -d: -f4`
12685                 if (( $frag_lun != $lun )); then
12686                         cleanup_130
12687                         error "FIEMAP on 1-stripe file($fm_file) failed"
12688                         return
12689                 fi
12690                 (( tot_len += ext_len ))
12691         done
12692
12693         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12694                 cleanup_130
12695                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12696                 return
12697         fi
12698
12699         cleanup_130
12700
12701         echo "FIEMAP on single striped file succeeded"
12702 }
12703 run_test 130a "FIEMAP (1-stripe file)"
12704
12705 test_130b() {
12706         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12707
12708         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12709         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12710
12711         trap cleanup_130 EXIT RETURN
12712
12713         local fm_file=$DIR/$tfile
12714         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12715                         error "setstripe on $fm_file"
12716         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12717                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12718
12719         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12720                 error "dd failed on $fm_file"
12721
12722         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12723         filefrag_op=$(filefrag -ve -k $fm_file |
12724                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12725
12726         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12727                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12728
12729         IFS=$'\n'
12730         tot_len=0
12731         num_luns=1
12732         for line in $filefrag_op
12733         do
12734                 frag_lun=$(echo $line | cut -d: -f5 |
12735                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12736                 ext_len=$(echo $line | cut -d: -f4)
12737                 if (( $frag_lun != $last_lun )); then
12738                         if (( tot_len != 1024 )); then
12739                                 cleanup_130
12740                                 error "FIEMAP on $fm_file failed; returned " \
12741                                 "len $tot_len for OST $last_lun instead of 1024"
12742                                 return
12743                         else
12744                                 (( num_luns += 1 ))
12745                                 tot_len=0
12746                         fi
12747                 fi
12748                 (( tot_len += ext_len ))
12749                 last_lun=$frag_lun
12750         done
12751         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12752                 cleanup_130
12753                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12754                         "luns or wrong len for OST $last_lun"
12755                 return
12756         fi
12757
12758         cleanup_130
12759
12760         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12761 }
12762 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12763
12764 test_130c() {
12765         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12766
12767         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12768         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12769
12770         trap cleanup_130 EXIT RETURN
12771
12772         local fm_file=$DIR/$tfile
12773         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12774         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12775                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12776
12777         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12778                         error "dd failed on $fm_file"
12779
12780         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12781         filefrag_op=$(filefrag -ve -k $fm_file |
12782                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12783
12784         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12785                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12786
12787         IFS=$'\n'
12788         tot_len=0
12789         num_luns=1
12790         for line in $filefrag_op
12791         do
12792                 frag_lun=$(echo $line | cut -d: -f5 |
12793                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12794                 ext_len=$(echo $line | cut -d: -f4)
12795                 if (( $frag_lun != $last_lun )); then
12796                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12797                         if (( logical != 512 )); then
12798                                 cleanup_130
12799                                 error "FIEMAP on $fm_file failed; returned " \
12800                                 "logical start for lun $logical instead of 512"
12801                                 return
12802                         fi
12803                         if (( tot_len != 512 )); then
12804                                 cleanup_130
12805                                 error "FIEMAP on $fm_file failed; returned " \
12806                                 "len $tot_len for OST $last_lun instead of 1024"
12807                                 return
12808                         else
12809                                 (( num_luns += 1 ))
12810                                 tot_len=0
12811                         fi
12812                 fi
12813                 (( tot_len += ext_len ))
12814                 last_lun=$frag_lun
12815         done
12816         if (( num_luns != 2 || tot_len != 512 )); then
12817                 cleanup_130
12818                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12819                         "luns or wrong len for OST $last_lun"
12820                 return
12821         fi
12822
12823         cleanup_130
12824
12825         echo "FIEMAP on 2-stripe file with hole succeeded"
12826 }
12827 run_test 130c "FIEMAP (2-stripe file with hole)"
12828
12829 test_130d() {
12830         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12831
12832         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12833         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12834
12835         trap cleanup_130 EXIT RETURN
12836
12837         local fm_file=$DIR/$tfile
12838         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12839                         error "setstripe on $fm_file"
12840         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12841                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12842
12843         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12844         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12845                 error "dd failed on $fm_file"
12846
12847         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12848         filefrag_op=$(filefrag -ve -k $fm_file |
12849                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12850
12851         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12852                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12853
12854         IFS=$'\n'
12855         tot_len=0
12856         num_luns=1
12857         for line in $filefrag_op
12858         do
12859                 frag_lun=$(echo $line | cut -d: -f5 |
12860                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12861                 ext_len=$(echo $line | cut -d: -f4)
12862                 if (( $frag_lun != $last_lun )); then
12863                         if (( tot_len != 1024 )); then
12864                                 cleanup_130
12865                                 error "FIEMAP on $fm_file failed; returned " \
12866                                 "len $tot_len for OST $last_lun instead of 1024"
12867                                 return
12868                         else
12869                                 (( num_luns += 1 ))
12870                                 tot_len=0
12871                         fi
12872                 fi
12873                 (( tot_len += ext_len ))
12874                 last_lun=$frag_lun
12875         done
12876         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12877                 cleanup_130
12878                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12879                         "luns or wrong len for OST $last_lun"
12880                 return
12881         fi
12882
12883         cleanup_130
12884
12885         echo "FIEMAP on N-stripe file succeeded"
12886 }
12887 run_test 130d "FIEMAP (N-stripe file)"
12888
12889 test_130e() {
12890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12891
12892         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12893         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12894
12895         trap cleanup_130 EXIT RETURN
12896
12897         local fm_file=$DIR/$tfile
12898         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12899
12900         NUM_BLKS=512
12901         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12902         for ((i = 0; i < $NUM_BLKS; i++)); do
12903                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12904                         conv=notrunc > /dev/null 2>&1
12905         done
12906
12907         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12908         filefrag_op=$(filefrag -ve -k $fm_file |
12909                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12910
12911         last_lun=$(echo $filefrag_op | cut -d: -f5)
12912
12913         IFS=$'\n'
12914         tot_len=0
12915         num_luns=1
12916         for line in $filefrag_op; do
12917                 frag_lun=$(echo $line | cut -d: -f5)
12918                 ext_len=$(echo $line | cut -d: -f4)
12919                 if [[ "$frag_lun" != "$last_lun" ]]; then
12920                         if (( tot_len != $EXPECTED_LEN )); then
12921                                 cleanup_130
12922                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12923                         else
12924                                 (( num_luns += 1 ))
12925                                 tot_len=0
12926                         fi
12927                 fi
12928                 (( tot_len += ext_len ))
12929                 last_lun=$frag_lun
12930         done
12931         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12932                 cleanup_130
12933                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12934         fi
12935
12936         echo "FIEMAP with continuation calls succeeded"
12937 }
12938 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12939
12940 test_130f() {
12941         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12942         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12943
12944         local fm_file=$DIR/$tfile
12945         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12946                 error "multiop create with lov_delay_create on $fm_file"
12947
12948         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12949         filefrag_extents=$(filefrag -vek $fm_file |
12950                            awk '/extents? found/ { print $2 }')
12951         if [[ "$filefrag_extents" != "0" ]]; then
12952                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
12953         fi
12954
12955         rm -f $fm_file
12956 }
12957 run_test 130f "FIEMAP (unstriped file)"
12958
12959 test_130g() {
12960         local file=$DIR/$tfile
12961         local nr=$((OSTCOUNT * 100))
12962
12963         $LFS setstripe -C $nr $file ||
12964                 error "failed to setstripe -C $nr $file"
12965
12966         dd if=/dev/zero of=$file count=$nr bs=1M
12967         sync
12968         nr=$($LFS getstripe -c $file)
12969
12970         local extents=$(filefrag -v $file |
12971                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
12972
12973         echo "filefrag list $extents extents in file with stripecount $nr"
12974         if (( extents < nr )); then
12975                 $LFS getstripe $file
12976                 filefrag -v $file
12977                 error "filefrag printed $extents < $nr extents"
12978         fi
12979
12980         rm -f $file
12981 }
12982 run_test 130g "FIEMAP (overstripe file)"
12983
12984 # Test for writev/readv
12985 test_131a() {
12986         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12987                 error "writev test failed"
12988         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12989                 error "readv failed"
12990         rm -f $DIR/$tfile
12991 }
12992 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12993
12994 test_131b() {
12995         local fsize=$((524288 + 1048576 + 1572864))
12996         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12997                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12998                         error "append writev test failed"
12999
13000         ((fsize += 1572864 + 1048576))
13001         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13002                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13003                         error "append writev test failed"
13004         rm -f $DIR/$tfile
13005 }
13006 run_test 131b "test append writev"
13007
13008 test_131c() {
13009         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13010         error "NOT PASS"
13011 }
13012 run_test 131c "test read/write on file w/o objects"
13013
13014 test_131d() {
13015         rwv -f $DIR/$tfile -w -n 1 1572864
13016         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13017         if [ "$NOB" != 1572864 ]; then
13018                 error "Short read filed: read $NOB bytes instead of 1572864"
13019         fi
13020         rm -f $DIR/$tfile
13021 }
13022 run_test 131d "test short read"
13023
13024 test_131e() {
13025         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13026         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13027         error "read hitting hole failed"
13028         rm -f $DIR/$tfile
13029 }
13030 run_test 131e "test read hitting hole"
13031
13032 check_stats() {
13033         local facet=$1
13034         local op=$2
13035         local want=${3:-0}
13036         local res
13037
13038         case $facet in
13039         mds*) res=$(do_facet $facet \
13040                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13041                  ;;
13042         ost*) res=$(do_facet $facet \
13043                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13044                  ;;
13045         *) error "Wrong facet '$facet'" ;;
13046         esac
13047         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13048         # if the argument $3 is zero, it means any stat increment is ok.
13049         if [[ $want -gt 0 ]]; then
13050                 local count=$(echo $res | awk '{ print $2 }')
13051                 [[ $count -ne $want ]] &&
13052                         error "The $op counter on $facet is $count, not $want"
13053         fi
13054 }
13055
13056 test_133a() {
13057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13058         remote_ost_nodsh && skip "remote OST with nodsh"
13059         remote_mds_nodsh && skip "remote MDS with nodsh"
13060         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13061                 skip_env "MDS doesn't support rename stats"
13062
13063         local testdir=$DIR/${tdir}/stats_testdir
13064
13065         mkdir -p $DIR/${tdir}
13066
13067         # clear stats.
13068         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13069         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13070
13071         # verify mdt stats first.
13072         mkdir ${testdir} || error "mkdir failed"
13073         check_stats $SINGLEMDS "mkdir" 1
13074         touch ${testdir}/${tfile} || error "touch failed"
13075         check_stats $SINGLEMDS "open" 1
13076         check_stats $SINGLEMDS "close" 1
13077         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13078                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13079                 check_stats $SINGLEMDS "mknod" 2
13080         }
13081         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13082         check_stats $SINGLEMDS "unlink" 1
13083         rm -f ${testdir}/${tfile} || error "file remove failed"
13084         check_stats $SINGLEMDS "unlink" 2
13085
13086         # remove working dir and check mdt stats again.
13087         rmdir ${testdir} || error "rmdir failed"
13088         check_stats $SINGLEMDS "rmdir" 1
13089
13090         local testdir1=$DIR/${tdir}/stats_testdir1
13091         mkdir -p ${testdir}
13092         mkdir -p ${testdir1}
13093         touch ${testdir1}/test1
13094         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13095         check_stats $SINGLEMDS "crossdir_rename" 1
13096
13097         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13098         check_stats $SINGLEMDS "samedir_rename" 1
13099
13100         rm -rf $DIR/${tdir}
13101 }
13102 run_test 133a "Verifying MDT stats ========================================"
13103
13104 test_133b() {
13105         local res
13106
13107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13108         remote_ost_nodsh && skip "remote OST with nodsh"
13109         remote_mds_nodsh && skip "remote MDS with nodsh"
13110
13111         local testdir=$DIR/${tdir}/stats_testdir
13112
13113         mkdir -p ${testdir} || error "mkdir failed"
13114         touch ${testdir}/${tfile} || error "touch failed"
13115         cancel_lru_locks mdc
13116
13117         # clear stats.
13118         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13119         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13120
13121         # extra mdt stats verification.
13122         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13123         check_stats $SINGLEMDS "setattr" 1
13124         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13125         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13126         then            # LU-1740
13127                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13128                 check_stats $SINGLEMDS "getattr" 1
13129         fi
13130         rm -rf $DIR/${tdir}
13131
13132         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13133         # so the check below is not reliable
13134         [ $MDSCOUNT -eq 1 ] || return 0
13135
13136         # Sleep to avoid a cached response.
13137         #define OBD_STATFS_CACHE_SECONDS 1
13138         sleep 2
13139         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13140         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13141         $LFS df || error "lfs failed"
13142         check_stats $SINGLEMDS "statfs" 1
13143
13144         # check aggregated statfs (LU-10018)
13145         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13146                 return 0
13147         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13148                 return 0
13149         sleep 2
13150         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13151         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13152         df $DIR
13153         check_stats $SINGLEMDS "statfs" 1
13154
13155         # We want to check that the client didn't send OST_STATFS to
13156         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13157         # extra care is needed here.
13158         if remote_mds; then
13159                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13160                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13161
13162                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13163                 [ "$res" ] && error "OST got STATFS"
13164         fi
13165
13166         return 0
13167 }
13168 run_test 133b "Verifying extra MDT stats =================================="
13169
13170 test_133c() {
13171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13172         remote_ost_nodsh && skip "remote OST with nodsh"
13173         remote_mds_nodsh && skip "remote MDS with nodsh"
13174
13175         local testdir=$DIR/$tdir/stats_testdir
13176
13177         test_mkdir -p $testdir
13178
13179         # verify obdfilter stats.
13180         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13181         sync
13182         cancel_lru_locks osc
13183         wait_delete_completed
13184
13185         # clear stats.
13186         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13187         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13188
13189         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13190                 error "dd failed"
13191         sync
13192         cancel_lru_locks osc
13193         check_stats ost1 "write" 1
13194
13195         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13196         check_stats ost1 "read" 1
13197
13198         > $testdir/$tfile || error "truncate failed"
13199         check_stats ost1 "punch" 1
13200
13201         rm -f $testdir/$tfile || error "file remove failed"
13202         wait_delete_completed
13203         check_stats ost1 "destroy" 1
13204
13205         rm -rf $DIR/$tdir
13206 }
13207 run_test 133c "Verifying OST stats ========================================"
13208
13209 order_2() {
13210         local value=$1
13211         local orig=$value
13212         local order=1
13213
13214         while [ $value -ge 2 ]; do
13215                 order=$((order*2))
13216                 value=$((value/2))
13217         done
13218
13219         if [ $orig -gt $order ]; then
13220                 order=$((order*2))
13221         fi
13222         echo $order
13223 }
13224
13225 size_in_KMGT() {
13226     local value=$1
13227     local size=('K' 'M' 'G' 'T');
13228     local i=0
13229     local size_string=$value
13230
13231     while [ $value -ge 1024 ]; do
13232         if [ $i -gt 3 ]; then
13233             #T is the biggest unit we get here, if that is bigger,
13234             #just return XXXT
13235             size_string=${value}T
13236             break
13237         fi
13238         value=$((value >> 10))
13239         if [ $value -lt 1024 ]; then
13240             size_string=${value}${size[$i]}
13241             break
13242         fi
13243         i=$((i + 1))
13244     done
13245
13246     echo $size_string
13247 }
13248
13249 get_rename_size() {
13250         local size=$1
13251         local context=${2:-.}
13252         local sample=$(do_facet $SINGLEMDS $LCTL \
13253                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13254                 grep -A1 $context |
13255                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13256         echo $sample
13257 }
13258
13259 test_133d() {
13260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13261         remote_ost_nodsh && skip "remote OST with nodsh"
13262         remote_mds_nodsh && skip "remote MDS with nodsh"
13263         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13264                 skip_env "MDS doesn't support rename stats"
13265
13266         local testdir1=$DIR/${tdir}/stats_testdir1
13267         local testdir2=$DIR/${tdir}/stats_testdir2
13268         mkdir -p $DIR/${tdir}
13269
13270         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13271
13272         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13273         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13274
13275         createmany -o $testdir1/test 512 || error "createmany failed"
13276
13277         # check samedir rename size
13278         mv ${testdir1}/test0 ${testdir1}/test_0
13279
13280         local testdir1_size=$(ls -l $DIR/${tdir} |
13281                 awk '/stats_testdir1/ {print $5}')
13282         local testdir2_size=$(ls -l $DIR/${tdir} |
13283                 awk '/stats_testdir2/ {print $5}')
13284
13285         testdir1_size=$(order_2 $testdir1_size)
13286         testdir2_size=$(order_2 $testdir2_size)
13287
13288         testdir1_size=$(size_in_KMGT $testdir1_size)
13289         testdir2_size=$(size_in_KMGT $testdir2_size)
13290
13291         echo "source rename dir size: ${testdir1_size}"
13292         echo "target rename dir size: ${testdir2_size}"
13293
13294         local cmd="do_facet $SINGLEMDS $LCTL "
13295         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13296
13297         eval $cmd || error "$cmd failed"
13298         local samedir=$($cmd | grep 'same_dir')
13299         local same_sample=$(get_rename_size $testdir1_size)
13300         [ -z "$samedir" ] && error "samedir_rename_size count error"
13301         [[ $same_sample -eq 1 ]] ||
13302                 error "samedir_rename_size error $same_sample"
13303         echo "Check same dir rename stats success"
13304
13305         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13306
13307         # check crossdir rename size
13308         mv ${testdir1}/test_0 ${testdir2}/test_0
13309
13310         testdir1_size=$(ls -l $DIR/${tdir} |
13311                 awk '/stats_testdir1/ {print $5}')
13312         testdir2_size=$(ls -l $DIR/${tdir} |
13313                 awk '/stats_testdir2/ {print $5}')
13314
13315         testdir1_size=$(order_2 $testdir1_size)
13316         testdir2_size=$(order_2 $testdir2_size)
13317
13318         testdir1_size=$(size_in_KMGT $testdir1_size)
13319         testdir2_size=$(size_in_KMGT $testdir2_size)
13320
13321         echo "source rename dir size: ${testdir1_size}"
13322         echo "target rename dir size: ${testdir2_size}"
13323
13324         eval $cmd || error "$cmd failed"
13325         local crossdir=$($cmd | grep 'crossdir')
13326         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13327         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13328         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13329         [[ $src_sample -eq 1 ]] ||
13330                 error "crossdir_rename_size error $src_sample"
13331         [[ $tgt_sample -eq 1 ]] ||
13332                 error "crossdir_rename_size error $tgt_sample"
13333         echo "Check cross dir rename stats success"
13334         rm -rf $DIR/${tdir}
13335 }
13336 run_test 133d "Verifying rename_stats ========================================"
13337
13338 test_133e() {
13339         remote_mds_nodsh && skip "remote MDS with nodsh"
13340         remote_ost_nodsh && skip "remote OST with nodsh"
13341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13342
13343         local testdir=$DIR/${tdir}/stats_testdir
13344         local ctr f0 f1 bs=32768 count=42 sum
13345
13346         mkdir -p ${testdir} || error "mkdir failed"
13347
13348         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13349
13350         for ctr in {write,read}_bytes; do
13351                 sync
13352                 cancel_lru_locks osc
13353
13354                 do_facet ost1 $LCTL set_param -n \
13355                         "obdfilter.*.exports.clear=clear"
13356
13357                 if [ $ctr = write_bytes ]; then
13358                         f0=/dev/zero
13359                         f1=${testdir}/${tfile}
13360                 else
13361                         f0=${testdir}/${tfile}
13362                         f1=/dev/null
13363                 fi
13364
13365                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13366                         error "dd failed"
13367                 sync
13368                 cancel_lru_locks osc
13369
13370                 sum=$(do_facet ost1 $LCTL get_param \
13371                         "obdfilter.*.exports.*.stats" |
13372                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13373                                 $1 == ctr { sum += $7 }
13374                                 END { printf("%0.0f", sum) }')
13375
13376                 if ((sum != bs * count)); then
13377                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13378                 fi
13379         done
13380
13381         rm -rf $DIR/${tdir}
13382 }
13383 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13384
13385 test_133f() {
13386         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13387                 skip "too old lustre for get_param -R ($facet_ver)"
13388
13389         # verifying readability.
13390         $LCTL get_param -R '*' &> /dev/null
13391
13392         # Verifing writability with badarea_io.
13393         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13394                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13395                 error "client badarea_io failed"
13396
13397         # remount the FS in case writes/reads /proc break the FS
13398         cleanup || error "failed to unmount"
13399         setup || error "failed to setup"
13400 }
13401 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13402
13403 test_133g() {
13404         remote_mds_nodsh && skip "remote MDS with nodsh"
13405         remote_ost_nodsh && skip "remote OST with nodsh"
13406
13407         local facet
13408         for facet in mds1 ost1; do
13409                 local facet_ver=$(lustre_version_code $facet)
13410                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13411                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13412                 else
13413                         log "$facet: too old lustre for get_param -R"
13414                 fi
13415                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13416                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13417                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13418                                 xargs badarea_io" ||
13419                                         error "$facet badarea_io failed"
13420                 else
13421                         skip_noexit "$facet: too old lustre for get_param -R"
13422                 fi
13423         done
13424
13425         # remount the FS in case writes/reads /proc break the FS
13426         cleanup || error "failed to unmount"
13427         setup || error "failed to setup"
13428 }
13429 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13430
13431 test_133h() {
13432         remote_mds_nodsh && skip "remote MDS with nodsh"
13433         remote_ost_nodsh && skip "remote OST with nodsh"
13434         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13435                 skip "Need MDS version at least 2.9.54"
13436
13437         local facet
13438         for facet in client mds1 ost1; do
13439                 # Get the list of files that are missing the terminating newline
13440                 local plist=$(do_facet $facet
13441                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13442                 local ent
13443                 for ent in $plist; do
13444                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13445                                 awk -v FS='\v' -v RS='\v\v' \
13446                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13447                                         print FILENAME}'" 2>/dev/null)
13448                         [ -z $missing ] || {
13449                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13450                                 error "file does not end with newline: $facet-$ent"
13451                         }
13452                 done
13453         done
13454 }
13455 run_test 133h "Proc files should end with newlines"
13456
13457 test_134a() {
13458         remote_mds_nodsh && skip "remote MDS with nodsh"
13459         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13460                 skip "Need MDS version at least 2.7.54"
13461
13462         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13463         cancel_lru_locks mdc
13464
13465         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13466         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13467         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13468
13469         local nr=1000
13470         createmany -o $DIR/$tdir/f $nr ||
13471                 error "failed to create $nr files in $DIR/$tdir"
13472         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13473
13474         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13475         do_facet mds1 $LCTL set_param fail_loc=0x327
13476         do_facet mds1 $LCTL set_param fail_val=500
13477         touch $DIR/$tdir/m
13478
13479         echo "sleep 10 seconds ..."
13480         sleep 10
13481         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13482
13483         do_facet mds1 $LCTL set_param fail_loc=0
13484         do_facet mds1 $LCTL set_param fail_val=0
13485         [ $lck_cnt -lt $unused ] ||
13486                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13487
13488         rm $DIR/$tdir/m
13489         unlinkmany $DIR/$tdir/f $nr
13490 }
13491 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13492
13493 test_134b() {
13494         remote_mds_nodsh && skip "remote MDS with nodsh"
13495         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13496                 skip "Need MDS version at least 2.7.54"
13497
13498         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13499         cancel_lru_locks mdc
13500
13501         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13502                         ldlm.lock_reclaim_threshold_mb)
13503         # disable reclaim temporarily
13504         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13505
13506         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13507         do_facet mds1 $LCTL set_param fail_loc=0x328
13508         do_facet mds1 $LCTL set_param fail_val=500
13509
13510         $LCTL set_param debug=+trace
13511
13512         local nr=600
13513         createmany -o $DIR/$tdir/f $nr &
13514         local create_pid=$!
13515
13516         echo "Sleep $TIMEOUT seconds ..."
13517         sleep $TIMEOUT
13518         if ! ps -p $create_pid  > /dev/null 2>&1; then
13519                 do_facet mds1 $LCTL set_param fail_loc=0
13520                 do_facet mds1 $LCTL set_param fail_val=0
13521                 do_facet mds1 $LCTL set_param \
13522                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13523                 error "createmany finished incorrectly!"
13524         fi
13525         do_facet mds1 $LCTL set_param fail_loc=0
13526         do_facet mds1 $LCTL set_param fail_val=0
13527         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13528         wait $create_pid || return 1
13529
13530         unlinkmany $DIR/$tdir/f $nr
13531 }
13532 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13533
13534 test_135() {
13535         remote_mds_nodsh && skip "remote MDS with nodsh"
13536         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13537                 skip "Need MDS version at least 2.13.50"
13538         local fname
13539
13540         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13541
13542 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13543         #set only one record at plain llog
13544         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13545
13546         #fill already existed plain llog each 64767
13547         #wrapping whole catalog
13548         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13549
13550         createmany -o $DIR/$tdir/$tfile_ 64700
13551         for (( i = 0; i < 64700; i = i + 2 ))
13552         do
13553                 rm $DIR/$tdir/$tfile_$i &
13554                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13555                 local pid=$!
13556                 wait $pid
13557         done
13558
13559         #waiting osp synchronization
13560         wait_delete_completed
13561 }
13562 run_test 135 "Race catalog processing"
13563
13564 test_136() {
13565         remote_mds_nodsh && skip "remote MDS with nodsh"
13566         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13567                 skip "Need MDS version at least 2.13.50"
13568         local fname
13569
13570         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13571         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13572         #set only one record at plain llog
13573 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13574         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13575
13576         #fill already existed 2 plain llogs each 64767
13577         #wrapping whole catalog
13578         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13579         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13580         wait_delete_completed
13581
13582         createmany -o $DIR/$tdir/$tfile_ 10
13583         sleep 25
13584
13585         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13586         for (( i = 0; i < 10; i = i + 3 ))
13587         do
13588                 rm $DIR/$tdir/$tfile_$i &
13589                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13590                 local pid=$!
13591                 wait $pid
13592                 sleep 7
13593                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13594         done
13595
13596         #waiting osp synchronization
13597         wait_delete_completed
13598 }
13599 run_test 136 "Race catalog processing 2"
13600
13601 test_140() { #bug-17379
13602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13603
13604         test_mkdir $DIR/$tdir
13605         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13606         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13607
13608         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13609         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13610         local i=0
13611         while i=$((i + 1)); do
13612                 test_mkdir $i
13613                 cd $i || error "Changing to $i"
13614                 ln -s ../stat stat || error "Creating stat symlink"
13615                 # Read the symlink until ELOOP present,
13616                 # not LBUGing the system is considered success,
13617                 # we didn't overrun the stack.
13618                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13619                 if [ $ret -ne 0 ]; then
13620                         if [ $ret -eq 40 ]; then
13621                                 break  # -ELOOP
13622                         else
13623                                 error "Open stat symlink"
13624                                         return
13625                         fi
13626                 fi
13627         done
13628         i=$((i - 1))
13629         echo "The symlink depth = $i"
13630         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13631                 error "Invalid symlink depth"
13632
13633         # Test recursive symlink
13634         ln -s symlink_self symlink_self
13635         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13636         echo "open symlink_self returns $ret"
13637         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13638 }
13639 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13640
13641 test_150a() {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643
13644         local TF="$TMP/$tfile"
13645
13646         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13647         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13648         cp $TF $DIR/$tfile
13649         cancel_lru_locks $OSC
13650         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13651         remount_client $MOUNT
13652         df -P $MOUNT
13653         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13654
13655         $TRUNCATE $TF 6000
13656         $TRUNCATE $DIR/$tfile 6000
13657         cancel_lru_locks $OSC
13658         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13659
13660         echo "12345" >>$TF
13661         echo "12345" >>$DIR/$tfile
13662         cancel_lru_locks $OSC
13663         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13664
13665         echo "12345" >>$TF
13666         echo "12345" >>$DIR/$tfile
13667         cancel_lru_locks $OSC
13668         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13669 }
13670 run_test 150a "truncate/append tests"
13671
13672 test_150b() {
13673         check_set_fallocate_or_skip
13674
13675         touch $DIR/$tfile
13676         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13677         check_fallocate $DIR/$tfile || error "fallocate failed"
13678 }
13679 run_test 150b "Verify fallocate (prealloc) functionality"
13680
13681 test_150bb() {
13682         check_set_fallocate_or_skip
13683
13684         touch $DIR/$tfile
13685         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13686         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13687         > $DIR/$tfile
13688         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13689         # precomputed md5sum for 20MB of zeroes
13690         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13691         local sum=($(md5sum $DIR/$tfile))
13692
13693         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13694
13695         check_set_fallocate 1
13696
13697         > $DIR/$tfile
13698         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13699         sum=($(md5sum $DIR/$tfile))
13700
13701         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13702 }
13703 run_test 150bb "Verify fallocate modes both zero space"
13704
13705 test_150c() {
13706         check_set_fallocate_or_skip
13707
13708         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13709         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13710         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13711         sync; sync_all_data
13712         cancel_lru_locks $OSC
13713         sleep 5
13714         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13715         want=$((OSTCOUNT * 1048576))
13716
13717         # Must allocate all requested space, not more than 5% extra
13718         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13719                 error "bytes $bytes is not $want"
13720
13721         rm -f $DIR/$tfile
13722         # verify fallocate on PFL file
13723         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13724                 error "Create $DIR/$tfile failed"
13725         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13726                         error "fallocate failed"
13727         sync; sync_all_data
13728         cancel_lru_locks $OSC
13729         sleep 5
13730         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13731         local want=$((1024 * 1048576))
13732
13733         # Must allocate all requested space, not more than 5% extra
13734         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13735                 error "bytes $bytes is not $want"
13736 }
13737 run_test 150c "Verify fallocate Size and Blocks"
13738
13739 test_150d() {
13740         check_set_fallocate_or_skip
13741
13742         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13743         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13744         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13745         sync; sync_all_data
13746         cancel_lru_locks $OSC
13747         sleep 5
13748         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13749         local want=$((OSTCOUNT * 1048576))
13750
13751         # Must allocate all requested space, not more than 5% extra
13752         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13753                 error "bytes $bytes is not $want"
13754 }
13755 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13756
13757 test_150e() {
13758         check_set_fallocate_or_skip
13759
13760         echo "df before:"
13761         $LFS df
13762         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13763         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13764                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13765
13766         # Find OST with Minimum Size
13767         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13768                        sort -un | head -1)
13769
13770         # Get 100MB per OST of the available space to reduce run time
13771         # else 60% of the available space if we are running SLOW tests
13772         if [ $SLOW == "no" ]; then
13773                 local space=$((1024 * 100 * OSTCOUNT))
13774         else
13775                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13776         fi
13777
13778         fallocate -l${space}k $DIR/$tfile ||
13779                 error "fallocate ${space}k $DIR/$tfile failed"
13780         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13781
13782         # get size immediately after fallocate. This should be correctly
13783         # updated
13784         local size=$(stat -c '%s' $DIR/$tfile)
13785         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13786
13787         # Sleep for a while for statfs to get updated. And not pull from cache.
13788         sleep 2
13789
13790         echo "df after fallocate:"
13791         $LFS df
13792
13793         (( size / 1024 == space )) || error "size $size != requested $space"
13794         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13795                 error "used $used < space $space"
13796
13797         rm $DIR/$tfile || error "rm failed"
13798         sync
13799         wait_delete_completed
13800
13801         echo "df after unlink:"
13802         $LFS df
13803 }
13804 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13805
13806 #LU-2902 roc_hit was not able to read all values from lproc
13807 function roc_hit_init() {
13808         local list=$(comma_list $(osts_nodes))
13809         local dir=$DIR/$tdir-check
13810         local file=$dir/$tfile
13811         local BEFORE
13812         local AFTER
13813         local idx
13814
13815         test_mkdir $dir
13816         #use setstripe to do a write to every ost
13817         for i in $(seq 0 $((OSTCOUNT-1))); do
13818                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13819                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13820                 idx=$(printf %04x $i)
13821                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13822                         awk '$1 == "cache_access" {sum += $7}
13823                                 END { printf("%0.0f", sum) }')
13824
13825                 cancel_lru_locks osc
13826                 cat $file >/dev/null
13827
13828                 AFTER=$(get_osd_param $list *OST*$idx stats |
13829                         awk '$1 == "cache_access" {sum += $7}
13830                                 END { printf("%0.0f", sum) }')
13831
13832                 echo BEFORE:$BEFORE AFTER:$AFTER
13833                 if ! let "AFTER - BEFORE == 4"; then
13834                         rm -rf $dir
13835                         error "roc_hit is not safe to use"
13836                 fi
13837                 rm $file
13838         done
13839
13840         rm -rf $dir
13841 }
13842
13843 function roc_hit() {
13844         local list=$(comma_list $(osts_nodes))
13845         echo $(get_osd_param $list '' stats |
13846                 awk '$1 == "cache_hit" {sum += $7}
13847                         END { printf("%0.0f", sum) }')
13848 }
13849
13850 function set_cache() {
13851         local on=1
13852
13853         if [ "$2" == "off" ]; then
13854                 on=0;
13855         fi
13856         local list=$(comma_list $(osts_nodes))
13857         set_osd_param $list '' $1_cache_enable $on
13858
13859         cancel_lru_locks osc
13860 }
13861
13862 test_151() {
13863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13864         remote_ost_nodsh && skip "remote OST with nodsh"
13865
13866         local CPAGES=3
13867         local list=$(comma_list $(osts_nodes))
13868
13869         # check whether obdfilter is cache capable at all
13870         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13871                 skip "not cache-capable obdfilter"
13872         fi
13873
13874         # check cache is enabled on all obdfilters
13875         if get_osd_param $list '' read_cache_enable | grep 0; then
13876                 skip "oss cache is disabled"
13877         fi
13878
13879         set_osd_param $list '' writethrough_cache_enable 1
13880
13881         # check write cache is enabled on all obdfilters
13882         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13883                 skip "oss write cache is NOT enabled"
13884         fi
13885
13886         roc_hit_init
13887
13888         #define OBD_FAIL_OBD_NO_LRU  0x609
13889         do_nodes $list $LCTL set_param fail_loc=0x609
13890
13891         # pages should be in the case right after write
13892         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13893                 error "dd failed"
13894
13895         local BEFORE=$(roc_hit)
13896         cancel_lru_locks osc
13897         cat $DIR/$tfile >/dev/null
13898         local AFTER=$(roc_hit)
13899
13900         do_nodes $list $LCTL set_param fail_loc=0
13901
13902         if ! let "AFTER - BEFORE == CPAGES"; then
13903                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13904         fi
13905
13906         cancel_lru_locks osc
13907         # invalidates OST cache
13908         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13909         set_osd_param $list '' read_cache_enable 0
13910         cat $DIR/$tfile >/dev/null
13911
13912         # now data shouldn't be found in the cache
13913         BEFORE=$(roc_hit)
13914         cancel_lru_locks osc
13915         cat $DIR/$tfile >/dev/null
13916         AFTER=$(roc_hit)
13917         if let "AFTER - BEFORE != 0"; then
13918                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13919         fi
13920
13921         set_osd_param $list '' read_cache_enable 1
13922         rm -f $DIR/$tfile
13923 }
13924 run_test 151 "test cache on oss and controls ==============================="
13925
13926 test_152() {
13927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13928
13929         local TF="$TMP/$tfile"
13930
13931         # simulate ENOMEM during write
13932 #define OBD_FAIL_OST_NOMEM      0x226
13933         lctl set_param fail_loc=0x80000226
13934         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13935         cp $TF $DIR/$tfile
13936         sync || error "sync failed"
13937         lctl set_param fail_loc=0
13938
13939         # discard client's cache
13940         cancel_lru_locks osc
13941
13942         # simulate ENOMEM during read
13943         lctl set_param fail_loc=0x80000226
13944         cmp $TF $DIR/$tfile || error "cmp failed"
13945         lctl set_param fail_loc=0
13946
13947         rm -f $TF
13948 }
13949 run_test 152 "test read/write with enomem ============================"
13950
13951 test_153() {
13952         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13953 }
13954 run_test 153 "test if fdatasync does not crash ======================="
13955
13956 dot_lustre_fid_permission_check() {
13957         local fid=$1
13958         local ffid=$MOUNT/.lustre/fid/$fid
13959         local test_dir=$2
13960
13961         echo "stat fid $fid"
13962         stat $ffid > /dev/null || error "stat $ffid failed."
13963         echo "touch fid $fid"
13964         touch $ffid || error "touch $ffid failed."
13965         echo "write to fid $fid"
13966         cat /etc/hosts > $ffid || error "write $ffid failed."
13967         echo "read fid $fid"
13968         diff /etc/hosts $ffid || error "read $ffid failed."
13969         echo "append write to fid $fid"
13970         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13971         echo "rename fid $fid"
13972         mv $ffid $test_dir/$tfile.1 &&
13973                 error "rename $ffid to $tfile.1 should fail."
13974         touch $test_dir/$tfile.1
13975         mv $test_dir/$tfile.1 $ffid &&
13976                 error "rename $tfile.1 to $ffid should fail."
13977         rm -f $test_dir/$tfile.1
13978         echo "truncate fid $fid"
13979         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13980         echo "link fid $fid"
13981         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13982         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13983                 echo "setfacl fid $fid"
13984                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13985                 echo "getfacl fid $fid"
13986                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13987         fi
13988         echo "unlink fid $fid"
13989         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13990         echo "mknod fid $fid"
13991         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13992
13993         fid=[0xf00000400:0x1:0x0]
13994         ffid=$MOUNT/.lustre/fid/$fid
13995
13996         echo "stat non-exist fid $fid"
13997         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13998         echo "write to non-exist fid $fid"
13999         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14000         echo "link new fid $fid"
14001         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14002
14003         mkdir -p $test_dir/$tdir
14004         touch $test_dir/$tdir/$tfile
14005         fid=$($LFS path2fid $test_dir/$tdir)
14006         rc=$?
14007         [ $rc -ne 0 ] &&
14008                 error "error: could not get fid for $test_dir/$dir/$tfile."
14009
14010         ffid=$MOUNT/.lustre/fid/$fid
14011
14012         echo "ls $fid"
14013         ls $ffid > /dev/null || error "ls $ffid failed."
14014         echo "touch $fid/$tfile.1"
14015         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14016
14017         echo "touch $MOUNT/.lustre/fid/$tfile"
14018         touch $MOUNT/.lustre/fid/$tfile && \
14019                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14020
14021         echo "setxattr to $MOUNT/.lustre/fid"
14022         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14023
14024         echo "listxattr for $MOUNT/.lustre/fid"
14025         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14026
14027         echo "delxattr from $MOUNT/.lustre/fid"
14028         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14029
14030         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14031         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14032                 error "touch invalid fid should fail."
14033
14034         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14035         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14036                 error "touch non-normal fid should fail."
14037
14038         echo "rename $tdir to $MOUNT/.lustre/fid"
14039         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14040                 error "rename to $MOUNT/.lustre/fid should fail."
14041
14042         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14043         then            # LU-3547
14044                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14045                 local new_obf_mode=777
14046
14047                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14048                 chmod $new_obf_mode $DIR/.lustre/fid ||
14049                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14050
14051                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14052                 [ $obf_mode -eq $new_obf_mode ] ||
14053                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14054
14055                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14056                 chmod $old_obf_mode $DIR/.lustre/fid ||
14057                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14058         fi
14059
14060         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14061         fid=$($LFS path2fid $test_dir/$tfile-2)
14062
14063         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14064         then # LU-5424
14065                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14066                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14067                         error "create lov data thru .lustre failed"
14068         fi
14069         echo "cp /etc/passwd $test_dir/$tfile-2"
14070         cp /etc/passwd $test_dir/$tfile-2 ||
14071                 error "copy to $test_dir/$tfile-2 failed."
14072         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14073         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14074                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14075
14076         rm -rf $test_dir/tfile.lnk
14077         rm -rf $test_dir/$tfile-2
14078 }
14079
14080 test_154A() {
14081         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14082                 skip "Need MDS version at least 2.4.1"
14083
14084         local tf=$DIR/$tfile
14085         touch $tf
14086
14087         local fid=$($LFS path2fid $tf)
14088         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14089
14090         # check that we get the same pathname back
14091         local rootpath
14092         local found
14093         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14094                 echo "$rootpath $fid"
14095                 found=$($LFS fid2path $rootpath "$fid")
14096                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14097                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14098         done
14099
14100         # check wrong root path format
14101         rootpath=$MOUNT"_wrong"
14102         found=$($LFS fid2path $rootpath "$fid")
14103         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14104 }
14105 run_test 154A "lfs path2fid and fid2path basic checks"
14106
14107 test_154B() {
14108         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14109                 skip "Need MDS version at least 2.4.1"
14110
14111         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14112         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14113         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14114         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14115
14116         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14117         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14118
14119         # check that we get the same pathname
14120         echo "PFID: $PFID, name: $name"
14121         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14122         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14123         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14124                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14125
14126         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14127 }
14128 run_test 154B "verify the ll_decode_linkea tool"
14129
14130 test_154a() {
14131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14132         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14133         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14134                 skip "Need MDS version at least 2.2.51"
14135         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14136
14137         cp /etc/hosts $DIR/$tfile
14138
14139         fid=$($LFS path2fid $DIR/$tfile)
14140         rc=$?
14141         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14142
14143         dot_lustre_fid_permission_check "$fid" $DIR ||
14144                 error "dot lustre permission check $fid failed"
14145
14146         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14147
14148         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14149
14150         touch $MOUNT/.lustre/file &&
14151                 error "creation is not allowed under .lustre"
14152
14153         mkdir $MOUNT/.lustre/dir &&
14154                 error "mkdir is not allowed under .lustre"
14155
14156         rm -rf $DIR/$tfile
14157 }
14158 run_test 154a "Open-by-FID"
14159
14160 test_154b() {
14161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14162         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14164         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14165                 skip "Need MDS version at least 2.2.51"
14166
14167         local remote_dir=$DIR/$tdir/remote_dir
14168         local MDTIDX=1
14169         local rc=0
14170
14171         mkdir -p $DIR/$tdir
14172         $LFS mkdir -i $MDTIDX $remote_dir ||
14173                 error "create remote directory failed"
14174
14175         cp /etc/hosts $remote_dir/$tfile
14176
14177         fid=$($LFS path2fid $remote_dir/$tfile)
14178         rc=$?
14179         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14180
14181         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14182                 error "dot lustre permission check $fid failed"
14183         rm -rf $DIR/$tdir
14184 }
14185 run_test 154b "Open-by-FID for remote directory"
14186
14187 test_154c() {
14188         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14189                 skip "Need MDS version at least 2.4.1"
14190
14191         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14192         local FID1=$($LFS path2fid $DIR/$tfile.1)
14193         local FID2=$($LFS path2fid $DIR/$tfile.2)
14194         local FID3=$($LFS path2fid $DIR/$tfile.3)
14195
14196         local N=1
14197         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14198                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14199                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14200                 local want=FID$N
14201                 [ "$FID" = "${!want}" ] ||
14202                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14203                 N=$((N + 1))
14204         done
14205
14206         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14207         do
14208                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14209                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14210                 N=$((N + 1))
14211         done
14212 }
14213 run_test 154c "lfs path2fid and fid2path multiple arguments"
14214
14215 test_154d() {
14216         remote_mds_nodsh && skip "remote MDS with nodsh"
14217         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14218                 skip "Need MDS version at least 2.5.53"
14219
14220         if remote_mds; then
14221                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14222         else
14223                 nid="0@lo"
14224         fi
14225         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14226         local fd
14227         local cmd
14228
14229         rm -f $DIR/$tfile
14230         touch $DIR/$tfile
14231
14232         local fid=$($LFS path2fid $DIR/$tfile)
14233         # Open the file
14234         fd=$(free_fd)
14235         cmd="exec $fd<$DIR/$tfile"
14236         eval $cmd
14237         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14238         echo "$fid_list" | grep "$fid"
14239         rc=$?
14240
14241         cmd="exec $fd>/dev/null"
14242         eval $cmd
14243         if [ $rc -ne 0 ]; then
14244                 error "FID $fid not found in open files list $fid_list"
14245         fi
14246 }
14247 run_test 154d "Verify open file fid"
14248
14249 test_154e()
14250 {
14251         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14252                 skip "Need MDS version at least 2.6.50"
14253
14254         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14255                 error ".lustre returned by readdir"
14256         fi
14257 }
14258 run_test 154e ".lustre is not returned by readdir"
14259
14260 test_154f() {
14261         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14262
14263         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14264         test_mkdir -p -c1 $DIR/$tdir/d
14265         # test dirs inherit from its stripe
14266         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14267         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14268         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14269         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14270         touch $DIR/f
14271
14272         # get fid of parents
14273         local FID0=$($LFS path2fid $DIR/$tdir/d)
14274         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14275         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14276         local FID3=$($LFS path2fid $DIR)
14277
14278         # check that path2fid --parents returns expected <parent_fid>/name
14279         # 1) test for a directory (single parent)
14280         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14281         [ "$parent" == "$FID0/foo1" ] ||
14282                 error "expected parent: $FID0/foo1, got: $parent"
14283
14284         # 2) test for a file with nlink > 1 (multiple parents)
14285         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14286         echo "$parent" | grep -F "$FID1/$tfile" ||
14287                 error "$FID1/$tfile not returned in parent list"
14288         echo "$parent" | grep -F "$FID2/link" ||
14289                 error "$FID2/link not returned in parent list"
14290
14291         # 3) get parent by fid
14292         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14293         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14294         echo "$parent" | grep -F "$FID1/$tfile" ||
14295                 error "$FID1/$tfile not returned in parent list (by fid)"
14296         echo "$parent" | grep -F "$FID2/link" ||
14297                 error "$FID2/link not returned in parent list (by fid)"
14298
14299         # 4) test for entry in root directory
14300         parent=$($LFS path2fid --parents $DIR/f)
14301         echo "$parent" | grep -F "$FID3/f" ||
14302                 error "$FID3/f not returned in parent list"
14303
14304         # 5) test it on root directory
14305         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14306                 error "$MOUNT should not have parents"
14307
14308         # enable xattr caching and check that linkea is correctly updated
14309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14310         save_lustre_params client "llite.*.xattr_cache" > $save
14311         lctl set_param llite.*.xattr_cache 1
14312
14313         # 6.1) linkea update on rename
14314         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14315
14316         # get parents by fid
14317         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14318         # foo1 should no longer be returned in parent list
14319         echo "$parent" | grep -F "$FID1" &&
14320                 error "$FID1 should no longer be in parent list"
14321         # the new path should appear
14322         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14323                 error "$FID2/$tfile.moved is not in parent list"
14324
14325         # 6.2) linkea update on unlink
14326         rm -f $DIR/$tdir/d/foo2/link
14327         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14328         # foo2/link should no longer be returned in parent list
14329         echo "$parent" | grep -F "$FID2/link" &&
14330                 error "$FID2/link should no longer be in parent list"
14331         true
14332
14333         rm -f $DIR/f
14334         restore_lustre_params < $save
14335         rm -f $save
14336 }
14337 run_test 154f "get parent fids by reading link ea"
14338
14339 test_154g()
14340 {
14341         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14342         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14343            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14344                 skip "Need MDS version at least 2.6.92"
14345
14346         mkdir -p $DIR/$tdir
14347         llapi_fid_test -d $DIR/$tdir
14348 }
14349 run_test 154g "various llapi FID tests"
14350
14351 test_155_small_load() {
14352     local temp=$TMP/$tfile
14353     local file=$DIR/$tfile
14354
14355     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14356         error "dd of=$temp bs=6096 count=1 failed"
14357     cp $temp $file
14358     cancel_lru_locks $OSC
14359     cmp $temp $file || error "$temp $file differ"
14360
14361     $TRUNCATE $temp 6000
14362     $TRUNCATE $file 6000
14363     cmp $temp $file || error "$temp $file differ (truncate1)"
14364
14365     echo "12345" >>$temp
14366     echo "12345" >>$file
14367     cmp $temp $file || error "$temp $file differ (append1)"
14368
14369     echo "12345" >>$temp
14370     echo "12345" >>$file
14371     cmp $temp $file || error "$temp $file differ (append2)"
14372
14373     rm -f $temp $file
14374     true
14375 }
14376
14377 test_155_big_load() {
14378         remote_ost_nodsh && skip "remote OST with nodsh"
14379
14380         local temp=$TMP/$tfile
14381         local file=$DIR/$tfile
14382
14383         free_min_max
14384         local cache_size=$(do_facet ost$((MAXI+1)) \
14385                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14386         local large_file_size=$((cache_size * 2))
14387
14388         echo "OSS cache size: $cache_size KB"
14389         echo "Large file size: $large_file_size KB"
14390
14391         [ $MAXV -le $large_file_size ] &&
14392                 skip_env "max available OST size needs > $large_file_size KB"
14393
14394         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14395
14396         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14397                 error "dd of=$temp bs=$large_file_size count=1k failed"
14398         cp $temp $file
14399         ls -lh $temp $file
14400         cancel_lru_locks osc
14401         cmp $temp $file || error "$temp $file differ"
14402
14403         rm -f $temp $file
14404         true
14405 }
14406
14407 save_writethrough() {
14408         local facets=$(get_facets OST)
14409
14410         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14411 }
14412
14413 test_155a() {
14414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14415
14416         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14417
14418         save_writethrough $p
14419
14420         set_cache read on
14421         set_cache writethrough on
14422         test_155_small_load
14423         restore_lustre_params < $p
14424         rm -f $p
14425 }
14426 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14427
14428 test_155b() {
14429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14430
14431         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14432
14433         save_writethrough $p
14434
14435         set_cache read on
14436         set_cache writethrough off
14437         test_155_small_load
14438         restore_lustre_params < $p
14439         rm -f $p
14440 }
14441 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14442
14443 test_155c() {
14444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14445
14446         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14447
14448         save_writethrough $p
14449
14450         set_cache read off
14451         set_cache writethrough on
14452         test_155_small_load
14453         restore_lustre_params < $p
14454         rm -f $p
14455 }
14456 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14457
14458 test_155d() {
14459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14460
14461         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14462
14463         save_writethrough $p
14464
14465         set_cache read off
14466         set_cache writethrough off
14467         test_155_small_load
14468         restore_lustre_params < $p
14469         rm -f $p
14470 }
14471 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14472
14473 test_155e() {
14474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14475
14476         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14477
14478         save_writethrough $p
14479
14480         set_cache read on
14481         set_cache writethrough on
14482         test_155_big_load
14483         restore_lustre_params < $p
14484         rm -f $p
14485 }
14486 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14487
14488 test_155f() {
14489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14490
14491         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14492
14493         save_writethrough $p
14494
14495         set_cache read on
14496         set_cache writethrough off
14497         test_155_big_load
14498         restore_lustre_params < $p
14499         rm -f $p
14500 }
14501 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14502
14503 test_155g() {
14504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14505
14506         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14507
14508         save_writethrough $p
14509
14510         set_cache read off
14511         set_cache writethrough on
14512         test_155_big_load
14513         restore_lustre_params < $p
14514         rm -f $p
14515 }
14516 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14517
14518 test_155h() {
14519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14520
14521         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14522
14523         save_writethrough $p
14524
14525         set_cache read off
14526         set_cache writethrough off
14527         test_155_big_load
14528         restore_lustre_params < $p
14529         rm -f $p
14530 }
14531 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14532
14533 test_156() {
14534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14535         remote_ost_nodsh && skip "remote OST with nodsh"
14536         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14537                 skip "stats not implemented on old servers"
14538         [ "$ost1_FSTYPE" = "zfs" ] &&
14539                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14540
14541         local CPAGES=3
14542         local BEFORE
14543         local AFTER
14544         local file="$DIR/$tfile"
14545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14546
14547         save_writethrough $p
14548         roc_hit_init
14549
14550         log "Turn on read and write cache"
14551         set_cache read on
14552         set_cache writethrough on
14553
14554         log "Write data and read it back."
14555         log "Read should be satisfied from the cache."
14556         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14557         BEFORE=$(roc_hit)
14558         cancel_lru_locks osc
14559         cat $file >/dev/null
14560         AFTER=$(roc_hit)
14561         if ! let "AFTER - BEFORE == CPAGES"; then
14562                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14563         else
14564                 log "cache hits: before: $BEFORE, after: $AFTER"
14565         fi
14566
14567         log "Read again; it should be satisfied from the cache."
14568         BEFORE=$AFTER
14569         cancel_lru_locks osc
14570         cat $file >/dev/null
14571         AFTER=$(roc_hit)
14572         if ! let "AFTER - BEFORE == CPAGES"; then
14573                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14574         else
14575                 log "cache hits:: before: $BEFORE, after: $AFTER"
14576         fi
14577
14578         log "Turn off the read cache and turn on the write cache"
14579         set_cache read off
14580         set_cache writethrough on
14581
14582         log "Read again; it should be satisfied from the cache."
14583         BEFORE=$(roc_hit)
14584         cancel_lru_locks osc
14585         cat $file >/dev/null
14586         AFTER=$(roc_hit)
14587         if ! let "AFTER - BEFORE == CPAGES"; then
14588                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14589         else
14590                 log "cache hits:: before: $BEFORE, after: $AFTER"
14591         fi
14592
14593         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14594                 # > 2.12.56 uses pagecache if cached
14595                 log "Read again; it should not be satisfied from the cache."
14596                 BEFORE=$AFTER
14597                 cancel_lru_locks osc
14598                 cat $file >/dev/null
14599                 AFTER=$(roc_hit)
14600                 if ! let "AFTER - BEFORE == 0"; then
14601                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14602                 else
14603                         log "cache hits:: before: $BEFORE, after: $AFTER"
14604                 fi
14605         fi
14606
14607         log "Write data and read it back."
14608         log "Read should be satisfied from the cache."
14609         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14610         BEFORE=$(roc_hit)
14611         cancel_lru_locks osc
14612         cat $file >/dev/null
14613         AFTER=$(roc_hit)
14614         if ! let "AFTER - BEFORE == CPAGES"; then
14615                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14616         else
14617                 log "cache hits:: before: $BEFORE, after: $AFTER"
14618         fi
14619
14620         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14621                 # > 2.12.56 uses pagecache if cached
14622                 log "Read again; it should not be satisfied from the cache."
14623                 BEFORE=$AFTER
14624                 cancel_lru_locks osc
14625                 cat $file >/dev/null
14626                 AFTER=$(roc_hit)
14627                 if ! let "AFTER - BEFORE == 0"; then
14628                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14629                 else
14630                         log "cache hits:: before: $BEFORE, after: $AFTER"
14631                 fi
14632         fi
14633
14634         log "Turn off read and write cache"
14635         set_cache read off
14636         set_cache writethrough off
14637
14638         log "Write data and read it back"
14639         log "It should not be satisfied from the cache."
14640         rm -f $file
14641         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14642         cancel_lru_locks osc
14643         BEFORE=$(roc_hit)
14644         cat $file >/dev/null
14645         AFTER=$(roc_hit)
14646         if ! let "AFTER - BEFORE == 0"; then
14647                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14648         else
14649                 log "cache hits:: before: $BEFORE, after: $AFTER"
14650         fi
14651
14652         log "Turn on the read cache and turn off the write cache"
14653         set_cache read on
14654         set_cache writethrough off
14655
14656         log "Write data and read it back"
14657         log "It should not be satisfied from the cache."
14658         rm -f $file
14659         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14660         BEFORE=$(roc_hit)
14661         cancel_lru_locks osc
14662         cat $file >/dev/null
14663         AFTER=$(roc_hit)
14664         if ! let "AFTER - BEFORE == 0"; then
14665                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14666         else
14667                 log "cache hits:: before: $BEFORE, after: $AFTER"
14668         fi
14669
14670         log "Read again; it should be satisfied from the cache."
14671         BEFORE=$(roc_hit)
14672         cancel_lru_locks osc
14673         cat $file >/dev/null
14674         AFTER=$(roc_hit)
14675         if ! let "AFTER - BEFORE == CPAGES"; then
14676                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14677         else
14678                 log "cache hits:: before: $BEFORE, after: $AFTER"
14679         fi
14680
14681         restore_lustre_params < $p
14682         rm -f $p $file
14683 }
14684 run_test 156 "Verification of tunables"
14685
14686 test_160a() {
14687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14688         remote_mds_nodsh && skip "remote MDS with nodsh"
14689         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14690                 skip "Need MDS version at least 2.2.0"
14691
14692         changelog_register || error "changelog_register failed"
14693         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14694         changelog_users $SINGLEMDS | grep -q $cl_user ||
14695                 error "User $cl_user not found in changelog_users"
14696
14697         # change something
14698         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14699         changelog_clear 0 || error "changelog_clear failed"
14700         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14701         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14702         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14703         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14704         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14705         rm $DIR/$tdir/pics/desktop.jpg
14706
14707         changelog_dump | tail -10
14708
14709         echo "verifying changelog mask"
14710         changelog_chmask "-MKDIR"
14711         changelog_chmask "-CLOSE"
14712
14713         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14714         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14715
14716         changelog_chmask "+MKDIR"
14717         changelog_chmask "+CLOSE"
14718
14719         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14720         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14721
14722         changelog_dump | tail -10
14723         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14724         CLOSES=$(changelog_dump | grep -c "CLOSE")
14725         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14726         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14727
14728         # verify contents
14729         echo "verifying target fid"
14730         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14731         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14732         [ "$fidc" == "$fidf" ] ||
14733                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14734         echo "verifying parent fid"
14735         # The FID returned from the Changelog may be the directory shard on
14736         # a different MDT, and not the FID returned by path2fid on the parent.
14737         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14738         # since this is what will matter when recreating this file in the tree.
14739         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14740         local pathp=$($LFS fid2path $MOUNT "$fidp")
14741         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14742                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14743
14744         echo "getting records for $cl_user"
14745         changelog_users $SINGLEMDS
14746         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14747         local nclr=3
14748         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14749                 error "changelog_clear failed"
14750         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14751         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14752         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14753                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14754
14755         local min0_rec=$(changelog_users $SINGLEMDS |
14756                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14757         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14758                           awk '{ print $1; exit; }')
14759
14760         changelog_dump | tail -n 5
14761         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14762         [ $first_rec == $((min0_rec + 1)) ] ||
14763                 error "first index should be $min0_rec + 1 not $first_rec"
14764
14765         # LU-3446 changelog index reset on MDT restart
14766         local cur_rec1=$(changelog_users $SINGLEMDS |
14767                          awk '/^current.index:/ { print $NF }')
14768         changelog_clear 0 ||
14769                 error "clear all changelog records for $cl_user failed"
14770         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14771         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14772                 error "Fail to start $SINGLEMDS"
14773         local cur_rec2=$(changelog_users $SINGLEMDS |
14774                          awk '/^current.index:/ { print $NF }')
14775         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14776         [ $cur_rec1 == $cur_rec2 ] ||
14777                 error "current index should be $cur_rec1 not $cur_rec2"
14778
14779         echo "verifying users from this test are deregistered"
14780         changelog_deregister || error "changelog_deregister failed"
14781         changelog_users $SINGLEMDS | grep -q $cl_user &&
14782                 error "User '$cl_user' still in changelog_users"
14783
14784         # lctl get_param -n mdd.*.changelog_users
14785         # current index: 144
14786         # ID    index (idle seconds)
14787         # cl3   144 (2)
14788         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14789                 # this is the normal case where all users were deregistered
14790                 # make sure no new records are added when no users are present
14791                 local last_rec1=$(changelog_users $SINGLEMDS |
14792                                   awk '/^current.index:/ { print $NF }')
14793                 touch $DIR/$tdir/chloe
14794                 local last_rec2=$(changelog_users $SINGLEMDS |
14795                                   awk '/^current.index:/ { print $NF }')
14796                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14797                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14798         else
14799                 # any changelog users must be leftovers from a previous test
14800                 changelog_users $SINGLEMDS
14801                 echo "other changelog users; can't verify off"
14802         fi
14803 }
14804 run_test 160a "changelog sanity"
14805
14806 test_160b() { # LU-3587
14807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14808         remote_mds_nodsh && skip "remote MDS with nodsh"
14809         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14810                 skip "Need MDS version at least 2.2.0"
14811
14812         changelog_register || error "changelog_register failed"
14813         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14814         changelog_users $SINGLEMDS | grep -q $cl_user ||
14815                 error "User '$cl_user' not found in changelog_users"
14816
14817         local longname1=$(str_repeat a 255)
14818         local longname2=$(str_repeat b 255)
14819
14820         cd $DIR
14821         echo "creating very long named file"
14822         touch $longname1 || error "create of '$longname1' failed"
14823         echo "renaming very long named file"
14824         mv $longname1 $longname2
14825
14826         changelog_dump | grep RENME | tail -n 5
14827         rm -f $longname2
14828 }
14829 run_test 160b "Verify that very long rename doesn't crash in changelog"
14830
14831 test_160c() {
14832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14833         remote_mds_nodsh && skip "remote MDS with nodsh"
14834
14835         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14836                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14837                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14838                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14839
14840         local rc=0
14841
14842         # Registration step
14843         changelog_register || error "changelog_register failed"
14844
14845         rm -rf $DIR/$tdir
14846         mkdir -p $DIR/$tdir
14847         $MCREATE $DIR/$tdir/foo_160c
14848         changelog_chmask "-TRUNC"
14849         $TRUNCATE $DIR/$tdir/foo_160c 200
14850         changelog_chmask "+TRUNC"
14851         $TRUNCATE $DIR/$tdir/foo_160c 199
14852         changelog_dump | tail -n 5
14853         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14854         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14855 }
14856 run_test 160c "verify that changelog log catch the truncate event"
14857
14858 test_160d() {
14859         remote_mds_nodsh && skip "remote MDS with nodsh"
14860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14862         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14863                 skip "Need MDS version at least 2.7.60"
14864
14865         # Registration step
14866         changelog_register || error "changelog_register failed"
14867
14868         mkdir -p $DIR/$tdir/migrate_dir
14869         changelog_clear 0 || error "changelog_clear failed"
14870
14871         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14872         changelog_dump | tail -n 5
14873         local migrates=$(changelog_dump | grep -c "MIGRT")
14874         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14875 }
14876 run_test 160d "verify that changelog log catch the migrate event"
14877
14878 test_160e() {
14879         remote_mds_nodsh && skip "remote MDS with nodsh"
14880
14881         # Create a user
14882         changelog_register || error "changelog_register failed"
14883
14884         # Delete a future user (expect fail)
14885         local MDT0=$(facet_svc $SINGLEMDS)
14886         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14887         local rc=$?
14888
14889         if [ $rc -eq 0 ]; then
14890                 error "Deleted non-existant user cl77"
14891         elif [ $rc -ne 2 ]; then
14892                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14893         fi
14894
14895         # Clear to a bad index (1 billion should be safe)
14896         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14897         rc=$?
14898
14899         if [ $rc -eq 0 ]; then
14900                 error "Successfully cleared to invalid CL index"
14901         elif [ $rc -ne 22 ]; then
14902                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14903         fi
14904 }
14905 run_test 160e "changelog negative testing (should return errors)"
14906
14907 test_160f() {
14908         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14909         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14910                 skip "Need MDS version at least 2.10.56"
14911
14912         local mdts=$(comma_list $(mdts_nodes))
14913
14914         # Create a user
14915         changelog_register || error "first changelog_register failed"
14916         changelog_register || error "second changelog_register failed"
14917         local cl_users
14918         declare -A cl_user1
14919         declare -A cl_user2
14920         local user_rec1
14921         local user_rec2
14922         local i
14923
14924         # generate some changelog records to accumulate on each MDT
14925         # use fnv1a because created files should be evenly distributed
14926         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14927                 error "test_mkdir $tdir failed"
14928         log "$(date +%s): creating first files"
14929         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14930                 error "create $DIR/$tdir/$tfile failed"
14931
14932         # check changelogs have been generated
14933         local start=$SECONDS
14934         local idle_time=$((MDSCOUNT * 5 + 5))
14935         local nbcl=$(changelog_dump | wc -l)
14936         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14937
14938         for param in "changelog_max_idle_time=$idle_time" \
14939                      "changelog_gc=1" \
14940                      "changelog_min_gc_interval=2" \
14941                      "changelog_min_free_cat_entries=3"; do
14942                 local MDT0=$(facet_svc $SINGLEMDS)
14943                 local var="${param%=*}"
14944                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14945
14946                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14947                 do_nodes $mdts $LCTL set_param mdd.*.$param
14948         done
14949
14950         # force cl_user2 to be idle (1st part), but also cancel the
14951         # cl_user1 records so that it is not evicted later in the test.
14952         local sleep1=$((idle_time / 2))
14953         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14954         sleep $sleep1
14955
14956         # simulate changelog catalog almost full
14957         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14958         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14959
14960         for i in $(seq $MDSCOUNT); do
14961                 cl_users=(${CL_USERS[mds$i]})
14962                 cl_user1[mds$i]="${cl_users[0]}"
14963                 cl_user2[mds$i]="${cl_users[1]}"
14964
14965                 [ -n "${cl_user1[mds$i]}" ] ||
14966                         error "mds$i: no user registered"
14967                 [ -n "${cl_user2[mds$i]}" ] ||
14968                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14969
14970                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14971                 [ -n "$user_rec1" ] ||
14972                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14973                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14974                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14975                 [ -n "$user_rec2" ] ||
14976                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14977                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14978                      "$user_rec1 + 2 == $user_rec2"
14979                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14980                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14981                               "$user_rec1 + 2, but is $user_rec2"
14982                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14983                 [ -n "$user_rec2" ] ||
14984                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14985                 [ $user_rec1 == $user_rec2 ] ||
14986                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14987                               "$user_rec1, but is $user_rec2"
14988         done
14989
14990         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14991         local sleep2=$((idle_time - (SECONDS - start) + 1))
14992         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14993         sleep $sleep2
14994
14995         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14996         # cl_user1 should be OK because it recently processed records.
14997         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14998         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14999                 error "create $DIR/$tdir/${tfile}b failed"
15000
15001         # ensure gc thread is done
15002         for i in $(mdts_nodes); do
15003                 wait_update $i \
15004                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15005                         error "$i: GC-thread not done"
15006         done
15007
15008         local first_rec
15009         for i in $(seq $MDSCOUNT); do
15010                 # check cl_user1 still registered
15011                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15012                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15013                 # check cl_user2 unregistered
15014                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15015                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15016
15017                 # check changelogs are present and starting at $user_rec1 + 1
15018                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15019                 [ -n "$user_rec1" ] ||
15020                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15021                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15022                             awk '{ print $1; exit; }')
15023
15024                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15025                 [ $((user_rec1 + 1)) == $first_rec ] ||
15026                         error "mds$i: first index should be $user_rec1 + 1, " \
15027                               "but is $first_rec"
15028         done
15029 }
15030 run_test 160f "changelog garbage collect (timestamped users)"
15031
15032 test_160g() {
15033         remote_mds_nodsh && skip "remote MDS with nodsh"
15034         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15035                 skip "Need MDS version at least 2.10.56"
15036
15037         local mdts=$(comma_list $(mdts_nodes))
15038
15039         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15040         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15041
15042         # Create a user
15043         changelog_register || error "first changelog_register failed"
15044         changelog_register || error "second changelog_register failed"
15045         local cl_users
15046         declare -A cl_user1
15047         declare -A cl_user2
15048         local user_rec1
15049         local user_rec2
15050         local i
15051
15052         # generate some changelog records to accumulate on each MDT
15053         # use fnv1a because created files should be evenly distributed
15054         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15055                 error "mkdir $tdir failed"
15056         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15057                 error "create $DIR/$tdir/$tfile failed"
15058
15059         # check changelogs have been generated
15060         local nbcl=$(changelog_dump | wc -l)
15061         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15062
15063         # reduce the max_idle_indexes value to make sure we exceed it
15064         max_ndx=$((nbcl / 2 - 1))
15065
15066         for param in "changelog_max_idle_indexes=$max_ndx" \
15067                      "changelog_gc=1" \
15068                      "changelog_min_gc_interval=2" \
15069                      "changelog_min_free_cat_entries=3"; do
15070                 local MDT0=$(facet_svc $SINGLEMDS)
15071                 local var="${param%=*}"
15072                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15073
15074                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15075                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15076                         error "unable to set mdd.*.$param"
15077         done
15078
15079         # simulate changelog catalog almost full
15080         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15081         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
15082
15083         for i in $(seq $MDSCOUNT); do
15084                 cl_users=(${CL_USERS[mds$i]})
15085                 cl_user1[mds$i]="${cl_users[0]}"
15086                 cl_user2[mds$i]="${cl_users[1]}"
15087
15088                 [ -n "${cl_user1[mds$i]}" ] ||
15089                         error "mds$i: no user registered"
15090                 [ -n "${cl_user2[mds$i]}" ] ||
15091                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15092
15093                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15094                 [ -n "$user_rec1" ] ||
15095                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15096                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15097                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15098                 [ -n "$user_rec2" ] ||
15099                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15100                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15101                      "$user_rec1 + 2 == $user_rec2"
15102                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15103                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15104                               "$user_rec1 + 2, but is $user_rec2"
15105                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15106                 [ -n "$user_rec2" ] ||
15107                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15108                 [ $user_rec1 == $user_rec2 ] ||
15109                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15110                               "$user_rec1, but is $user_rec2"
15111         done
15112
15113         # ensure we are past the previous changelog_min_gc_interval set above
15114         sleep 2
15115
15116         # generate one more changelog to trigger fail_loc
15117         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15118                 error "create $DIR/$tdir/${tfile}bis failed"
15119
15120         # ensure gc thread is done
15121         for i in $(mdts_nodes); do
15122                 wait_update $i \
15123                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15124                         error "$i: GC-thread not done"
15125         done
15126
15127         local first_rec
15128         for i in $(seq $MDSCOUNT); do
15129                 # check cl_user1 still registered
15130                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15131                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15132                 # check cl_user2 unregistered
15133                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15134                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15135
15136                 # check changelogs are present and starting at $user_rec1 + 1
15137                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15138                 [ -n "$user_rec1" ] ||
15139                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15140                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15141                             awk '{ print $1; exit; }')
15142
15143                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15144                 [ $((user_rec1 + 1)) == $first_rec ] ||
15145                         error "mds$i: first index should be $user_rec1 + 1, " \
15146                               "but is $first_rec"
15147         done
15148 }
15149 run_test 160g "changelog garbage collect (old users)"
15150
15151 test_160h() {
15152         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15153         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15154                 skip "Need MDS version at least 2.10.56"
15155
15156         local mdts=$(comma_list $(mdts_nodes))
15157
15158         # Create a user
15159         changelog_register || error "first changelog_register failed"
15160         changelog_register || error "second changelog_register failed"
15161         local cl_users
15162         declare -A cl_user1
15163         declare -A cl_user2
15164         local user_rec1
15165         local user_rec2
15166         local i
15167
15168         # generate some changelog records to accumulate on each MDT
15169         # use fnv1a because created files should be evenly distributed
15170         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15171                 error "test_mkdir $tdir failed"
15172         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15173                 error "create $DIR/$tdir/$tfile failed"
15174
15175         # check changelogs have been generated
15176         local nbcl=$(changelog_dump | wc -l)
15177         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15178
15179         for param in "changelog_max_idle_time=10" \
15180                      "changelog_gc=1" \
15181                      "changelog_min_gc_interval=2"; do
15182                 local MDT0=$(facet_svc $SINGLEMDS)
15183                 local var="${param%=*}"
15184                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15185
15186                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15187                 do_nodes $mdts $LCTL set_param mdd.*.$param
15188         done
15189
15190         # force cl_user2 to be idle (1st part)
15191         sleep 9
15192
15193         for i in $(seq $MDSCOUNT); do
15194                 cl_users=(${CL_USERS[mds$i]})
15195                 cl_user1[mds$i]="${cl_users[0]}"
15196                 cl_user2[mds$i]="${cl_users[1]}"
15197
15198                 [ -n "${cl_user1[mds$i]}" ] ||
15199                         error "mds$i: no user registered"
15200                 [ -n "${cl_user2[mds$i]}" ] ||
15201                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15202
15203                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15204                 [ -n "$user_rec1" ] ||
15205                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15206                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15207                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15208                 [ -n "$user_rec2" ] ||
15209                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15210                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15211                      "$user_rec1 + 2 == $user_rec2"
15212                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15213                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15214                               "$user_rec1 + 2, but is $user_rec2"
15215                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15216                 [ -n "$user_rec2" ] ||
15217                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15218                 [ $user_rec1 == $user_rec2 ] ||
15219                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15220                               "$user_rec1, but is $user_rec2"
15221         done
15222
15223         # force cl_user2 to be idle (2nd part) and to reach
15224         # changelog_max_idle_time
15225         sleep 2
15226
15227         # force each GC-thread start and block then
15228         # one per MDT/MDD, set fail_val accordingly
15229         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15230         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15231
15232         # generate more changelogs to trigger fail_loc
15233         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15234                 error "create $DIR/$tdir/${tfile}bis failed"
15235
15236         # stop MDT to stop GC-thread, should be done in back-ground as it will
15237         # block waiting for the thread to be released and exit
15238         declare -A stop_pids
15239         for i in $(seq $MDSCOUNT); do
15240                 stop mds$i &
15241                 stop_pids[mds$i]=$!
15242         done
15243
15244         for i in $(mdts_nodes); do
15245                 local facet
15246                 local nb=0
15247                 local facets=$(facets_up_on_host $i)
15248
15249                 for facet in ${facets//,/ }; do
15250                         if [[ $facet == mds* ]]; then
15251                                 nb=$((nb + 1))
15252                         fi
15253                 done
15254                 # ensure each MDS's gc threads are still present and all in "R"
15255                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15256                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15257                         error "$i: expected $nb GC-thread"
15258                 wait_update $i \
15259                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15260                         "R" 20 ||
15261                         error "$i: GC-thread not found in R-state"
15262                 # check umounts of each MDT on MDS have reached kthread_stop()
15263                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15264                         error "$i: expected $nb umount"
15265                 wait_update $i \
15266                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15267                         error "$i: umount not found in D-state"
15268         done
15269
15270         # release all GC-threads
15271         do_nodes $mdts $LCTL set_param fail_loc=0
15272
15273         # wait for MDT stop to complete
15274         for i in $(seq $MDSCOUNT); do
15275                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15276         done
15277
15278         # XXX
15279         # may try to check if any orphan changelog records are present
15280         # via ldiskfs/zfs and llog_reader...
15281
15282         # re-start/mount MDTs
15283         for i in $(seq $MDSCOUNT); do
15284                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15285                         error "Fail to start mds$i"
15286         done
15287
15288         local first_rec
15289         for i in $(seq $MDSCOUNT); do
15290                 # check cl_user1 still registered
15291                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15292                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15293                 # check cl_user2 unregistered
15294                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15295                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15296
15297                 # check changelogs are present and starting at $user_rec1 + 1
15298                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15299                 [ -n "$user_rec1" ] ||
15300                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15301                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15302                             awk '{ print $1; exit; }')
15303
15304                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15305                 [ $((user_rec1 + 1)) == $first_rec ] ||
15306                         error "mds$i: first index should be $user_rec1 + 1, " \
15307                               "but is $first_rec"
15308         done
15309 }
15310 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15311               "during mount"
15312
15313 test_160i() {
15314
15315         local mdts=$(comma_list $(mdts_nodes))
15316
15317         changelog_register || error "first changelog_register failed"
15318
15319         # generate some changelog records to accumulate on each MDT
15320         # use fnv1a because created files should be evenly distributed
15321         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15322                 error "mkdir $tdir failed"
15323         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15324                 error "create $DIR/$tdir/$tfile failed"
15325
15326         # check changelogs have been generated
15327         local nbcl=$(changelog_dump | wc -l)
15328         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15329
15330         # simulate race between register and unregister
15331         # XXX as fail_loc is set per-MDS, with DNE configs the race
15332         # simulation will only occur for one MDT per MDS and for the
15333         # others the normal race scenario will take place
15334         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15335         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15336         do_nodes $mdts $LCTL set_param fail_val=1
15337
15338         # unregister 1st user
15339         changelog_deregister &
15340         local pid1=$!
15341         # wait some time for deregister work to reach race rdv
15342         sleep 2
15343         # register 2nd user
15344         changelog_register || error "2nd user register failed"
15345
15346         wait $pid1 || error "1st user deregister failed"
15347
15348         local i
15349         local last_rec
15350         declare -A LAST_REC
15351         for i in $(seq $MDSCOUNT); do
15352                 if changelog_users mds$i | grep "^cl"; then
15353                         # make sure new records are added with one user present
15354                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15355                                           awk '/^current.index:/ { print $NF }')
15356                 else
15357                         error "mds$i has no user registered"
15358                 fi
15359         done
15360
15361         # generate more changelog records to accumulate on each MDT
15362         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15363                 error "create $DIR/$tdir/${tfile}bis failed"
15364
15365         for i in $(seq $MDSCOUNT); do
15366                 last_rec=$(changelog_users $SINGLEMDS |
15367                            awk '/^current.index:/ { print $NF }')
15368                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15369                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15370                         error "changelogs are off on mds$i"
15371         done
15372 }
15373 run_test 160i "changelog user register/unregister race"
15374
15375 test_160j() {
15376         remote_mds_nodsh && skip "remote MDS with nodsh"
15377         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15378                 skip "Need MDS version at least 2.12.56"
15379
15380         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15381         stack_trap "umount $MOUNT2" EXIT
15382
15383         changelog_register || error "first changelog_register failed"
15384         stack_trap "changelog_deregister" EXIT
15385
15386         # generate some changelog
15387         # use fnv1a because created files should be evenly distributed
15388         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15389                 error "mkdir $tdir failed"
15390         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15391                 error "create $DIR/$tdir/${tfile}bis failed"
15392
15393         # open the changelog device
15394         exec 3>/dev/changelog-$FSNAME-MDT0000
15395         stack_trap "exec 3>&-" EXIT
15396         exec 4</dev/changelog-$FSNAME-MDT0000
15397         stack_trap "exec 4<&-" EXIT
15398
15399         # umount the first lustre mount
15400         umount $MOUNT
15401         stack_trap "mount_client $MOUNT" EXIT
15402
15403         # read changelog, which may or may not fail, but should not crash
15404         cat <&4 >/dev/null
15405
15406         # clear changelog
15407         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15408         changelog_users $SINGLEMDS | grep -q $cl_user ||
15409                 error "User $cl_user not found in changelog_users"
15410
15411         printf 'clear:'$cl_user':0' >&3
15412 }
15413 run_test 160j "client can be umounted while its chanangelog is being used"
15414
15415 test_160k() {
15416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15417         remote_mds_nodsh && skip "remote MDS with nodsh"
15418
15419         mkdir -p $DIR/$tdir/1/1
15420
15421         changelog_register || error "changelog_register failed"
15422         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15423
15424         changelog_users $SINGLEMDS | grep -q $cl_user ||
15425                 error "User '$cl_user' not found in changelog_users"
15426 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15427         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15428         rmdir $DIR/$tdir/1/1 & sleep 1
15429         mkdir $DIR/$tdir/2
15430         touch $DIR/$tdir/2/2
15431         rm -rf $DIR/$tdir/2
15432
15433         wait
15434         sleep 4
15435
15436         changelog_dump | grep rmdir || error "rmdir not recorded"
15437
15438         rm -rf $DIR/$tdir
15439         changelog_deregister
15440 }
15441 run_test 160k "Verify that changelog records are not lost"
15442
15443 # Verifies that a file passed as a parameter has recently had an operation
15444 # performed on it that has generated an MTIME changelog which contains the
15445 # correct parent FID. As files might reside on a different MDT from the
15446 # parent directory in DNE configurations, the FIDs are translated to paths
15447 # before being compared, which should be identical
15448 compare_mtime_changelog() {
15449         local file="${1}"
15450         local mdtidx
15451         local mtime
15452         local cl_fid
15453         local pdir
15454         local dir
15455
15456         mdtidx=$($LFS getstripe --mdt-index $file)
15457         mdtidx=$(printf "%04x" $mdtidx)
15458
15459         # Obtain the parent FID from the MTIME changelog
15460         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15461         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15462
15463         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15464         [ -z "$cl_fid" ] && error "parent FID not present"
15465
15466         # Verify that the path for the parent FID is the same as the path for
15467         # the test directory
15468         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15469
15470         dir=$(dirname $1)
15471
15472         [[ "${pdir%/}" == "$dir" ]] ||
15473                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15474 }
15475
15476 test_160l() {
15477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15478
15479         remote_mds_nodsh && skip "remote MDS with nodsh"
15480         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15481                 skip "Need MDS version at least 2.13.55"
15482
15483         local cl_user
15484
15485         changelog_register || error "changelog_register failed"
15486         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15487
15488         changelog_users $SINGLEMDS | grep -q $cl_user ||
15489                 error "User '$cl_user' not found in changelog_users"
15490
15491         # Clear some types so that MTIME changelogs are generated
15492         changelog_chmask "-CREAT"
15493         changelog_chmask "-CLOSE"
15494
15495         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15496
15497         # Test CL_MTIME during setattr
15498         touch $DIR/$tdir/$tfile
15499         compare_mtime_changelog $DIR/$tdir/$tfile
15500
15501         # Test CL_MTIME during close
15502         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15503         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15504 }
15505 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15506
15507 test_161a() {
15508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15509
15510         test_mkdir -c1 $DIR/$tdir
15511         cp /etc/hosts $DIR/$tdir/$tfile
15512         test_mkdir -c1 $DIR/$tdir/foo1
15513         test_mkdir -c1 $DIR/$tdir/foo2
15514         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15515         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15516         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15517         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15518         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15519         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15520                 $LFS fid2path $DIR $FID
15521                 error "bad link ea"
15522         fi
15523         # middle
15524         rm $DIR/$tdir/foo2/zachary
15525         # last
15526         rm $DIR/$tdir/foo2/thor
15527         # first
15528         rm $DIR/$tdir/$tfile
15529         # rename
15530         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15531         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15532                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15533         rm $DIR/$tdir/foo2/maggie
15534
15535         # overflow the EA
15536         local longname=$tfile.avg_len_is_thirty_two_
15537         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15538                 error_noexit 'failed to unlink many hardlinks'" EXIT
15539         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15540                 error "failed to hardlink many files"
15541         links=$($LFS fid2path $DIR $FID | wc -l)
15542         echo -n "${links}/1000 links in link EA"
15543         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15544 }
15545 run_test 161a "link ea sanity"
15546
15547 test_161b() {
15548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15549         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15550
15551         local MDTIDX=1
15552         local remote_dir=$DIR/$tdir/remote_dir
15553
15554         mkdir -p $DIR/$tdir
15555         $LFS mkdir -i $MDTIDX $remote_dir ||
15556                 error "create remote directory failed"
15557
15558         cp /etc/hosts $remote_dir/$tfile
15559         mkdir -p $remote_dir/foo1
15560         mkdir -p $remote_dir/foo2
15561         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15562         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15563         ln $remote_dir/$tfile $remote_dir/foo1/luna
15564         ln $remote_dir/$tfile $remote_dir/foo2/thor
15565
15566         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15567                      tr -d ']')
15568         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15569                 $LFS fid2path $DIR $FID
15570                 error "bad link ea"
15571         fi
15572         # middle
15573         rm $remote_dir/foo2/zachary
15574         # last
15575         rm $remote_dir/foo2/thor
15576         # first
15577         rm $remote_dir/$tfile
15578         # rename
15579         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15580         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15581         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15582                 $LFS fid2path $DIR $FID
15583                 error "bad link rename"
15584         fi
15585         rm $remote_dir/foo2/maggie
15586
15587         # overflow the EA
15588         local longname=filename_avg_len_is_thirty_two_
15589         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15590                 error "failed to hardlink many files"
15591         links=$($LFS fid2path $DIR $FID | wc -l)
15592         echo -n "${links}/1000 links in link EA"
15593         [[ ${links} -gt 60 ]] ||
15594                 error "expected at least 60 links in link EA"
15595         unlinkmany $remote_dir/foo2/$longname 1000 ||
15596         error "failed to unlink many hardlinks"
15597 }
15598 run_test 161b "link ea sanity under remote directory"
15599
15600 test_161c() {
15601         remote_mds_nodsh && skip "remote MDS with nodsh"
15602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15603         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15604                 skip "Need MDS version at least 2.1.5"
15605
15606         # define CLF_RENAME_LAST 0x0001
15607         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15608         changelog_register || error "changelog_register failed"
15609
15610         rm -rf $DIR/$tdir
15611         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15612         touch $DIR/$tdir/foo_161c
15613         touch $DIR/$tdir/bar_161c
15614         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15615         changelog_dump | grep RENME | tail -n 5
15616         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15617         changelog_clear 0 || error "changelog_clear failed"
15618         if [ x$flags != "x0x1" ]; then
15619                 error "flag $flags is not 0x1"
15620         fi
15621
15622         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15623         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15624         touch $DIR/$tdir/foo_161c
15625         touch $DIR/$tdir/bar_161c
15626         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15627         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15628         changelog_dump | grep RENME | tail -n 5
15629         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15630         changelog_clear 0 || error "changelog_clear failed"
15631         if [ x$flags != "x0x0" ]; then
15632                 error "flag $flags is not 0x0"
15633         fi
15634         echo "rename overwrite a target having nlink > 1," \
15635                 "changelog record has flags of $flags"
15636
15637         # rename doesn't overwrite a target (changelog flag 0x0)
15638         touch $DIR/$tdir/foo_161c
15639         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15640         changelog_dump | grep RENME | tail -n 5
15641         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15642         changelog_clear 0 || error "changelog_clear failed"
15643         if [ x$flags != "x0x0" ]; then
15644                 error "flag $flags is not 0x0"
15645         fi
15646         echo "rename doesn't overwrite a target," \
15647                 "changelog record has flags of $flags"
15648
15649         # define CLF_UNLINK_LAST 0x0001
15650         # unlink a file having nlink = 1 (changelog flag 0x1)
15651         rm -f $DIR/$tdir/foo2_161c
15652         changelog_dump | grep UNLNK | tail -n 5
15653         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15654         changelog_clear 0 || error "changelog_clear failed"
15655         if [ x$flags != "x0x1" ]; then
15656                 error "flag $flags is not 0x1"
15657         fi
15658         echo "unlink a file having nlink = 1," \
15659                 "changelog record has flags of $flags"
15660
15661         # unlink a file having nlink > 1 (changelog flag 0x0)
15662         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15663         rm -f $DIR/$tdir/foobar_161c
15664         changelog_dump | grep UNLNK | tail -n 5
15665         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15666         changelog_clear 0 || error "changelog_clear failed"
15667         if [ x$flags != "x0x0" ]; then
15668                 error "flag $flags is not 0x0"
15669         fi
15670         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15671 }
15672 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15673
15674 test_161d() {
15675         remote_mds_nodsh && skip "remote MDS with nodsh"
15676         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15677
15678         local pid
15679         local fid
15680
15681         changelog_register || error "changelog_register failed"
15682
15683         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15684         # interfer with $MOUNT/.lustre/fid/ access
15685         mkdir $DIR/$tdir
15686         [[ $? -eq 0 ]] || error "mkdir failed"
15687
15688         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15689         $LCTL set_param fail_loc=0x8000140c
15690         # 5s pause
15691         $LCTL set_param fail_val=5
15692
15693         # create file
15694         echo foofoo > $DIR/$tdir/$tfile &
15695         pid=$!
15696
15697         # wait for create to be delayed
15698         sleep 2
15699
15700         ps -p $pid
15701         [[ $? -eq 0 ]] || error "create should be blocked"
15702
15703         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15704         stack_trap "rm -f $tempfile"
15705         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15706         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15707         # some delay may occur during ChangeLog publishing and file read just
15708         # above, that could allow file write to happen finally
15709         [[ -s $tempfile ]] && echo "file should be empty"
15710
15711         $LCTL set_param fail_loc=0
15712
15713         wait $pid
15714         [[ $? -eq 0 ]] || error "create failed"
15715 }
15716 run_test 161d "create with concurrent .lustre/fid access"
15717
15718 check_path() {
15719         local expected="$1"
15720         shift
15721         local fid="$2"
15722
15723         local path
15724         path=$($LFS fid2path "$@")
15725         local rc=$?
15726
15727         if [ $rc -ne 0 ]; then
15728                 error "path looked up of '$expected' failed: rc=$rc"
15729         elif [ "$path" != "$expected" ]; then
15730                 error "path looked up '$path' instead of '$expected'"
15731         else
15732                 echo "FID '$fid' resolves to path '$path' as expected"
15733         fi
15734 }
15735
15736 test_162a() { # was test_162
15737         test_mkdir -p -c1 $DIR/$tdir/d2
15738         touch $DIR/$tdir/d2/$tfile
15739         touch $DIR/$tdir/d2/x1
15740         touch $DIR/$tdir/d2/x2
15741         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15742         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15743         # regular file
15744         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15745         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15746
15747         # softlink
15748         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15749         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15750         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15751
15752         # softlink to wrong file
15753         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15754         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15755         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15756
15757         # hardlink
15758         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15759         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15760         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15761         # fid2path dir/fsname should both work
15762         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15763         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15764
15765         # hardlink count: check that there are 2 links
15766         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15767         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15768
15769         # hardlink indexing: remove the first link
15770         rm $DIR/$tdir/d2/p/q/r/hlink
15771         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15772 }
15773 run_test 162a "path lookup sanity"
15774
15775 test_162b() {
15776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15777         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15778
15779         mkdir $DIR/$tdir
15780         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15781                                 error "create striped dir failed"
15782
15783         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15784                                         tail -n 1 | awk '{print $2}')
15785         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15786
15787         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15788         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15789
15790         # regular file
15791         for ((i=0;i<5;i++)); do
15792                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15793                         error "get fid for f$i failed"
15794                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15795
15796                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15797                         error "get fid for d$i failed"
15798                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15799         done
15800
15801         return 0
15802 }
15803 run_test 162b "striped directory path lookup sanity"
15804
15805 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15806 test_162c() {
15807         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15808                 skip "Need MDS version at least 2.7.51"
15809
15810         local lpath=$tdir.local
15811         local rpath=$tdir.remote
15812
15813         test_mkdir $DIR/$lpath
15814         test_mkdir $DIR/$rpath
15815
15816         for ((i = 0; i <= 101; i++)); do
15817                 lpath="$lpath/$i"
15818                 mkdir $DIR/$lpath
15819                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15820                         error "get fid for local directory $DIR/$lpath failed"
15821                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15822
15823                 rpath="$rpath/$i"
15824                 test_mkdir $DIR/$rpath
15825                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15826                         error "get fid for remote directory $DIR/$rpath failed"
15827                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15828         done
15829
15830         return 0
15831 }
15832 run_test 162c "fid2path works with paths 100 or more directories deep"
15833
15834 oalr_event_count() {
15835         local event="${1}"
15836         local trace="${2}"
15837
15838         awk -v name="${FSNAME}-OST0000" \
15839             -v event="${event}" \
15840             '$1 == "TRACE" && $2 == event && $3 == name' \
15841             "${trace}" |
15842         wc -l
15843 }
15844
15845 oalr_expect_event_count() {
15846         local event="${1}"
15847         local trace="${2}"
15848         local expect="${3}"
15849         local count
15850
15851         count=$(oalr_event_count "${event}" "${trace}")
15852         if ((count == expect)); then
15853                 return 0
15854         fi
15855
15856         error_noexit "${event} event count was '${count}', expected ${expect}"
15857         cat "${trace}" >&2
15858         exit 1
15859 }
15860
15861 cleanup_165() {
15862         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15863         stop ost1
15864         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15865 }
15866
15867 setup_165() {
15868         sync # Flush previous IOs so we can count log entries.
15869         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15870         stack_trap cleanup_165 EXIT
15871 }
15872
15873 test_165a() {
15874         local trace="/tmp/${tfile}.trace"
15875         local rc
15876         local count
15877
15878         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15879                 skip "OFD access log unsupported"
15880
15881         setup_165
15882         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15883         sleep 5
15884
15885         do_facet ost1 ofd_access_log_reader --list
15886         stop ost1
15887
15888         do_facet ost1 killall -TERM ofd_access_log_reader
15889         wait
15890         rc=$?
15891
15892         if ((rc != 0)); then
15893                 error "ofd_access_log_reader exited with rc = '${rc}'"
15894         fi
15895
15896         # Parse trace file for discovery events:
15897         oalr_expect_event_count alr_log_add "${trace}" 1
15898         oalr_expect_event_count alr_log_eof "${trace}" 1
15899         oalr_expect_event_count alr_log_free "${trace}" 1
15900 }
15901 run_test 165a "ofd access log discovery"
15902
15903 test_165b() {
15904         local trace="/tmp/${tfile}.trace"
15905         local file="${DIR}/${tfile}"
15906         local pfid1
15907         local pfid2
15908         local -a entry
15909         local rc
15910         local count
15911         local size
15912         local flags
15913
15914         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15915                 skip "OFD access log unsupported"
15916
15917         setup_165
15918         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15919         sleep 5
15920
15921         do_facet ost1 ofd_access_log_reader --list
15922
15923         lfs setstripe -c 1 -i 0 "${file}"
15924         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15925                 error "cannot create '${file}'"
15926
15927         sleep 5
15928         do_facet ost1 killall -TERM ofd_access_log_reader
15929         wait
15930         rc=$?
15931
15932         if ((rc != 0)); then
15933                 error "ofd_access_log_reader exited with rc = '${rc}'"
15934         fi
15935
15936         oalr_expect_event_count alr_log_entry "${trace}" 1
15937
15938         pfid1=$($LFS path2fid "${file}")
15939
15940         # 1     2             3   4    5     6   7    8    9     10
15941         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15942         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15943
15944         echo "entry = '${entry[*]}'" >&2
15945
15946         pfid2=${entry[4]}
15947         if [[ "${pfid1}" != "${pfid2}" ]]; then
15948                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15949         fi
15950
15951         size=${entry[8]}
15952         if ((size != 1048576)); then
15953                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15954         fi
15955
15956         flags=${entry[10]}
15957         if [[ "${flags}" != "w" ]]; then
15958                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15959         fi
15960
15961         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15962         sleep 5
15963
15964         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15965                 error "cannot read '${file}'"
15966         sleep 5
15967
15968         do_facet ost1 killall -TERM ofd_access_log_reader
15969         wait
15970         rc=$?
15971
15972         if ((rc != 0)); then
15973                 error "ofd_access_log_reader exited with rc = '${rc}'"
15974         fi
15975
15976         oalr_expect_event_count alr_log_entry "${trace}" 1
15977
15978         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15979         echo "entry = '${entry[*]}'" >&2
15980
15981         pfid2=${entry[4]}
15982         if [[ "${pfid1}" != "${pfid2}" ]]; then
15983                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15984         fi
15985
15986         size=${entry[8]}
15987         if ((size != 524288)); then
15988                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15989         fi
15990
15991         flags=${entry[10]}
15992         if [[ "${flags}" != "r" ]]; then
15993                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15994         fi
15995 }
15996 run_test 165b "ofd access log entries are produced and consumed"
15997
15998 test_165c() {
15999         local trace="/tmp/${tfile}.trace"
16000         local file="${DIR}/${tdir}/${tfile}"
16001
16002         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16003                 skip "OFD access log unsupported"
16004
16005         test_mkdir "${DIR}/${tdir}"
16006
16007         setup_165
16008         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16009         sleep 5
16010
16011         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16012
16013         # 4096 / 64 = 64. Create twice as many entries.
16014         for ((i = 0; i < 128; i++)); do
16015                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16016                         error "cannot create file"
16017         done
16018
16019         sync
16020
16021         do_facet ost1 killall -TERM ofd_access_log_reader
16022         wait
16023         rc=$?
16024         if ((rc != 0)); then
16025                 error "ofd_access_log_reader exited with rc = '${rc}'"
16026         fi
16027
16028         unlinkmany  "${file}-%d" 128
16029 }
16030 run_test 165c "full ofd access logs do not block IOs"
16031
16032 oal_get_read_count() {
16033         local stats="$1"
16034
16035         # STATS lustre-OST0001 alr_read_count 1
16036
16037         do_facet ost1 cat "${stats}" |
16038         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16039              END { print count; }'
16040 }
16041
16042 oal_expect_read_count() {
16043         local stats="$1"
16044         local count
16045         local expect="$2"
16046
16047         # Ask ofd_access_log_reader to write stats.
16048         do_facet ost1 killall -USR1 ofd_access_log_reader
16049
16050         # Allow some time for things to happen.
16051         sleep 1
16052
16053         count=$(oal_get_read_count "${stats}")
16054         if ((count == expect)); then
16055                 return 0
16056         fi
16057
16058         error_noexit "bad read count, got ${count}, expected ${expect}"
16059         do_facet ost1 cat "${stats}" >&2
16060         exit 1
16061 }
16062
16063 test_165d() {
16064         local stats="/tmp/${tfile}.stats"
16065         local file="${DIR}/${tdir}/${tfile}"
16066         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16067
16068         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16069                 skip "OFD access log unsupported"
16070
16071         test_mkdir "${DIR}/${tdir}"
16072
16073         setup_165
16074         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16075         sleep 5
16076
16077         lfs setstripe -c 1 -i 0 "${file}"
16078
16079         do_facet ost1 lctl set_param "${param}=rw"
16080         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16081                 error "cannot create '${file}'"
16082         oal_expect_read_count "${stats}" 1
16083
16084         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16085                 error "cannot read '${file}'"
16086         oal_expect_read_count "${stats}" 2
16087
16088         do_facet ost1 lctl set_param "${param}=r"
16089         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16090                 error "cannot create '${file}'"
16091         oal_expect_read_count "${stats}" 2
16092
16093         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16094                 error "cannot read '${file}'"
16095         oal_expect_read_count "${stats}" 3
16096
16097         do_facet ost1 lctl set_param "${param}=w"
16098         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16099                 error "cannot create '${file}'"
16100         oal_expect_read_count "${stats}" 4
16101
16102         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16103                 error "cannot read '${file}'"
16104         oal_expect_read_count "${stats}" 4
16105
16106         do_facet ost1 lctl set_param "${param}=0"
16107         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16108                 error "cannot create '${file}'"
16109         oal_expect_read_count "${stats}" 4
16110
16111         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16112                 error "cannot read '${file}'"
16113         oal_expect_read_count "${stats}" 4
16114
16115         do_facet ost1 killall -TERM ofd_access_log_reader
16116         wait
16117         rc=$?
16118         if ((rc != 0)); then
16119                 error "ofd_access_log_reader exited with rc = '${rc}'"
16120         fi
16121 }
16122 run_test 165d "ofd_access_log mask works"
16123
16124 test_165e() {
16125         local stats="/tmp/${tfile}.stats"
16126         local file0="${DIR}/${tdir}-0/${tfile}"
16127         local file1="${DIR}/${tdir}-1/${tfile}"
16128
16129         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16130                 skip "OFD access log unsupported"
16131
16132         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16133
16134         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16135         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16136
16137         lfs setstripe -c 1 -i 0 "${file0}"
16138         lfs setstripe -c 1 -i 0 "${file1}"
16139
16140         setup_165
16141         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16142         sleep 5
16143
16144         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16145                 error "cannot create '${file0}'"
16146         sync
16147         oal_expect_read_count "${stats}" 0
16148
16149         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16150                 error "cannot create '${file1}'"
16151         sync
16152         oal_expect_read_count "${stats}" 1
16153
16154         do_facet ost1 killall -TERM ofd_access_log_reader
16155         wait
16156         rc=$?
16157         if ((rc != 0)); then
16158                 error "ofd_access_log_reader exited with rc = '${rc}'"
16159         fi
16160 }
16161 run_test 165e "ofd_access_log MDT index filter works"
16162
16163 test_165f() {
16164         local trace="/tmp/${tfile}.trace"
16165         local rc
16166         local count
16167
16168         setup_165
16169         do_facet ost1 timeout 60 ofd_access_log_reader \
16170                 --exit-on-close --debug=- --trace=- > "${trace}" &
16171         sleep 5
16172         stop ost1
16173
16174         wait
16175         rc=$?
16176
16177         if ((rc != 0)); then
16178                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16179                 cat "${trace}"
16180                 exit 1
16181         fi
16182 }
16183 run_test 165f "ofd_access_log_reader --exit-on-close works"
16184
16185 test_169() {
16186         # do directio so as not to populate the page cache
16187         log "creating a 10 Mb file"
16188         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16189                 error "multiop failed while creating a file"
16190         log "starting reads"
16191         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16192         log "truncating the file"
16193         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16194                 error "multiop failed while truncating the file"
16195         log "killing dd"
16196         kill %+ || true # reads might have finished
16197         echo "wait until dd is finished"
16198         wait
16199         log "removing the temporary file"
16200         rm -rf $DIR/$tfile || error "tmp file removal failed"
16201 }
16202 run_test 169 "parallel read and truncate should not deadlock"
16203
16204 test_170() {
16205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16206
16207         $LCTL clear     # bug 18514
16208         $LCTL debug_daemon start $TMP/${tfile}_log_good
16209         touch $DIR/$tfile
16210         $LCTL debug_daemon stop
16211         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16212                 error "sed failed to read log_good"
16213
16214         $LCTL debug_daemon start $TMP/${tfile}_log_good
16215         rm -rf $DIR/$tfile
16216         $LCTL debug_daemon stop
16217
16218         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16219                error "lctl df log_bad failed"
16220
16221         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16222         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16223
16224         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16225         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16226
16227         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16228                 error "bad_line good_line1 good_line2 are empty"
16229
16230         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16231         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16232         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16233
16234         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16235         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16236         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16237
16238         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16239                 error "bad_line_new good_line_new are empty"
16240
16241         local expected_good=$((good_line1 + good_line2*2))
16242
16243         rm -f $TMP/${tfile}*
16244         # LU-231, short malformed line may not be counted into bad lines
16245         if [ $bad_line -ne $bad_line_new ] &&
16246                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16247                 error "expected $bad_line bad lines, but got $bad_line_new"
16248                 return 1
16249         fi
16250
16251         if [ $expected_good -ne $good_line_new ]; then
16252                 error "expected $expected_good good lines, but got $good_line_new"
16253                 return 2
16254         fi
16255         true
16256 }
16257 run_test 170 "test lctl df to handle corrupted log ====================="
16258
16259 test_171() { # bug20592
16260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16261
16262         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16263         $LCTL set_param fail_loc=0x50e
16264         $LCTL set_param fail_val=3000
16265         multiop_bg_pause $DIR/$tfile O_s || true
16266         local MULTIPID=$!
16267         kill -USR1 $MULTIPID
16268         # cause log dump
16269         sleep 3
16270         wait $MULTIPID
16271         if dmesg | grep "recursive fault"; then
16272                 error "caught a recursive fault"
16273         fi
16274         $LCTL set_param fail_loc=0
16275         true
16276 }
16277 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16278
16279 # it would be good to share it with obdfilter-survey/iokit-libecho code
16280 setup_obdecho_osc () {
16281         local rc=0
16282         local ost_nid=$1
16283         local obdfilter_name=$2
16284         echo "Creating new osc for $obdfilter_name on $ost_nid"
16285         # make sure we can find loopback nid
16286         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16287
16288         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16289                            ${obdfilter_name}_osc_UUID || rc=2; }
16290         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16291                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16292         return $rc
16293 }
16294
16295 cleanup_obdecho_osc () {
16296         local obdfilter_name=$1
16297         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16298         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16299         return 0
16300 }
16301
16302 obdecho_test() {
16303         local OBD=$1
16304         local node=$2
16305         local pages=${3:-64}
16306         local rc=0
16307         local id
16308
16309         local count=10
16310         local obd_size=$(get_obd_size $node $OBD)
16311         local page_size=$(get_page_size $node)
16312         if [[ -n "$obd_size" ]]; then
16313                 local new_count=$((obd_size / (pages * page_size / 1024)))
16314                 [[ $new_count -ge $count ]] || count=$new_count
16315         fi
16316
16317         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16318         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16319                            rc=2; }
16320         if [ $rc -eq 0 ]; then
16321             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16322             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16323         fi
16324         echo "New object id is $id"
16325         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16326                            rc=4; }
16327         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16328                            "test_brw $count w v $pages $id" || rc=4; }
16329         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16330                            rc=4; }
16331         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16332                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16333         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16334                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16335         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16336         return $rc
16337 }
16338
16339 test_180a() {
16340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16341
16342         if ! [ -d /sys/fs/lustre/echo_client ] &&
16343            ! module_loaded obdecho; then
16344                 load_module obdecho/obdecho &&
16345                         stack_trap "rmmod obdecho" EXIT ||
16346                         error "unable to load obdecho on client"
16347         fi
16348
16349         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16350         local host=$($LCTL get_param -n osc.$osc.import |
16351                      awk '/current_connection:/ { print $2 }' )
16352         local target=$($LCTL get_param -n osc.$osc.import |
16353                        awk '/target:/ { print $2 }' )
16354         target=${target%_UUID}
16355
16356         if [ -n "$target" ]; then
16357                 setup_obdecho_osc $host $target &&
16358                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16359                         { error "obdecho setup failed with $?"; return; }
16360
16361                 obdecho_test ${target}_osc client ||
16362                         error "obdecho_test failed on ${target}_osc"
16363         else
16364                 $LCTL get_param osc.$osc.import
16365                 error "there is no osc.$osc.import target"
16366         fi
16367 }
16368 run_test 180a "test obdecho on osc"
16369
16370 test_180b() {
16371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16372         remote_ost_nodsh && skip "remote OST with nodsh"
16373
16374         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16375                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16376                 error "failed to load module obdecho"
16377
16378         local target=$(do_facet ost1 $LCTL dl |
16379                        awk '/obdfilter/ { print $4; exit; }')
16380
16381         if [ -n "$target" ]; then
16382                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16383         else
16384                 do_facet ost1 $LCTL dl
16385                 error "there is no obdfilter target on ost1"
16386         fi
16387 }
16388 run_test 180b "test obdecho directly on obdfilter"
16389
16390 test_180c() { # LU-2598
16391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16392         remote_ost_nodsh && skip "remote OST with nodsh"
16393         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16394                 skip "Need MDS version at least 2.4.0"
16395
16396         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16397                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16398                 error "failed to load module obdecho"
16399
16400         local target=$(do_facet ost1 $LCTL dl |
16401                        awk '/obdfilter/ { print $4; exit; }')
16402
16403         if [ -n "$target" ]; then
16404                 local pages=16384 # 64MB bulk I/O RPC size
16405
16406                 obdecho_test "$target" ost1 "$pages" ||
16407                         error "obdecho_test with pages=$pages failed with $?"
16408         else
16409                 do_facet ost1 $LCTL dl
16410                 error "there is no obdfilter target on ost1"
16411         fi
16412 }
16413 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16414
16415 test_181() { # bug 22177
16416         test_mkdir $DIR/$tdir
16417         # create enough files to index the directory
16418         createmany -o $DIR/$tdir/foobar 4000
16419         # print attributes for debug purpose
16420         lsattr -d .
16421         # open dir
16422         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16423         MULTIPID=$!
16424         # remove the files & current working dir
16425         unlinkmany $DIR/$tdir/foobar 4000
16426         rmdir $DIR/$tdir
16427         kill -USR1 $MULTIPID
16428         wait $MULTIPID
16429         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16430         return 0
16431 }
16432 run_test 181 "Test open-unlinked dir ========================"
16433
16434 test_182() {
16435         local fcount=1000
16436         local tcount=10
16437
16438         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16439
16440         $LCTL set_param mdc.*.rpc_stats=clear
16441
16442         for (( i = 0; i < $tcount; i++ )) ; do
16443                 mkdir $DIR/$tdir/$i
16444         done
16445
16446         for (( i = 0; i < $tcount; i++ )) ; do
16447                 createmany -o $DIR/$tdir/$i/f- $fcount &
16448         done
16449         wait
16450
16451         for (( i = 0; i < $tcount; i++ )) ; do
16452                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16453         done
16454         wait
16455
16456         $LCTL get_param mdc.*.rpc_stats
16457
16458         rm -rf $DIR/$tdir
16459 }
16460 run_test 182 "Test parallel modify metadata operations ================"
16461
16462 test_183() { # LU-2275
16463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16464         remote_mds_nodsh && skip "remote MDS with nodsh"
16465         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16466                 skip "Need MDS version at least 2.3.56"
16467
16468         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16469         echo aaa > $DIR/$tdir/$tfile
16470
16471 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16472         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16473
16474         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16475         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16476
16477         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16478
16479         # Flush negative dentry cache
16480         touch $DIR/$tdir/$tfile
16481
16482         # We are not checking for any leaked references here, they'll
16483         # become evident next time we do cleanup with module unload.
16484         rm -rf $DIR/$tdir
16485 }
16486 run_test 183 "No crash or request leak in case of strange dispositions ========"
16487
16488 # test suite 184 is for LU-2016, LU-2017
16489 test_184a() {
16490         check_swap_layouts_support
16491
16492         dir0=$DIR/$tdir/$testnum
16493         test_mkdir -p -c1 $dir0
16494         ref1=/etc/passwd
16495         ref2=/etc/group
16496         file1=$dir0/f1
16497         file2=$dir0/f2
16498         $LFS setstripe -c1 $file1
16499         cp $ref1 $file1
16500         $LFS setstripe -c2 $file2
16501         cp $ref2 $file2
16502         gen1=$($LFS getstripe -g $file1)
16503         gen2=$($LFS getstripe -g $file2)
16504
16505         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16506         gen=$($LFS getstripe -g $file1)
16507         [[ $gen1 != $gen ]] ||
16508                 "Layout generation on $file1 does not change"
16509         gen=$($LFS getstripe -g $file2)
16510         [[ $gen2 != $gen ]] ||
16511                 "Layout generation on $file2 does not change"
16512
16513         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16514         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16515
16516         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16517 }
16518 run_test 184a "Basic layout swap"
16519
16520 test_184b() {
16521         check_swap_layouts_support
16522
16523         dir0=$DIR/$tdir/$testnum
16524         mkdir -p $dir0 || error "creating dir $dir0"
16525         file1=$dir0/f1
16526         file2=$dir0/f2
16527         file3=$dir0/f3
16528         dir1=$dir0/d1
16529         dir2=$dir0/d2
16530         mkdir $dir1 $dir2
16531         $LFS setstripe -c1 $file1
16532         $LFS setstripe -c2 $file2
16533         $LFS setstripe -c1 $file3
16534         chown $RUNAS_ID $file3
16535         gen1=$($LFS getstripe -g $file1)
16536         gen2=$($LFS getstripe -g $file2)
16537
16538         $LFS swap_layouts $dir1 $dir2 &&
16539                 error "swap of directories layouts should fail"
16540         $LFS swap_layouts $dir1 $file1 &&
16541                 error "swap of directory and file layouts should fail"
16542         $RUNAS $LFS swap_layouts $file1 $file2 &&
16543                 error "swap of file we cannot write should fail"
16544         $LFS swap_layouts $file1 $file3 &&
16545                 error "swap of file with different owner should fail"
16546         /bin/true # to clear error code
16547 }
16548 run_test 184b "Forbidden layout swap (will generate errors)"
16549
16550 test_184c() {
16551         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16552         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16553         check_swap_layouts_support
16554         check_swap_layout_no_dom $DIR
16555
16556         local dir0=$DIR/$tdir/$testnum
16557         mkdir -p $dir0 || error "creating dir $dir0"
16558
16559         local ref1=$dir0/ref1
16560         local ref2=$dir0/ref2
16561         local file1=$dir0/file1
16562         local file2=$dir0/file2
16563         # create a file large enough for the concurrent test
16564         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16565         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16566         echo "ref file size: ref1($(stat -c %s $ref1))," \
16567              "ref2($(stat -c %s $ref2))"
16568
16569         cp $ref2 $file2
16570         dd if=$ref1 of=$file1 bs=16k &
16571         local DD_PID=$!
16572
16573         # Make sure dd starts to copy file, but wait at most 5 seconds
16574         local loops=0
16575         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16576
16577         $LFS swap_layouts $file1 $file2
16578         local rc=$?
16579         wait $DD_PID
16580         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16581         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16582
16583         # how many bytes copied before swapping layout
16584         local copied=$(stat -c %s $file2)
16585         local remaining=$(stat -c %s $ref1)
16586         remaining=$((remaining - copied))
16587         echo "Copied $copied bytes before swapping layout..."
16588
16589         cmp -n $copied $file1 $ref2 | grep differ &&
16590                 error "Content mismatch [0, $copied) of ref2 and file1"
16591         cmp -n $copied $file2 $ref1 ||
16592                 error "Content mismatch [0, $copied) of ref1 and file2"
16593         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16594                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16595
16596         # clean up
16597         rm -f $ref1 $ref2 $file1 $file2
16598 }
16599 run_test 184c "Concurrent write and layout swap"
16600
16601 test_184d() {
16602         check_swap_layouts_support
16603         check_swap_layout_no_dom $DIR
16604         [ -z "$(which getfattr 2>/dev/null)" ] &&
16605                 skip_env "no getfattr command"
16606
16607         local file1=$DIR/$tdir/$tfile-1
16608         local file2=$DIR/$tdir/$tfile-2
16609         local file3=$DIR/$tdir/$tfile-3
16610         local lovea1
16611         local lovea2
16612
16613         mkdir -p $DIR/$tdir
16614         touch $file1 || error "create $file1 failed"
16615         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16616                 error "create $file2 failed"
16617         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16618                 error "create $file3 failed"
16619         lovea1=$(get_layout_param $file1)
16620
16621         $LFS swap_layouts $file2 $file3 ||
16622                 error "swap $file2 $file3 layouts failed"
16623         $LFS swap_layouts $file1 $file2 ||
16624                 error "swap $file1 $file2 layouts failed"
16625
16626         lovea2=$(get_layout_param $file2)
16627         echo "$lovea1"
16628         echo "$lovea2"
16629         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16630
16631         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16632         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16633 }
16634 run_test 184d "allow stripeless layouts swap"
16635
16636 test_184e() {
16637         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16638                 skip "Need MDS version at least 2.6.94"
16639         check_swap_layouts_support
16640         check_swap_layout_no_dom $DIR
16641         [ -z "$(which getfattr 2>/dev/null)" ] &&
16642                 skip_env "no getfattr command"
16643
16644         local file1=$DIR/$tdir/$tfile-1
16645         local file2=$DIR/$tdir/$tfile-2
16646         local file3=$DIR/$tdir/$tfile-3
16647         local lovea
16648
16649         mkdir -p $DIR/$tdir
16650         touch $file1 || error "create $file1 failed"
16651         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16652                 error "create $file2 failed"
16653         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16654                 error "create $file3 failed"
16655
16656         $LFS swap_layouts $file1 $file2 ||
16657                 error "swap $file1 $file2 layouts failed"
16658
16659         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16660         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16661
16662         echo 123 > $file1 || error "Should be able to write into $file1"
16663
16664         $LFS swap_layouts $file1 $file3 ||
16665                 error "swap $file1 $file3 layouts failed"
16666
16667         echo 123 > $file1 || error "Should be able to write into $file1"
16668
16669         rm -rf $file1 $file2 $file3
16670 }
16671 run_test 184e "Recreate layout after stripeless layout swaps"
16672
16673 test_184f() {
16674         # Create a file with name longer than sizeof(struct stat) ==
16675         # 144 to see if we can get chars from the file name to appear
16676         # in the returned striping. Note that 'f' == 0x66.
16677         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16678
16679         mkdir -p $DIR/$tdir
16680         mcreate $DIR/$tdir/$file
16681         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16682                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16683         fi
16684 }
16685 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16686
16687 test_185() { # LU-2441
16688         # LU-3553 - no volatile file support in old servers
16689         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16690                 skip "Need MDS version at least 2.3.60"
16691
16692         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16693         touch $DIR/$tdir/spoo
16694         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16695         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16696                 error "cannot create/write a volatile file"
16697         [ "$FILESET" == "" ] &&
16698         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16699                 error "FID is still valid after close"
16700
16701         multiop_bg_pause $DIR/$tdir vVw4096_c
16702         local multi_pid=$!
16703
16704         local OLD_IFS=$IFS
16705         IFS=":"
16706         local fidv=($fid)
16707         IFS=$OLD_IFS
16708         # assume that the next FID for this client is sequential, since stdout
16709         # is unfortunately eaten by multiop_bg_pause
16710         local n=$((${fidv[1]} + 1))
16711         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16712         if [ "$FILESET" == "" ]; then
16713                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16714                         error "FID is missing before close"
16715         fi
16716         kill -USR1 $multi_pid
16717         # 1 second delay, so if mtime change we will see it
16718         sleep 1
16719         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16720         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16721 }
16722 run_test 185 "Volatile file support"
16723
16724 function create_check_volatile() {
16725         local idx=$1
16726         local tgt
16727
16728         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16729         local PID=$!
16730         sleep 1
16731         local FID=$(cat /tmp/${tfile}.fid)
16732         [ "$FID" == "" ] && error "can't get FID for volatile"
16733         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16734         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16735         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16736         kill -USR1 $PID
16737         wait
16738         sleep 1
16739         cancel_lru_locks mdc # flush opencache
16740         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16741         return 0
16742 }
16743
16744 test_185a(){
16745         # LU-12516 - volatile creation via .lustre
16746         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16747                 skip "Need MDS version at least 2.3.55"
16748
16749         create_check_volatile 0
16750         [ $MDSCOUNT -lt 2 ] && return 0
16751
16752         # DNE case
16753         create_check_volatile 1
16754
16755         return 0
16756 }
16757 run_test 185a "Volatile file creation in .lustre/fid/"
16758
16759 test_187a() {
16760         remote_mds_nodsh && skip "remote MDS with nodsh"
16761         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16762                 skip "Need MDS version at least 2.3.0"
16763
16764         local dir0=$DIR/$tdir/$testnum
16765         mkdir -p $dir0 || error "creating dir $dir0"
16766
16767         local file=$dir0/file1
16768         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16769         local dv1=$($LFS data_version $file)
16770         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16771         local dv2=$($LFS data_version $file)
16772         [[ $dv1 != $dv2 ]] ||
16773                 error "data version did not change on write $dv1 == $dv2"
16774
16775         # clean up
16776         rm -f $file1
16777 }
16778 run_test 187a "Test data version change"
16779
16780 test_187b() {
16781         remote_mds_nodsh && skip "remote MDS with nodsh"
16782         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16783                 skip "Need MDS version at least 2.3.0"
16784
16785         local dir0=$DIR/$tdir/$testnum
16786         mkdir -p $dir0 || error "creating dir $dir0"
16787
16788         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16789         [[ ${DV[0]} != ${DV[1]} ]] ||
16790                 error "data version did not change on write"\
16791                       " ${DV[0]} == ${DV[1]}"
16792
16793         # clean up
16794         rm -f $file1
16795 }
16796 run_test 187b "Test data version change on volatile file"
16797
16798 test_200() {
16799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16800         remote_mgs_nodsh && skip "remote MGS with nodsh"
16801         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16802
16803         local POOL=${POOL:-cea1}
16804         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16805         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16806         # Pool OST targets
16807         local first_ost=0
16808         local last_ost=$(($OSTCOUNT - 1))
16809         local ost_step=2
16810         local ost_list=$(seq $first_ost $ost_step $last_ost)
16811         local ost_range="$first_ost $last_ost $ost_step"
16812         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16813         local file_dir=$POOL_ROOT/file_tst
16814         local subdir=$test_path/subdir
16815         local rc=0
16816
16817         while : ; do
16818                 # former test_200a test_200b
16819                 pool_add $POOL                          || { rc=$? ; break; }
16820                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16821                 # former test_200c test_200d
16822                 mkdir -p $test_path
16823                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16824                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16825                 mkdir -p $subdir
16826                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16827                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16828                                                         || { rc=$? ; break; }
16829                 # former test_200e test_200f
16830                 local files=$((OSTCOUNT*3))
16831                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16832                                                         || { rc=$? ; break; }
16833                 pool_create_files $POOL $file_dir $files "$ost_list" \
16834                                                         || { rc=$? ; break; }
16835                 # former test_200g test_200h
16836                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16837                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16838
16839                 # former test_201a test_201b test_201c
16840                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16841
16842                 local f=$test_path/$tfile
16843                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16844                 pool_remove $POOL $f                    || { rc=$? ; break; }
16845                 break
16846         done
16847
16848         destroy_test_pools
16849
16850         return $rc
16851 }
16852 run_test 200 "OST pools"
16853
16854 # usage: default_attr <count | size | offset>
16855 default_attr() {
16856         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16857 }
16858
16859 # usage: check_default_stripe_attr
16860 check_default_stripe_attr() {
16861         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16862         case $1 in
16863         --stripe-count|-c)
16864                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16865         --stripe-size|-S)
16866                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16867         --stripe-index|-i)
16868                 EXPECTED=-1;;
16869         *)
16870                 error "unknown getstripe attr '$1'"
16871         esac
16872
16873         [ $ACTUAL == $EXPECTED ] ||
16874                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16875 }
16876
16877 test_204a() {
16878         test_mkdir $DIR/$tdir
16879         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16880
16881         check_default_stripe_attr --stripe-count
16882         check_default_stripe_attr --stripe-size
16883         check_default_stripe_attr --stripe-index
16884 }
16885 run_test 204a "Print default stripe attributes"
16886
16887 test_204b() {
16888         test_mkdir $DIR/$tdir
16889         $LFS setstripe --stripe-count 1 $DIR/$tdir
16890
16891         check_default_stripe_attr --stripe-size
16892         check_default_stripe_attr --stripe-index
16893 }
16894 run_test 204b "Print default stripe size and offset"
16895
16896 test_204c() {
16897         test_mkdir $DIR/$tdir
16898         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16899
16900         check_default_stripe_attr --stripe-count
16901         check_default_stripe_attr --stripe-index
16902 }
16903 run_test 204c "Print default stripe count and offset"
16904
16905 test_204d() {
16906         test_mkdir $DIR/$tdir
16907         $LFS setstripe --stripe-index 0 $DIR/$tdir
16908
16909         check_default_stripe_attr --stripe-count
16910         check_default_stripe_attr --stripe-size
16911 }
16912 run_test 204d "Print default stripe count and size"
16913
16914 test_204e() {
16915         test_mkdir $DIR/$tdir
16916         $LFS setstripe -d $DIR/$tdir
16917
16918         check_default_stripe_attr --stripe-count --raw
16919         check_default_stripe_attr --stripe-size --raw
16920         check_default_stripe_attr --stripe-index --raw
16921 }
16922 run_test 204e "Print raw stripe attributes"
16923
16924 test_204f() {
16925         test_mkdir $DIR/$tdir
16926         $LFS setstripe --stripe-count 1 $DIR/$tdir
16927
16928         check_default_stripe_attr --stripe-size --raw
16929         check_default_stripe_attr --stripe-index --raw
16930 }
16931 run_test 204f "Print raw stripe size and offset"
16932
16933 test_204g() {
16934         test_mkdir $DIR/$tdir
16935         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16936
16937         check_default_stripe_attr --stripe-count --raw
16938         check_default_stripe_attr --stripe-index --raw
16939 }
16940 run_test 204g "Print raw stripe count and offset"
16941
16942 test_204h() {
16943         test_mkdir $DIR/$tdir
16944         $LFS setstripe --stripe-index 0 $DIR/$tdir
16945
16946         check_default_stripe_attr --stripe-count --raw
16947         check_default_stripe_attr --stripe-size --raw
16948 }
16949 run_test 204h "Print raw stripe count and size"
16950
16951 # Figure out which job scheduler is being used, if any,
16952 # or use a fake one
16953 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16954         JOBENV=SLURM_JOB_ID
16955 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16956         JOBENV=LSB_JOBID
16957 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16958         JOBENV=PBS_JOBID
16959 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16960         JOBENV=LOADL_STEP_ID
16961 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16962         JOBENV=JOB_ID
16963 else
16964         $LCTL list_param jobid_name > /dev/null 2>&1
16965         if [ $? -eq 0 ]; then
16966                 JOBENV=nodelocal
16967         else
16968                 JOBENV=FAKE_JOBID
16969         fi
16970 fi
16971 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16972
16973 verify_jobstats() {
16974         local cmd=($1)
16975         shift
16976         local facets="$@"
16977
16978 # we don't really need to clear the stats for this test to work, since each
16979 # command has a unique jobid, but it makes debugging easier if needed.
16980 #       for facet in $facets; do
16981 #               local dev=$(convert_facet2label $facet)
16982 #               # clear old jobstats
16983 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16984 #       done
16985
16986         # use a new JobID for each test, or we might see an old one
16987         [ "$JOBENV" = "FAKE_JOBID" ] &&
16988                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16989
16990         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16991
16992         [ "$JOBENV" = "nodelocal" ] && {
16993                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16994                 $LCTL set_param jobid_name=$FAKE_JOBID
16995                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16996         }
16997
16998         log "Test: ${cmd[*]}"
16999         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17000
17001         if [ $JOBENV = "FAKE_JOBID" ]; then
17002                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17003         else
17004                 ${cmd[*]}
17005         fi
17006
17007         # all files are created on OST0000
17008         for facet in $facets; do
17009                 local stats="*.$(convert_facet2label $facet).job_stats"
17010
17011                 # strip out libtool wrappers for in-tree executables
17012                 if [ $(do_facet $facet lctl get_param $stats |
17013                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17014                         do_facet $facet lctl get_param $stats
17015                         error "No jobstats for $JOBVAL found on $facet::$stats"
17016                 fi
17017         done
17018 }
17019
17020 jobstats_set() {
17021         local new_jobenv=$1
17022
17023         set_persistent_param_and_check client "jobid_var" \
17024                 "$FSNAME.sys.jobid_var" $new_jobenv
17025 }
17026
17027 test_205a() { # Job stats
17028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17029         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17030                 skip "Need MDS version with at least 2.7.1"
17031         remote_mgs_nodsh && skip "remote MGS with nodsh"
17032         remote_mds_nodsh && skip "remote MDS with nodsh"
17033         remote_ost_nodsh && skip "remote OST with nodsh"
17034         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17035                 skip "Server doesn't support jobstats"
17036         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17037
17038         local old_jobenv=$($LCTL get_param -n jobid_var)
17039         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17040
17041         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17042                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17043         else
17044                 stack_trap "do_facet mgs $PERM_CMD \
17045                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17046         fi
17047         changelog_register
17048
17049         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17050                                 mdt.*.job_cleanup_interval | head -n 1)
17051         local new_interval=5
17052         do_facet $SINGLEMDS \
17053                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17054         stack_trap "do_facet $SINGLEMDS \
17055                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17056         local start=$SECONDS
17057
17058         local cmd
17059         # mkdir
17060         cmd="mkdir $DIR/$tdir"
17061         verify_jobstats "$cmd" "$SINGLEMDS"
17062         # rmdir
17063         cmd="rmdir $DIR/$tdir"
17064         verify_jobstats "$cmd" "$SINGLEMDS"
17065         # mkdir on secondary MDT
17066         if [ $MDSCOUNT -gt 1 ]; then
17067                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17068                 verify_jobstats "$cmd" "mds2"
17069         fi
17070         # mknod
17071         cmd="mknod $DIR/$tfile c 1 3"
17072         verify_jobstats "$cmd" "$SINGLEMDS"
17073         # unlink
17074         cmd="rm -f $DIR/$tfile"
17075         verify_jobstats "$cmd" "$SINGLEMDS"
17076         # create all files on OST0000 so verify_jobstats can find OST stats
17077         # open & close
17078         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17079         verify_jobstats "$cmd" "$SINGLEMDS"
17080         # setattr
17081         cmd="touch $DIR/$tfile"
17082         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17083         # write
17084         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17085         verify_jobstats "$cmd" "ost1"
17086         # read
17087         cancel_lru_locks osc
17088         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17089         verify_jobstats "$cmd" "ost1"
17090         # truncate
17091         cmd="$TRUNCATE $DIR/$tfile 0"
17092         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17093         # rename
17094         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17095         verify_jobstats "$cmd" "$SINGLEMDS"
17096         # jobstats expiry - sleep until old stats should be expired
17097         local left=$((new_interval + 5 - (SECONDS - start)))
17098         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17099                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17100                         "0" $left
17101         cmd="mkdir $DIR/$tdir.expire"
17102         verify_jobstats "$cmd" "$SINGLEMDS"
17103         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17104             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17105
17106         # Ensure that jobid are present in changelog (if supported by MDS)
17107         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17108                 changelog_dump | tail -10
17109                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17110                 [ $jobids -eq 9 ] ||
17111                         error "Wrong changelog jobid count $jobids != 9"
17112
17113                 # LU-5862
17114                 JOBENV="disable"
17115                 jobstats_set $JOBENV
17116                 touch $DIR/$tfile
17117                 changelog_dump | grep $tfile
17118                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17119                 [ $jobids -eq 0 ] ||
17120                         error "Unexpected jobids when jobid_var=$JOBENV"
17121         fi
17122
17123         # test '%j' access to environment variable - if supported
17124         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17125                 JOBENV="JOBCOMPLEX"
17126                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17127
17128                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17129         fi
17130
17131         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17132                 JOBENV="JOBCOMPLEX"
17133                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17134
17135                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17136         fi
17137
17138         # test '%j' access to per-session jobid - if supported
17139         if lctl list_param jobid_this_session > /dev/null 2>&1
17140         then
17141                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17142                 lctl set_param jobid_this_session=$USER
17143
17144                 JOBENV="JOBCOMPLEX"
17145                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17146
17147                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17148         fi
17149 }
17150 run_test 205a "Verify job stats"
17151
17152 # LU-13117, LU-13597
17153 test_205b() {
17154         job_stats="mdt.*.job_stats"
17155         $LCTL set_param $job_stats=clear
17156         # Setting jobid_var to USER might not be supported
17157         $LCTL set_param jobid_var=USER || true
17158         $LCTL set_param jobid_name="%e.%u"
17159         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17160         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17161                 grep "job_id:.*foolish" &&
17162                         error "Unexpected jobid found"
17163         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17164                 grep "open:.*min.*max.*sum" ||
17165                         error "wrong job_stats format found"
17166 }
17167 run_test 205b "Verify job stats jobid and output format"
17168
17169 # LU-13733
17170 test_205c() {
17171         $LCTL set_param llite.*.stats=0
17172         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17173         $LCTL get_param llite.*.stats
17174         $LCTL get_param llite.*.stats | grep \
17175                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17176                         error "wrong client stats format found"
17177 }
17178 run_test 205c "Verify client stats format"
17179
17180 # LU-1480, LU-1773 and LU-1657
17181 test_206() {
17182         mkdir -p $DIR/$tdir
17183         $LFS setstripe -c -1 $DIR/$tdir
17184 #define OBD_FAIL_LOV_INIT 0x1403
17185         $LCTL set_param fail_loc=0xa0001403
17186         $LCTL set_param fail_val=1
17187         touch $DIR/$tdir/$tfile || true
17188 }
17189 run_test 206 "fail lov_init_raid0() doesn't lbug"
17190
17191 test_207a() {
17192         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17193         local fsz=`stat -c %s $DIR/$tfile`
17194         cancel_lru_locks mdc
17195
17196         # do not return layout in getattr intent
17197 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17198         $LCTL set_param fail_loc=0x170
17199         local sz=`stat -c %s $DIR/$tfile`
17200
17201         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17202
17203         rm -rf $DIR/$tfile
17204 }
17205 run_test 207a "can refresh layout at glimpse"
17206
17207 test_207b() {
17208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17209         local cksum=`md5sum $DIR/$tfile`
17210         local fsz=`stat -c %s $DIR/$tfile`
17211         cancel_lru_locks mdc
17212         cancel_lru_locks osc
17213
17214         # do not return layout in getattr intent
17215 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17216         $LCTL set_param fail_loc=0x171
17217
17218         # it will refresh layout after the file is opened but before read issues
17219         echo checksum is "$cksum"
17220         echo "$cksum" |md5sum -c --quiet || error "file differs"
17221
17222         rm -rf $DIR/$tfile
17223 }
17224 run_test 207b "can refresh layout at open"
17225
17226 test_208() {
17227         # FIXME: in this test suite, only RD lease is used. This is okay
17228         # for now as only exclusive open is supported. After generic lease
17229         # is done, this test suite should be revised. - Jinshan
17230
17231         remote_mds_nodsh && skip "remote MDS with nodsh"
17232         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17233                 skip "Need MDS version at least 2.4.52"
17234
17235         echo "==== test 1: verify get lease work"
17236         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17237
17238         echo "==== test 2: verify lease can be broken by upcoming open"
17239         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17240         local PID=$!
17241         sleep 1
17242
17243         $MULTIOP $DIR/$tfile oO_RDONLY:c
17244         kill -USR1 $PID && wait $PID || error "break lease error"
17245
17246         echo "==== test 3: verify lease can't be granted if an open already exists"
17247         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17248         local PID=$!
17249         sleep 1
17250
17251         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17252         kill -USR1 $PID && wait $PID || error "open file error"
17253
17254         echo "==== test 4: lease can sustain over recovery"
17255         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17256         PID=$!
17257         sleep 1
17258
17259         fail mds1
17260
17261         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17262
17263         echo "==== test 5: lease broken can't be regained by replay"
17264         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17265         PID=$!
17266         sleep 1
17267
17268         # open file to break lease and then recovery
17269         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17270         fail mds1
17271
17272         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17273
17274         rm -f $DIR/$tfile
17275 }
17276 run_test 208 "Exclusive open"
17277
17278 test_209() {
17279         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17280                 skip_env "must have disp_stripe"
17281
17282         touch $DIR/$tfile
17283         sync; sleep 5; sync;
17284
17285         echo 3 > /proc/sys/vm/drop_caches
17286         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17287                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17288         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17289
17290         # open/close 500 times
17291         for i in $(seq 500); do
17292                 cat $DIR/$tfile
17293         done
17294
17295         echo 3 > /proc/sys/vm/drop_caches
17296         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17297                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17298         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17299
17300         echo "before: $req_before, after: $req_after"
17301         [ $((req_after - req_before)) -ge 300 ] &&
17302                 error "open/close requests are not freed"
17303         return 0
17304 }
17305 run_test 209 "read-only open/close requests should be freed promptly"
17306
17307 test_210() {
17308         local pid
17309
17310         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17311         pid=$!
17312         sleep 1
17313
17314         $LFS getstripe $DIR/$tfile
17315         kill -USR1 $pid
17316         wait $pid || error "multiop failed"
17317
17318         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17319         pid=$!
17320         sleep 1
17321
17322         $LFS getstripe $DIR/$tfile
17323         kill -USR1 $pid
17324         wait $pid || error "multiop failed"
17325 }
17326 run_test 210 "lfs getstripe does not break leases"
17327
17328 test_212() {
17329         size=`date +%s`
17330         size=$((size % 8192 + 1))
17331         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17332         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17333         rm -f $DIR/f212 $DIR/f212.xyz
17334 }
17335 run_test 212 "Sendfile test ============================================"
17336
17337 test_213() {
17338         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17339         cancel_lru_locks osc
17340         lctl set_param fail_loc=0x8000040f
17341         # generate a read lock
17342         cat $DIR/$tfile > /dev/null
17343         # write to the file, it will try to cancel the above read lock.
17344         cat /etc/hosts >> $DIR/$tfile
17345 }
17346 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17347
17348 test_214() { # for bug 20133
17349         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17350         for (( i=0; i < 340; i++ )) ; do
17351                 touch $DIR/$tdir/d214c/a$i
17352         done
17353
17354         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17355         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17356         ls $DIR/d214c || error "ls $DIR/d214c failed"
17357         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17358         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17359 }
17360 run_test 214 "hash-indexed directory test - bug 20133"
17361
17362 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17363 create_lnet_proc_files() {
17364         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17365 }
17366
17367 # counterpart of create_lnet_proc_files
17368 remove_lnet_proc_files() {
17369         rm -f $TMP/lnet_$1.sys
17370 }
17371
17372 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17373 # 3rd arg as regexp for body
17374 check_lnet_proc_stats() {
17375         local l=$(cat "$TMP/lnet_$1" |wc -l)
17376         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17377
17378         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17379 }
17380
17381 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17382 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17383 # optional and can be regexp for 2nd line (lnet.routes case)
17384 check_lnet_proc_entry() {
17385         local blp=2          # blp stands for 'position of 1st line of body'
17386         [ -z "$5" ] || blp=3 # lnet.routes case
17387
17388         local l=$(cat "$TMP/lnet_$1" |wc -l)
17389         # subtracting one from $blp because the body can be empty
17390         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17391
17392         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17393                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17394
17395         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17396                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17397
17398         # bail out if any unexpected line happened
17399         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17400         [ "$?" != 0 ] || error "$2 misformatted"
17401 }
17402
17403 test_215() { # for bugs 18102, 21079, 21517
17404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17405
17406         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17407         local P='[1-9][0-9]*'           # positive numeric
17408         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17409         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17410         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17411         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17412
17413         local L1 # regexp for 1st line
17414         local L2 # regexp for 2nd line (optional)
17415         local BR # regexp for the rest (body)
17416
17417         # lnet.stats should look as 11 space-separated non-negative numerics
17418         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17419         create_lnet_proc_files "stats"
17420         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17421         remove_lnet_proc_files "stats"
17422
17423         # lnet.routes should look like this:
17424         # Routing disabled/enabled
17425         # net hops priority state router
17426         # where net is a string like tcp0, hops > 0, priority >= 0,
17427         # state is up/down,
17428         # router is a string like 192.168.1.1@tcp2
17429         L1="^Routing (disabled|enabled)$"
17430         L2="^net +hops +priority +state +router$"
17431         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17432         create_lnet_proc_files "routes"
17433         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17434         remove_lnet_proc_files "routes"
17435
17436         # lnet.routers should look like this:
17437         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17438         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17439         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17440         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17441         L1="^ref +rtr_ref +alive +router$"
17442         BR="^$P +$P +(up|down) +$NID$"
17443         create_lnet_proc_files "routers"
17444         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17445         remove_lnet_proc_files "routers"
17446
17447         # lnet.peers should look like this:
17448         # nid refs state last max rtr min tx min queue
17449         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17450         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17451         # numeric (0 or >0 or <0), queue >= 0.
17452         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17453         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17454         create_lnet_proc_files "peers"
17455         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17456         remove_lnet_proc_files "peers"
17457
17458         # lnet.buffers  should look like this:
17459         # pages count credits min
17460         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17461         L1="^pages +count +credits +min$"
17462         BR="^ +$N +$N +$I +$I$"
17463         create_lnet_proc_files "buffers"
17464         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17465         remove_lnet_proc_files "buffers"
17466
17467         # lnet.nis should look like this:
17468         # nid status alive refs peer rtr max tx min
17469         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17470         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17471         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17472         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17473         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17474         create_lnet_proc_files "nis"
17475         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17476         remove_lnet_proc_files "nis"
17477
17478         # can we successfully write to lnet.stats?
17479         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17480 }
17481 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17482
17483 test_216() { # bug 20317
17484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17485         remote_ost_nodsh && skip "remote OST with nodsh"
17486
17487         local node
17488         local facets=$(get_facets OST)
17489         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17490
17491         save_lustre_params client "osc.*.contention_seconds" > $p
17492         save_lustre_params $facets \
17493                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17494         save_lustre_params $facets \
17495                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17496         save_lustre_params $facets \
17497                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17498         clear_stats osc.*.osc_stats
17499
17500         # agressive lockless i/o settings
17501         do_nodes $(comma_list $(osts_nodes)) \
17502                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17503                         ldlm.namespaces.filter-*.contended_locks=0 \
17504                         ldlm.namespaces.filter-*.contention_seconds=60"
17505         lctl set_param -n osc.*.contention_seconds=60
17506
17507         $DIRECTIO write $DIR/$tfile 0 10 4096
17508         $CHECKSTAT -s 40960 $DIR/$tfile
17509
17510         # disable lockless i/o
17511         do_nodes $(comma_list $(osts_nodes)) \
17512                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17513                         ldlm.namespaces.filter-*.contended_locks=32 \
17514                         ldlm.namespaces.filter-*.contention_seconds=0"
17515         lctl set_param -n osc.*.contention_seconds=0
17516         clear_stats osc.*.osc_stats
17517
17518         dd if=/dev/zero of=$DIR/$tfile count=0
17519         $CHECKSTAT -s 0 $DIR/$tfile
17520
17521         restore_lustre_params <$p
17522         rm -f $p
17523         rm $DIR/$tfile
17524 }
17525 run_test 216 "check lockless direct write updates file size and kms correctly"
17526
17527 test_217() { # bug 22430
17528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17529
17530         local node
17531         local nid
17532
17533         for node in $(nodes_list); do
17534                 nid=$(host_nids_address $node $NETTYPE)
17535                 if [[ $nid = *-* ]] ; then
17536                         echo "lctl ping $(h2nettype $nid)"
17537                         lctl ping $(h2nettype $nid)
17538                 else
17539                         echo "skipping $node (no hyphen detected)"
17540                 fi
17541         done
17542 }
17543 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17544
17545 test_218() {
17546        # do directio so as not to populate the page cache
17547        log "creating a 10 Mb file"
17548        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17549        log "starting reads"
17550        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17551        log "truncating the file"
17552        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17553        log "killing dd"
17554        kill %+ || true # reads might have finished
17555        echo "wait until dd is finished"
17556        wait
17557        log "removing the temporary file"
17558        rm -rf $DIR/$tfile || error "tmp file removal failed"
17559 }
17560 run_test 218 "parallel read and truncate should not deadlock"
17561
17562 test_219() {
17563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17564
17565         # write one partial page
17566         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17567         # set no grant so vvp_io_commit_write will do sync write
17568         $LCTL set_param fail_loc=0x411
17569         # write a full page at the end of file
17570         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17571
17572         $LCTL set_param fail_loc=0
17573         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17574         $LCTL set_param fail_loc=0x411
17575         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17576
17577         # LU-4201
17578         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17579         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17580 }
17581 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17582
17583 test_220() { #LU-325
17584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17585         remote_ost_nodsh && skip "remote OST with nodsh"
17586         remote_mds_nodsh && skip "remote MDS with nodsh"
17587         remote_mgs_nodsh && skip "remote MGS with nodsh"
17588
17589         local OSTIDX=0
17590
17591         # create on MDT0000 so the last_id and next_id are correct
17592         mkdir $DIR/$tdir
17593         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17594         OST=${OST%_UUID}
17595
17596         # on the mdt's osc
17597         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17598         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17599                         osp.$mdtosc_proc1.prealloc_last_id)
17600         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17601                         osp.$mdtosc_proc1.prealloc_next_id)
17602
17603         $LFS df -i
17604
17605         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17606         #define OBD_FAIL_OST_ENOINO              0x229
17607         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17608         create_pool $FSNAME.$TESTNAME || return 1
17609         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17610
17611         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17612
17613         MDSOBJS=$((last_id - next_id))
17614         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17615
17616         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17617         echo "OST still has $count kbytes free"
17618
17619         echo "create $MDSOBJS files @next_id..."
17620         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17621
17622         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17623                         osp.$mdtosc_proc1.prealloc_last_id)
17624         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17625                         osp.$mdtosc_proc1.prealloc_next_id)
17626
17627         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17628         $LFS df -i
17629
17630         echo "cleanup..."
17631
17632         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17633         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17634
17635         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17636                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17637         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17638                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17639         echo "unlink $MDSOBJS files @$next_id..."
17640         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17641 }
17642 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17643
17644 test_221() {
17645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17646
17647         dd if=`which date` of=$MOUNT/date oflag=sync
17648         chmod +x $MOUNT/date
17649
17650         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17651         $LCTL set_param fail_loc=0x80001401
17652
17653         $MOUNT/date > /dev/null
17654         rm -f $MOUNT/date
17655 }
17656 run_test 221 "make sure fault and truncate race to not cause OOM"
17657
17658 test_222a () {
17659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17660
17661         rm -rf $DIR/$tdir
17662         test_mkdir $DIR/$tdir
17663         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17664         createmany -o $DIR/$tdir/$tfile 10
17665         cancel_lru_locks mdc
17666         cancel_lru_locks osc
17667         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17668         $LCTL set_param fail_loc=0x31a
17669         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17670         $LCTL set_param fail_loc=0
17671         rm -r $DIR/$tdir
17672 }
17673 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17674
17675 test_222b () {
17676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17677
17678         rm -rf $DIR/$tdir
17679         test_mkdir $DIR/$tdir
17680         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17681         createmany -o $DIR/$tdir/$tfile 10
17682         cancel_lru_locks mdc
17683         cancel_lru_locks osc
17684         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17685         $LCTL set_param fail_loc=0x31a
17686         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17687         $LCTL set_param fail_loc=0
17688 }
17689 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17690
17691 test_223 () {
17692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17693
17694         rm -rf $DIR/$tdir
17695         test_mkdir $DIR/$tdir
17696         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17697         createmany -o $DIR/$tdir/$tfile 10
17698         cancel_lru_locks mdc
17699         cancel_lru_locks osc
17700         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17701         $LCTL set_param fail_loc=0x31b
17702         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17703         $LCTL set_param fail_loc=0
17704         rm -r $DIR/$tdir
17705 }
17706 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17707
17708 test_224a() { # LU-1039, MRP-303
17709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17710
17711         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17712         $LCTL set_param fail_loc=0x508
17713         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17714         $LCTL set_param fail_loc=0
17715         df $DIR
17716 }
17717 run_test 224a "Don't panic on bulk IO failure"
17718
17719 test_224b() { # LU-1039, MRP-303
17720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17721
17722         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17723         cancel_lru_locks osc
17724         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17725         $LCTL set_param fail_loc=0x515
17726         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17727         $LCTL set_param fail_loc=0
17728         df $DIR
17729 }
17730 run_test 224b "Don't panic on bulk IO failure"
17731
17732 test_224c() { # LU-6441
17733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17734         remote_mds_nodsh && skip "remote MDS with nodsh"
17735
17736         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17737         save_writethrough $p
17738         set_cache writethrough on
17739
17740         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17741         local at_max=$($LCTL get_param -n at_max)
17742         local timeout=$($LCTL get_param -n timeout)
17743         local test_at="at_max"
17744         local param_at="$FSNAME.sys.at_max"
17745         local test_timeout="timeout"
17746         local param_timeout="$FSNAME.sys.timeout"
17747
17748         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17749
17750         set_persistent_param_and_check client "$test_at" "$param_at" 0
17751         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17752
17753         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17754         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17755         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17756         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17757         sync
17758         do_facet ost1 "$LCTL set_param fail_loc=0"
17759
17760         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17761         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17762                 $timeout
17763
17764         $LCTL set_param -n $pages_per_rpc
17765         restore_lustre_params < $p
17766         rm -f $p
17767 }
17768 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17769
17770 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17771 test_225a () {
17772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17773         if [ -z ${MDSSURVEY} ]; then
17774                 skip_env "mds-survey not found"
17775         fi
17776         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17777                 skip "Need MDS version at least 2.2.51"
17778
17779         local mds=$(facet_host $SINGLEMDS)
17780         local target=$(do_nodes $mds 'lctl dl' |
17781                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17782
17783         local cmd1="file_count=1000 thrhi=4"
17784         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17785         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17786         local cmd="$cmd1 $cmd2 $cmd3"
17787
17788         rm -f ${TMP}/mds_survey*
17789         echo + $cmd
17790         eval $cmd || error "mds-survey with zero-stripe failed"
17791         cat ${TMP}/mds_survey*
17792         rm -f ${TMP}/mds_survey*
17793 }
17794 run_test 225a "Metadata survey sanity with zero-stripe"
17795
17796 test_225b () {
17797         if [ -z ${MDSSURVEY} ]; then
17798                 skip_env "mds-survey not found"
17799         fi
17800         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17801                 skip "Need MDS version at least 2.2.51"
17802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17803         remote_mds_nodsh && skip "remote MDS with nodsh"
17804         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17805                 skip_env "Need to mount OST to test"
17806         fi
17807
17808         local mds=$(facet_host $SINGLEMDS)
17809         local target=$(do_nodes $mds 'lctl dl' |
17810                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17811
17812         local cmd1="file_count=1000 thrhi=4"
17813         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17814         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17815         local cmd="$cmd1 $cmd2 $cmd3"
17816
17817         rm -f ${TMP}/mds_survey*
17818         echo + $cmd
17819         eval $cmd || error "mds-survey with stripe_count failed"
17820         cat ${TMP}/mds_survey*
17821         rm -f ${TMP}/mds_survey*
17822 }
17823 run_test 225b "Metadata survey sanity with stripe_count = 1"
17824
17825 mcreate_path2fid () {
17826         local mode=$1
17827         local major=$2
17828         local minor=$3
17829         local name=$4
17830         local desc=$5
17831         local path=$DIR/$tdir/$name
17832         local fid
17833         local rc
17834         local fid_path
17835
17836         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17837                 error "cannot create $desc"
17838
17839         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17840         rc=$?
17841         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17842
17843         fid_path=$($LFS fid2path $MOUNT $fid)
17844         rc=$?
17845         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17846
17847         [ "$path" == "$fid_path" ] ||
17848                 error "fid2path returned $fid_path, expected $path"
17849
17850         echo "pass with $path and $fid"
17851 }
17852
17853 test_226a () {
17854         rm -rf $DIR/$tdir
17855         mkdir -p $DIR/$tdir
17856
17857         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17858         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17859         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17860         mcreate_path2fid 0040666 0 0 dir "directory"
17861         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17862         mcreate_path2fid 0100666 0 0 file "regular file"
17863         mcreate_path2fid 0120666 0 0 link "symbolic link"
17864         mcreate_path2fid 0140666 0 0 sock "socket"
17865 }
17866 run_test 226a "call path2fid and fid2path on files of all type"
17867
17868 test_226b () {
17869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17870
17871         local MDTIDX=1
17872
17873         rm -rf $DIR/$tdir
17874         mkdir -p $DIR/$tdir
17875         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17876                 error "create remote directory failed"
17877         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17878         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17879                                 "character special file (null)"
17880         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17881                                 "character special file (no device)"
17882         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17883         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17884                                 "block special file (loop)"
17885         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17886         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17887         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17888 }
17889 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17890
17891 test_226c () {
17892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17893         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17894                 skip "Need MDS version at least 2.13.55"
17895
17896         local submnt=/mnt/submnt
17897         local srcfile=/etc/passwd
17898         local dstfile=$submnt/passwd
17899         local path
17900         local fid
17901
17902         rm -rf $DIR/$tdir
17903         rm -rf $submnt
17904         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17905                 error "create remote directory failed"
17906         mkdir -p $submnt || error "create $submnt failed"
17907         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17908                 error "mount $submnt failed"
17909         stack_trap "umount $submnt" EXIT
17910
17911         cp $srcfile $dstfile
17912         fid=$($LFS path2fid $dstfile)
17913         path=$($LFS fid2path $submnt "$fid")
17914         [ "$path" = "$dstfile" ] ||
17915                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17916 }
17917 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17918
17919 # LU-1299 Executing or running ldd on a truncated executable does not
17920 # cause an out-of-memory condition.
17921 test_227() {
17922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17923         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17924
17925         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17926         chmod +x $MOUNT/date
17927
17928         $MOUNT/date > /dev/null
17929         ldd $MOUNT/date > /dev/null
17930         rm -f $MOUNT/date
17931 }
17932 run_test 227 "running truncated executable does not cause OOM"
17933
17934 # LU-1512 try to reuse idle OI blocks
17935 test_228a() {
17936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17937         remote_mds_nodsh && skip "remote MDS with nodsh"
17938         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17939
17940         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17941         local myDIR=$DIR/$tdir
17942
17943         mkdir -p $myDIR
17944         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17945         $LCTL set_param fail_loc=0x80001002
17946         createmany -o $myDIR/t- 10000
17947         $LCTL set_param fail_loc=0
17948         # The guard is current the largest FID holder
17949         touch $myDIR/guard
17950         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17951                     tr -d '[')
17952         local IDX=$(($SEQ % 64))
17953
17954         do_facet $SINGLEMDS sync
17955         # Make sure journal flushed.
17956         sleep 6
17957         local blk1=$(do_facet $SINGLEMDS \
17958                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17959                      grep Blockcount | awk '{print $4}')
17960
17961         # Remove old files, some OI blocks will become idle.
17962         unlinkmany $myDIR/t- 10000
17963         # Create new files, idle OI blocks should be reused.
17964         createmany -o $myDIR/t- 2000
17965         do_facet $SINGLEMDS sync
17966         # Make sure journal flushed.
17967         sleep 6
17968         local blk2=$(do_facet $SINGLEMDS \
17969                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17970                      grep Blockcount | awk '{print $4}')
17971
17972         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17973 }
17974 run_test 228a "try to reuse idle OI blocks"
17975
17976 test_228b() {
17977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17978         remote_mds_nodsh && skip "remote MDS with nodsh"
17979         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17980
17981         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17982         local myDIR=$DIR/$tdir
17983
17984         mkdir -p $myDIR
17985         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17986         $LCTL set_param fail_loc=0x80001002
17987         createmany -o $myDIR/t- 10000
17988         $LCTL set_param fail_loc=0
17989         # The guard is current the largest FID holder
17990         touch $myDIR/guard
17991         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17992                     tr -d '[')
17993         local IDX=$(($SEQ % 64))
17994
17995         do_facet $SINGLEMDS sync
17996         # Make sure journal flushed.
17997         sleep 6
17998         local blk1=$(do_facet $SINGLEMDS \
17999                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18000                      grep Blockcount | awk '{print $4}')
18001
18002         # Remove old files, some OI blocks will become idle.
18003         unlinkmany $myDIR/t- 10000
18004
18005         # stop the MDT
18006         stop $SINGLEMDS || error "Fail to stop MDT."
18007         # remount the MDT
18008         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18009
18010         df $MOUNT || error "Fail to df."
18011         # Create new files, idle OI blocks should be reused.
18012         createmany -o $myDIR/t- 2000
18013         do_facet $SINGLEMDS sync
18014         # Make sure journal flushed.
18015         sleep 6
18016         local blk2=$(do_facet $SINGLEMDS \
18017                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18018                      grep Blockcount | awk '{print $4}')
18019
18020         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18021 }
18022 run_test 228b "idle OI blocks can be reused after MDT restart"
18023
18024 #LU-1881
18025 test_228c() {
18026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18027         remote_mds_nodsh && skip "remote MDS with nodsh"
18028         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18029
18030         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18031         local myDIR=$DIR/$tdir
18032
18033         mkdir -p $myDIR
18034         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18035         $LCTL set_param fail_loc=0x80001002
18036         # 20000 files can guarantee there are index nodes in the OI file
18037         createmany -o $myDIR/t- 20000
18038         $LCTL set_param fail_loc=0
18039         # The guard is current the largest FID holder
18040         touch $myDIR/guard
18041         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18042                     tr -d '[')
18043         local IDX=$(($SEQ % 64))
18044
18045         do_facet $SINGLEMDS sync
18046         # Make sure journal flushed.
18047         sleep 6
18048         local blk1=$(do_facet $SINGLEMDS \
18049                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18050                      grep Blockcount | awk '{print $4}')
18051
18052         # Remove old files, some OI blocks will become idle.
18053         unlinkmany $myDIR/t- 20000
18054         rm -f $myDIR/guard
18055         # The OI file should become empty now
18056
18057         # Create new files, idle OI blocks should be reused.
18058         createmany -o $myDIR/t- 2000
18059         do_facet $SINGLEMDS sync
18060         # Make sure journal flushed.
18061         sleep 6
18062         local blk2=$(do_facet $SINGLEMDS \
18063                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18064                      grep Blockcount | awk '{print $4}')
18065
18066         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18067 }
18068 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18069
18070 test_229() { # LU-2482, LU-3448
18071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18072         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18073         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18074                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18075
18076         rm -f $DIR/$tfile
18077
18078         # Create a file with a released layout and stripe count 2.
18079         $MULTIOP $DIR/$tfile H2c ||
18080                 error "failed to create file with released layout"
18081
18082         $LFS getstripe -v $DIR/$tfile
18083
18084         local pattern=$($LFS getstripe -L $DIR/$tfile)
18085         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18086
18087         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18088                 error "getstripe"
18089         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18090         stat $DIR/$tfile || error "failed to stat released file"
18091
18092         chown $RUNAS_ID $DIR/$tfile ||
18093                 error "chown $RUNAS_ID $DIR/$tfile failed"
18094
18095         chgrp $RUNAS_ID $DIR/$tfile ||
18096                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18097
18098         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18099         rm $DIR/$tfile || error "failed to remove released file"
18100 }
18101 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18102
18103 test_230a() {
18104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18106         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18107                 skip "Need MDS version at least 2.11.52"
18108
18109         local MDTIDX=1
18110
18111         test_mkdir $DIR/$tdir
18112         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18113         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18114         [ $mdt_idx -ne 0 ] &&
18115                 error "create local directory on wrong MDT $mdt_idx"
18116
18117         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18118                         error "create remote directory failed"
18119         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18120         [ $mdt_idx -ne $MDTIDX ] &&
18121                 error "create remote directory on wrong MDT $mdt_idx"
18122
18123         createmany -o $DIR/$tdir/test_230/t- 10 ||
18124                 error "create files on remote directory failed"
18125         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18126         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18127         rm -r $DIR/$tdir || error "unlink remote directory failed"
18128 }
18129 run_test 230a "Create remote directory and files under the remote directory"
18130
18131 test_230b() {
18132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18134         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18135                 skip "Need MDS version at least 2.11.52"
18136
18137         local MDTIDX=1
18138         local mdt_index
18139         local i
18140         local file
18141         local pid
18142         local stripe_count
18143         local migrate_dir=$DIR/$tdir/migrate_dir
18144         local other_dir=$DIR/$tdir/other_dir
18145
18146         test_mkdir $DIR/$tdir
18147         test_mkdir -i0 -c1 $migrate_dir
18148         test_mkdir -i0 -c1 $other_dir
18149         for ((i=0; i<10; i++)); do
18150                 mkdir -p $migrate_dir/dir_${i}
18151                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18152                         error "create files under remote dir failed $i"
18153         done
18154
18155         cp /etc/passwd $migrate_dir/$tfile
18156         cp /etc/passwd $other_dir/$tfile
18157         chattr +SAD $migrate_dir
18158         chattr +SAD $migrate_dir/$tfile
18159
18160         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18161         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18162         local old_dir_mode=$(stat -c%f $migrate_dir)
18163         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18164
18165         mkdir -p $migrate_dir/dir_default_stripe2
18166         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18167         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18168
18169         mkdir -p $other_dir
18170         ln $migrate_dir/$tfile $other_dir/luna
18171         ln $migrate_dir/$tfile $migrate_dir/sofia
18172         ln $other_dir/$tfile $migrate_dir/david
18173         ln -s $migrate_dir/$tfile $other_dir/zachary
18174         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18175         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18176
18177         local len
18178         local lnktgt
18179
18180         # inline symlink
18181         for len in 58 59 60; do
18182                 lnktgt=$(str_repeat 'l' $len)
18183                 touch $migrate_dir/$lnktgt
18184                 ln -s $lnktgt $migrate_dir/${len}char_ln
18185         done
18186
18187         # PATH_MAX
18188         for len in 4094 4095; do
18189                 lnktgt=$(str_repeat 'l' $len)
18190                 ln -s $lnktgt $migrate_dir/${len}char_ln
18191         done
18192
18193         # NAME_MAX
18194         for len in 254 255; do
18195                 touch $migrate_dir/$(str_repeat 'l' $len)
18196         done
18197
18198         $LFS migrate -m $MDTIDX $migrate_dir ||
18199                 error "fails on migrating remote dir to MDT1"
18200
18201         echo "migratate to MDT1, then checking.."
18202         for ((i = 0; i < 10; i++)); do
18203                 for file in $(find $migrate_dir/dir_${i}); do
18204                         mdt_index=$($LFS getstripe -m $file)
18205                         # broken symlink getstripe will fail
18206                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18207                                 error "$file is not on MDT${MDTIDX}"
18208                 done
18209         done
18210
18211         # the multiple link file should still in MDT0
18212         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18213         [ $mdt_index == 0 ] ||
18214                 error "$file is not on MDT${MDTIDX}"
18215
18216         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18217         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18218                 error " expect $old_dir_flag get $new_dir_flag"
18219
18220         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18221         [ "$old_file_flag" = "$new_file_flag" ] ||
18222                 error " expect $old_file_flag get $new_file_flag"
18223
18224         local new_dir_mode=$(stat -c%f $migrate_dir)
18225         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18226                 error "expect mode $old_dir_mode get $new_dir_mode"
18227
18228         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18229         [ "$old_file_mode" = "$new_file_mode" ] ||
18230                 error "expect mode $old_file_mode get $new_file_mode"
18231
18232         diff /etc/passwd $migrate_dir/$tfile ||
18233                 error "$tfile different after migration"
18234
18235         diff /etc/passwd $other_dir/luna ||
18236                 error "luna different after migration"
18237
18238         diff /etc/passwd $migrate_dir/sofia ||
18239                 error "sofia different after migration"
18240
18241         diff /etc/passwd $migrate_dir/david ||
18242                 error "david different after migration"
18243
18244         diff /etc/passwd $other_dir/zachary ||
18245                 error "zachary different after migration"
18246
18247         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18248                 error "${tfile}_ln different after migration"
18249
18250         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18251                 error "${tfile}_ln_other different after migration"
18252
18253         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18254         [ $stripe_count = 2 ] ||
18255                 error "dir strpe_count $d != 2 after migration."
18256
18257         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18258         [ $stripe_count = 2 ] ||
18259                 error "file strpe_count $d != 2 after migration."
18260
18261         #migrate back to MDT0
18262         MDTIDX=0
18263
18264         $LFS migrate -m $MDTIDX $migrate_dir ||
18265                 error "fails on migrating remote dir to MDT0"
18266
18267         echo "migrate back to MDT0, checking.."
18268         for file in $(find $migrate_dir); do
18269                 mdt_index=$($LFS getstripe -m $file)
18270                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18271                         error "$file is not on MDT${MDTIDX}"
18272         done
18273
18274         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18275         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18276                 error " expect $old_dir_flag get $new_dir_flag"
18277
18278         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18279         [ "$old_file_flag" = "$new_file_flag" ] ||
18280                 error " expect $old_file_flag get $new_file_flag"
18281
18282         local new_dir_mode=$(stat -c%f $migrate_dir)
18283         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18284                 error "expect mode $old_dir_mode get $new_dir_mode"
18285
18286         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18287         [ "$old_file_mode" = "$new_file_mode" ] ||
18288                 error "expect mode $old_file_mode get $new_file_mode"
18289
18290         diff /etc/passwd ${migrate_dir}/$tfile ||
18291                 error "$tfile different after migration"
18292
18293         diff /etc/passwd ${other_dir}/luna ||
18294                 error "luna different after migration"
18295
18296         diff /etc/passwd ${migrate_dir}/sofia ||
18297                 error "sofia different after migration"
18298
18299         diff /etc/passwd ${other_dir}/zachary ||
18300                 error "zachary different after migration"
18301
18302         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18303                 error "${tfile}_ln different after migration"
18304
18305         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18306                 error "${tfile}_ln_other different after migration"
18307
18308         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18309         [ $stripe_count = 2 ] ||
18310                 error "dir strpe_count $d != 2 after migration."
18311
18312         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18313         [ $stripe_count = 2 ] ||
18314                 error "file strpe_count $d != 2 after migration."
18315
18316         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18317 }
18318 run_test 230b "migrate directory"
18319
18320 test_230c() {
18321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18322         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18323         remote_mds_nodsh && skip "remote MDS with nodsh"
18324         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18325                 skip "Need MDS version at least 2.11.52"
18326
18327         local MDTIDX=1
18328         local total=3
18329         local mdt_index
18330         local file
18331         local migrate_dir=$DIR/$tdir/migrate_dir
18332
18333         #If migrating directory fails in the middle, all entries of
18334         #the directory is still accessiable.
18335         test_mkdir $DIR/$tdir
18336         test_mkdir -i0 -c1 $migrate_dir
18337         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18338         stat $migrate_dir
18339         createmany -o $migrate_dir/f $total ||
18340                 error "create files under ${migrate_dir} failed"
18341
18342         # fail after migrating top dir, and this will fail only once, so the
18343         # first sub file migration will fail (currently f3), others succeed.
18344         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18345         do_facet mds1 lctl set_param fail_loc=0x1801
18346         local t=$(ls $migrate_dir | wc -l)
18347         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18348                 error "migrate should fail"
18349         local u=$(ls $migrate_dir | wc -l)
18350         [ "$u" == "$t" ] || error "$u != $t during migration"
18351
18352         # add new dir/file should succeed
18353         mkdir $migrate_dir/dir ||
18354                 error "mkdir failed under migrating directory"
18355         touch $migrate_dir/file ||
18356                 error "create file failed under migrating directory"
18357
18358         # add file with existing name should fail
18359         for file in $migrate_dir/f*; do
18360                 stat $file > /dev/null || error "stat $file failed"
18361                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18362                         error "open(O_CREAT|O_EXCL) $file should fail"
18363                 $MULTIOP $file m && error "create $file should fail"
18364                 touch $DIR/$tdir/remote_dir/$tfile ||
18365                         error "touch $tfile failed"
18366                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18367                         error "link $file should fail"
18368                 mdt_index=$($LFS getstripe -m $file)
18369                 if [ $mdt_index == 0 ]; then
18370                         # file failed to migrate is not allowed to rename to
18371                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18372                                 error "rename to $file should fail"
18373                 else
18374                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18375                                 error "rename to $file failed"
18376                 fi
18377                 echo hello >> $file || error "write $file failed"
18378         done
18379
18380         # resume migration with different options should fail
18381         $LFS migrate -m 0 $migrate_dir &&
18382                 error "migrate -m 0 $migrate_dir should fail"
18383
18384         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18385                 error "migrate -c 2 $migrate_dir should fail"
18386
18387         # resume migration should succeed
18388         $LFS migrate -m $MDTIDX $migrate_dir ||
18389                 error "migrate $migrate_dir failed"
18390
18391         echo "Finish migration, then checking.."
18392         for file in $(find $migrate_dir); do
18393                 mdt_index=$($LFS getstripe -m $file)
18394                 [ $mdt_index == $MDTIDX ] ||
18395                         error "$file is not on MDT${MDTIDX}"
18396         done
18397
18398         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18399 }
18400 run_test 230c "check directory accessiblity if migration failed"
18401
18402 test_230d() {
18403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18405         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18406                 skip "Need MDS version at least 2.11.52"
18407         # LU-11235
18408         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18409
18410         local migrate_dir=$DIR/$tdir/migrate_dir
18411         local old_index
18412         local new_index
18413         local old_count
18414         local new_count
18415         local new_hash
18416         local mdt_index
18417         local i
18418         local j
18419
18420         old_index=$((RANDOM % MDSCOUNT))
18421         old_count=$((MDSCOUNT - old_index))
18422         new_index=$((RANDOM % MDSCOUNT))
18423         new_count=$((MDSCOUNT - new_index))
18424         new_hash=1 # for all_char
18425
18426         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18427         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18428
18429         test_mkdir $DIR/$tdir
18430         test_mkdir -i $old_index -c $old_count $migrate_dir
18431
18432         for ((i=0; i<100; i++)); do
18433                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18434                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18435                         error "create files under remote dir failed $i"
18436         done
18437
18438         echo -n "Migrate from MDT$old_index "
18439         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18440         echo -n "to MDT$new_index"
18441         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18442         echo
18443
18444         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18445         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18446                 error "migrate remote dir error"
18447
18448         echo "Finish migration, then checking.."
18449         for file in $(find $migrate_dir); do
18450                 mdt_index=$($LFS getstripe -m $file)
18451                 if [ $mdt_index -lt $new_index ] ||
18452                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18453                         error "$file is on MDT$mdt_index"
18454                 fi
18455         done
18456
18457         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18458 }
18459 run_test 230d "check migrate big directory"
18460
18461 test_230e() {
18462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18464         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18465                 skip "Need MDS version at least 2.11.52"
18466
18467         local i
18468         local j
18469         local a_fid
18470         local b_fid
18471
18472         mkdir -p $DIR/$tdir
18473         mkdir $DIR/$tdir/migrate_dir
18474         mkdir $DIR/$tdir/other_dir
18475         touch $DIR/$tdir/migrate_dir/a
18476         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18477         ls $DIR/$tdir/other_dir
18478
18479         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18480                 error "migrate dir fails"
18481
18482         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18483         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18484
18485         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18486         [ $mdt_index == 0 ] || error "a is not on MDT0"
18487
18488         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18489                 error "migrate dir fails"
18490
18491         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18492         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18493
18494         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18495         [ $mdt_index == 1 ] || error "a is not on MDT1"
18496
18497         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18498         [ $mdt_index == 1 ] || error "b is not on MDT1"
18499
18500         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18501         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18502
18503         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18504
18505         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18506 }
18507 run_test 230e "migrate mulitple local link files"
18508
18509 test_230f() {
18510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18512         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18513                 skip "Need MDS version at least 2.11.52"
18514
18515         local a_fid
18516         local ln_fid
18517
18518         mkdir -p $DIR/$tdir
18519         mkdir $DIR/$tdir/migrate_dir
18520         $LFS mkdir -i1 $DIR/$tdir/other_dir
18521         touch $DIR/$tdir/migrate_dir/a
18522         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18523         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18524         ls $DIR/$tdir/other_dir
18525
18526         # a should be migrated to MDT1, since no other links on MDT0
18527         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18528                 error "#1 migrate dir fails"
18529         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18530         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18531         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18532         [ $mdt_index == 1 ] || error "a is not on MDT1"
18533
18534         # a should stay on MDT1, because it is a mulitple link file
18535         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18536                 error "#2 migrate dir fails"
18537         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18538         [ $mdt_index == 1 ] || error "a is not on MDT1"
18539
18540         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18541                 error "#3 migrate dir fails"
18542
18543         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18544         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18545         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18546
18547         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18548         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18549
18550         # a should be migrated to MDT0, since no other links on MDT1
18551         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18552                 error "#4 migrate dir fails"
18553         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18554         [ $mdt_index == 0 ] || error "a is not on MDT0"
18555
18556         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18557 }
18558 run_test 230f "migrate mulitple remote link files"
18559
18560 test_230g() {
18561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18563         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18564                 skip "Need MDS version at least 2.11.52"
18565
18566         mkdir -p $DIR/$tdir/migrate_dir
18567
18568         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18569                 error "migrating dir to non-exist MDT succeeds"
18570         true
18571 }
18572 run_test 230g "migrate dir to non-exist MDT"
18573
18574 test_230h() {
18575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18577         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18578                 skip "Need MDS version at least 2.11.52"
18579
18580         local mdt_index
18581
18582         mkdir -p $DIR/$tdir/migrate_dir
18583
18584         $LFS migrate -m1 $DIR &&
18585                 error "migrating mountpoint1 should fail"
18586
18587         $LFS migrate -m1 $DIR/$tdir/.. &&
18588                 error "migrating mountpoint2 should fail"
18589
18590         # same as mv
18591         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18592                 error "migrating $tdir/migrate_dir/.. should fail"
18593
18594         true
18595 }
18596 run_test 230h "migrate .. and root"
18597
18598 test_230i() {
18599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18601         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18602                 skip "Need MDS version at least 2.11.52"
18603
18604         mkdir -p $DIR/$tdir/migrate_dir
18605
18606         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18607                 error "migration fails with a tailing slash"
18608
18609         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18610                 error "migration fails with two tailing slashes"
18611 }
18612 run_test 230i "lfs migrate -m tolerates trailing slashes"
18613
18614 test_230j() {
18615         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18616         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18617                 skip "Need MDS version at least 2.11.52"
18618
18619         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18620         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18621                 error "create $tfile failed"
18622         cat /etc/passwd > $DIR/$tdir/$tfile
18623
18624         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18625
18626         cmp /etc/passwd $DIR/$tdir/$tfile ||
18627                 error "DoM file mismatch after migration"
18628 }
18629 run_test 230j "DoM file data not changed after dir migration"
18630
18631 test_230k() {
18632         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18633         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18634                 skip "Need MDS version at least 2.11.56"
18635
18636         local total=20
18637         local files_on_starting_mdt=0
18638
18639         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18640         $LFS getdirstripe $DIR/$tdir
18641         for i in $(seq $total); do
18642                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18643                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18644                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18645         done
18646
18647         echo "$files_on_starting_mdt files on MDT0"
18648
18649         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18650         $LFS getdirstripe $DIR/$tdir
18651
18652         files_on_starting_mdt=0
18653         for i in $(seq $total); do
18654                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18655                         error "file $tfile.$i mismatch after migration"
18656                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18657                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18658         done
18659
18660         echo "$files_on_starting_mdt files on MDT1 after migration"
18661         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18662
18663         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18664         $LFS getdirstripe $DIR/$tdir
18665
18666         files_on_starting_mdt=0
18667         for i in $(seq $total); do
18668                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18669                         error "file $tfile.$i mismatch after 2nd migration"
18670                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18671                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18672         done
18673
18674         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18675         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18676
18677         true
18678 }
18679 run_test 230k "file data not changed after dir migration"
18680
18681 test_230l() {
18682         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18683         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18684                 skip "Need MDS version at least 2.11.56"
18685
18686         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18687         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18688                 error "create files under remote dir failed $i"
18689         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18690 }
18691 run_test 230l "readdir between MDTs won't crash"
18692
18693 test_230m() {
18694         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18695         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18696                 skip "Need MDS version at least 2.11.56"
18697
18698         local MDTIDX=1
18699         local mig_dir=$DIR/$tdir/migrate_dir
18700         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18701         local shortstr="b"
18702         local val
18703
18704         echo "Creating files and dirs with xattrs"
18705         test_mkdir $DIR/$tdir
18706         test_mkdir -i0 -c1 $mig_dir
18707         mkdir $mig_dir/dir
18708         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18709                 error "cannot set xattr attr1 on dir"
18710         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18711                 error "cannot set xattr attr2 on dir"
18712         touch $mig_dir/dir/f0
18713         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18714                 error "cannot set xattr attr1 on file"
18715         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18716                 error "cannot set xattr attr2 on file"
18717         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18718         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18719         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18720         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18721         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18722         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18723         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18724         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18725         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18726
18727         echo "Migrating to MDT1"
18728         $LFS migrate -m $MDTIDX $mig_dir ||
18729                 error "fails on migrating dir to MDT1"
18730
18731         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18732         echo "Checking xattrs"
18733         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18734         [ "$val" = $longstr ] ||
18735                 error "expecting xattr1 $longstr on dir, found $val"
18736         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18737         [ "$val" = $shortstr ] ||
18738                 error "expecting xattr2 $shortstr on dir, found $val"
18739         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18740         [ "$val" = $longstr ] ||
18741                 error "expecting xattr1 $longstr on file, found $val"
18742         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18743         [ "$val" = $shortstr ] ||
18744                 error "expecting xattr2 $shortstr on file, found $val"
18745 }
18746 run_test 230m "xattrs not changed after dir migration"
18747
18748 test_230n() {
18749         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18750         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18751                 skip "Need MDS version at least 2.13.53"
18752
18753         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18754         cat /etc/hosts > $DIR/$tdir/$tfile
18755         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18756         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18757
18758         cmp /etc/hosts $DIR/$tdir/$tfile ||
18759                 error "File data mismatch after migration"
18760 }
18761 run_test 230n "Dir migration with mirrored file"
18762
18763 test_230o() {
18764         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18765         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18766                 skip "Need MDS version at least 2.13.52"
18767
18768         local mdts=$(comma_list $(mdts_nodes))
18769         local timeout=100
18770
18771         local restripe_status
18772         local delta
18773         local i
18774         local j
18775
18776         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18777
18778         # in case "crush" hash type is not set
18779         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18780
18781         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18782                            mdt.*MDT0000.enable_dir_restripe)
18783         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18784         stack_trap "do_nodes $mdts $LCTL set_param \
18785                     mdt.*.enable_dir_restripe=$restripe_status"
18786
18787         mkdir $DIR/$tdir
18788         createmany -m $DIR/$tdir/f 100 ||
18789                 error "create files under remote dir failed $i"
18790         createmany -d $DIR/$tdir/d 100 ||
18791                 error "create dirs under remote dir failed $i"
18792
18793         for i in $(seq 2 $MDSCOUNT); do
18794                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18795                 $LFS setdirstripe -c $i $DIR/$tdir ||
18796                         error "split -c $i $tdir failed"
18797                 wait_update $HOSTNAME \
18798                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18799                         error "dir split not finished"
18800                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18801                         awk '/migrate/ {sum += $2} END { print sum }')
18802                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18803                 # delta is around total_files/stripe_count
18804                 [ $delta -lt $((200 /(i - 1))) ] ||
18805                         error "$delta files migrated"
18806         done
18807 }
18808 run_test 230o "dir split"
18809
18810 test_230p() {
18811         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18812         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18813                 skip "Need MDS version at least 2.13.52"
18814
18815         local mdts=$(comma_list $(mdts_nodes))
18816         local timeout=100
18817
18818         local restripe_status
18819         local delta
18820         local i
18821         local j
18822
18823         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18824
18825         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18826
18827         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18828                            mdt.*MDT0000.enable_dir_restripe)
18829         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18830         stack_trap "do_nodes $mdts $LCTL set_param \
18831                     mdt.*.enable_dir_restripe=$restripe_status"
18832
18833         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18834         createmany -m $DIR/$tdir/f 100 ||
18835                 error "create files under remote dir failed $i"
18836         createmany -d $DIR/$tdir/d 100 ||
18837                 error "create dirs under remote dir failed $i"
18838
18839         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18840                 local mdt_hash="crush"
18841
18842                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18843                 $LFS setdirstripe -c $i $DIR/$tdir ||
18844                         error "split -c $i $tdir failed"
18845                 [ $i -eq 1 ] && mdt_hash="none"
18846                 wait_update $HOSTNAME \
18847                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18848                         error "dir merge not finished"
18849                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18850                         awk '/migrate/ {sum += $2} END { print sum }')
18851                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18852                 # delta is around total_files/stripe_count
18853                 [ $delta -lt $((200 / i)) ] ||
18854                         error "$delta files migrated"
18855         done
18856 }
18857 run_test 230p "dir merge"
18858
18859 test_230q() {
18860         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18861         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18862                 skip "Need MDS version at least 2.13.52"
18863
18864         local mdts=$(comma_list $(mdts_nodes))
18865         local saved_threshold=$(do_facet mds1 \
18866                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18867         local saved_delta=$(do_facet mds1 \
18868                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18869         local threshold=100
18870         local delta=2
18871         local total=0
18872         local stripe_count=0
18873         local stripe_index
18874         local nr_files
18875
18876         # test with fewer files on ZFS
18877         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18878
18879         stack_trap "do_nodes $mdts $LCTL set_param \
18880                     mdt.*.dir_split_count=$saved_threshold"
18881         stack_trap "do_nodes $mdts $LCTL set_param \
18882                     mdt.*.dir_split_delta=$saved_delta"
18883         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18884         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18885         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18886         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18887         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18888         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18889
18890         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18891         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18892
18893         while [ $stripe_count -lt $MDSCOUNT ]; do
18894                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18895                         error "create sub files failed"
18896                 stat $DIR/$tdir > /dev/null
18897                 total=$((total + threshold * 3 / 2))
18898                 stripe_count=$((stripe_count + delta))
18899                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18900
18901                 wait_update $HOSTNAME \
18902                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18903                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18904
18905                 wait_update $HOSTNAME \
18906                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18907                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18908
18909                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18910                            grep -w $stripe_index | wc -l)
18911                 echo "$nr_files files on MDT$stripe_index after split"
18912                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18913                         error "$nr_files files on MDT$stripe_index after split"
18914
18915                 nr_files=$(ls $DIR/$tdir | wc -w)
18916                 [ $nr_files -eq $total ] ||
18917                         error "total sub files $nr_files != $total"
18918         done
18919 }
18920 run_test 230q "dir auto split"
18921
18922 test_230r() {
18923         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18924         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18925         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18926                 skip "Need MDS version at least 2.13.54"
18927
18928         # maximum amount of local locks:
18929         # parent striped dir - 2 locks
18930         # new stripe in parent to migrate to - 1 lock
18931         # source and target - 2 locks
18932         # Total 5 locks for regular file
18933         mkdir -p $DIR/$tdir
18934         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18935         touch $DIR/$tdir/dir1/eee
18936
18937         # create 4 hardlink for 4 more locks
18938         # Total: 9 locks > RS_MAX_LOCKS (8)
18939         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18940         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18941         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18942         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18943         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18944         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18945         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18946         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18947
18948         cancel_lru_locks mdc
18949
18950         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18951                 error "migrate dir fails"
18952
18953         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18954 }
18955 run_test 230r "migrate with too many local locks"
18956
18957 test_231a()
18958 {
18959         # For simplicity this test assumes that max_pages_per_rpc
18960         # is the same across all OSCs
18961         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18962         local bulk_size=$((max_pages * PAGE_SIZE))
18963         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18964                                        head -n 1)
18965
18966         mkdir -p $DIR/$tdir
18967         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18968                 error "failed to set stripe with -S ${brw_size}M option"
18969
18970         # clear the OSC stats
18971         $LCTL set_param osc.*.stats=0 &>/dev/null
18972         stop_writeback
18973
18974         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18975         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18976                 oflag=direct &>/dev/null || error "dd failed"
18977
18978         sync; sleep 1; sync # just to be safe
18979         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18980         if [ x$nrpcs != "x1" ]; then
18981                 $LCTL get_param osc.*.stats
18982                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18983         fi
18984
18985         start_writeback
18986         # Drop the OSC cache, otherwise we will read from it
18987         cancel_lru_locks osc
18988
18989         # clear the OSC stats
18990         $LCTL set_param osc.*.stats=0 &>/dev/null
18991
18992         # Client reads $bulk_size.
18993         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18994                 iflag=direct &>/dev/null || error "dd failed"
18995
18996         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18997         if [ x$nrpcs != "x1" ]; then
18998                 $LCTL get_param osc.*.stats
18999                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19000         fi
19001 }
19002 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19003
19004 test_231b() {
19005         mkdir -p $DIR/$tdir
19006         local i
19007         for i in {0..1023}; do
19008                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19009                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19010                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19011         done
19012         sync
19013 }
19014 run_test 231b "must not assert on fully utilized OST request buffer"
19015
19016 test_232a() {
19017         mkdir -p $DIR/$tdir
19018         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19019
19020         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19021         do_facet ost1 $LCTL set_param fail_loc=0x31c
19022
19023         # ignore dd failure
19024         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19025
19026         do_facet ost1 $LCTL set_param fail_loc=0
19027         umount_client $MOUNT || error "umount failed"
19028         mount_client $MOUNT || error "mount failed"
19029         stop ost1 || error "cannot stop ost1"
19030         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19031 }
19032 run_test 232a "failed lock should not block umount"
19033
19034 test_232b() {
19035         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19036                 skip "Need MDS version at least 2.10.58"
19037
19038         mkdir -p $DIR/$tdir
19039         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19040         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19041         sync
19042         cancel_lru_locks osc
19043
19044         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19045         do_facet ost1 $LCTL set_param fail_loc=0x31c
19046
19047         # ignore failure
19048         $LFS data_version $DIR/$tdir/$tfile || true
19049
19050         do_facet ost1 $LCTL set_param fail_loc=0
19051         umount_client $MOUNT || error "umount failed"
19052         mount_client $MOUNT || error "mount failed"
19053         stop ost1 || error "cannot stop ost1"
19054         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19055 }
19056 run_test 232b "failed data version lock should not block umount"
19057
19058 test_233a() {
19059         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19060                 skip "Need MDS version at least 2.3.64"
19061         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19062
19063         local fid=$($LFS path2fid $MOUNT)
19064
19065         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19066                 error "cannot access $MOUNT using its FID '$fid'"
19067 }
19068 run_test 233a "checking that OBF of the FS root succeeds"
19069
19070 test_233b() {
19071         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19072                 skip "Need MDS version at least 2.5.90"
19073         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19074
19075         local fid=$($LFS path2fid $MOUNT/.lustre)
19076
19077         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19078                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19079
19080         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19081         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19082                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19083 }
19084 run_test 233b "checking that OBF of the FS .lustre succeeds"
19085
19086 test_234() {
19087         local p="$TMP/sanityN-$TESTNAME.parameters"
19088         save_lustre_params client "llite.*.xattr_cache" > $p
19089         lctl set_param llite.*.xattr_cache 1 ||
19090                 skip_env "xattr cache is not supported"
19091
19092         mkdir -p $DIR/$tdir || error "mkdir failed"
19093         touch $DIR/$tdir/$tfile || error "touch failed"
19094         # OBD_FAIL_LLITE_XATTR_ENOMEM
19095         $LCTL set_param fail_loc=0x1405
19096         getfattr -n user.attr $DIR/$tdir/$tfile &&
19097                 error "getfattr should have failed with ENOMEM"
19098         $LCTL set_param fail_loc=0x0
19099         rm -rf $DIR/$tdir
19100
19101         restore_lustre_params < $p
19102         rm -f $p
19103 }
19104 run_test 234 "xattr cache should not crash on ENOMEM"
19105
19106 test_235() {
19107         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19108                 skip "Need MDS version at least 2.4.52"
19109
19110         flock_deadlock $DIR/$tfile
19111         local RC=$?
19112         case $RC in
19113                 0)
19114                 ;;
19115                 124) error "process hangs on a deadlock"
19116                 ;;
19117                 *) error "error executing flock_deadlock $DIR/$tfile"
19118                 ;;
19119         esac
19120 }
19121 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19122
19123 #LU-2935
19124 test_236() {
19125         check_swap_layouts_support
19126
19127         local ref1=/etc/passwd
19128         local ref2=/etc/group
19129         local file1=$DIR/$tdir/f1
19130         local file2=$DIR/$tdir/f2
19131
19132         test_mkdir -c1 $DIR/$tdir
19133         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19134         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19135         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19136         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19137         local fd=$(free_fd)
19138         local cmd="exec $fd<>$file2"
19139         eval $cmd
19140         rm $file2
19141         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19142                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19143         cmd="exec $fd>&-"
19144         eval $cmd
19145         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19146
19147         #cleanup
19148         rm -rf $DIR/$tdir
19149 }
19150 run_test 236 "Layout swap on open unlinked file"
19151
19152 # LU-4659 linkea consistency
19153 test_238() {
19154         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19155                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19156                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19157                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19158
19159         touch $DIR/$tfile
19160         ln $DIR/$tfile $DIR/$tfile.lnk
19161         touch $DIR/$tfile.new
19162         mv $DIR/$tfile.new $DIR/$tfile
19163         local fid1=$($LFS path2fid $DIR/$tfile)
19164         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19165         local path1=$($LFS fid2path $FSNAME "$fid1")
19166         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19167         local path2=$($LFS fid2path $FSNAME "$fid2")
19168         [ $tfile.lnk == $path2 ] ||
19169                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19170         rm -f $DIR/$tfile*
19171 }
19172 run_test 238 "Verify linkea consistency"
19173
19174 test_239A() { # was test_239
19175         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19176                 skip "Need MDS version at least 2.5.60"
19177
19178         local list=$(comma_list $(mdts_nodes))
19179
19180         mkdir -p $DIR/$tdir
19181         createmany -o $DIR/$tdir/f- 5000
19182         unlinkmany $DIR/$tdir/f- 5000
19183         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19184                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19185         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19186                         osp.*MDT*.sync_in_flight" | calc_sum)
19187         [ "$changes" -eq 0 ] || error "$changes not synced"
19188 }
19189 run_test 239A "osp_sync test"
19190
19191 test_239a() { #LU-5297
19192         remote_mds_nodsh && skip "remote MDS with nodsh"
19193
19194         touch $DIR/$tfile
19195         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19196         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19197         chgrp $RUNAS_GID $DIR/$tfile
19198         wait_delete_completed
19199 }
19200 run_test 239a "process invalid osp sync record correctly"
19201
19202 test_239b() { #LU-5297
19203         remote_mds_nodsh && skip "remote MDS with nodsh"
19204
19205         touch $DIR/$tfile1
19206         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19207         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19208         chgrp $RUNAS_GID $DIR/$tfile1
19209         wait_delete_completed
19210         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19211         touch $DIR/$tfile2
19212         chgrp $RUNAS_GID $DIR/$tfile2
19213         wait_delete_completed
19214 }
19215 run_test 239b "process osp sync record with ENOMEM error correctly"
19216
19217 test_240() {
19218         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19219         remote_mds_nodsh && skip "remote MDS with nodsh"
19220
19221         mkdir -p $DIR/$tdir
19222
19223         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19224                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19225         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19226                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19227
19228         umount_client $MOUNT || error "umount failed"
19229         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19230         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19231         mount_client $MOUNT || error "failed to mount client"
19232
19233         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19234         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19235 }
19236 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19237
19238 test_241_bio() {
19239         local count=$1
19240         local bsize=$2
19241
19242         for LOOP in $(seq $count); do
19243                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19244                 cancel_lru_locks $OSC || true
19245         done
19246 }
19247
19248 test_241_dio() {
19249         local count=$1
19250         local bsize=$2
19251
19252         for LOOP in $(seq $1); do
19253                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19254                         2>/dev/null
19255         done
19256 }
19257
19258 test_241a() { # was test_241
19259         local bsize=$PAGE_SIZE
19260
19261         (( bsize < 40960 )) && bsize=40960
19262         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19263         ls -la $DIR/$tfile
19264         cancel_lru_locks $OSC
19265         test_241_bio 1000 $bsize &
19266         PID=$!
19267         test_241_dio 1000 $bsize
19268         wait $PID
19269 }
19270 run_test 241a "bio vs dio"
19271
19272 test_241b() {
19273         local bsize=$PAGE_SIZE
19274
19275         (( bsize < 40960 )) && bsize=40960
19276         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19277         ls -la $DIR/$tfile
19278         test_241_dio 1000 $bsize &
19279         PID=$!
19280         test_241_dio 1000 $bsize
19281         wait $PID
19282 }
19283 run_test 241b "dio vs dio"
19284
19285 test_242() {
19286         remote_mds_nodsh && skip "remote MDS with nodsh"
19287
19288         mkdir -p $DIR/$tdir
19289         touch $DIR/$tdir/$tfile
19290
19291         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19292         do_facet mds1 lctl set_param fail_loc=0x105
19293         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19294
19295         do_facet mds1 lctl set_param fail_loc=0
19296         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19297 }
19298 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19299
19300 test_243()
19301 {
19302         test_mkdir $DIR/$tdir
19303         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19304 }
19305 run_test 243 "various group lock tests"
19306
19307 test_244a()
19308 {
19309         test_mkdir $DIR/$tdir
19310         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19311         sendfile_grouplock $DIR/$tdir/$tfile || \
19312                 error "sendfile+grouplock failed"
19313         rm -rf $DIR/$tdir
19314 }
19315 run_test 244a "sendfile with group lock tests"
19316
19317 test_244b()
19318 {
19319         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19320
19321         local threads=50
19322         local size=$((1024*1024))
19323
19324         test_mkdir $DIR/$tdir
19325         for i in $(seq 1 $threads); do
19326                 local file=$DIR/$tdir/file_$((i / 10))
19327                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19328                 local pids[$i]=$!
19329         done
19330         for i in $(seq 1 $threads); do
19331                 wait ${pids[$i]}
19332         done
19333 }
19334 run_test 244b "multi-threaded write with group lock"
19335
19336 test_245() {
19337         local flagname="multi_mod_rpcs"
19338         local connect_data_name="max_mod_rpcs"
19339         local out
19340
19341         # check if multiple modify RPCs flag is set
19342         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19343                 grep "connect_flags:")
19344         echo "$out"
19345
19346         echo "$out" | grep -qw $flagname
19347         if [ $? -ne 0 ]; then
19348                 echo "connect flag $flagname is not set"
19349                 return
19350         fi
19351
19352         # check if multiple modify RPCs data is set
19353         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19354         echo "$out"
19355
19356         echo "$out" | grep -qw $connect_data_name ||
19357                 error "import should have connect data $connect_data_name"
19358 }
19359 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19360
19361 cleanup_247() {
19362         local submount=$1
19363
19364         trap 0
19365         umount_client $submount
19366         rmdir $submount
19367 }
19368
19369 test_247a() {
19370         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19371                 grep -q subtree ||
19372                 skip_env "Fileset feature is not supported"
19373
19374         local submount=${MOUNT}_$tdir
19375
19376         mkdir $MOUNT/$tdir
19377         mkdir -p $submount || error "mkdir $submount failed"
19378         FILESET="$FILESET/$tdir" mount_client $submount ||
19379                 error "mount $submount failed"
19380         trap "cleanup_247 $submount" EXIT
19381         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19382         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19383                 error "read $MOUNT/$tdir/$tfile failed"
19384         cleanup_247 $submount
19385 }
19386 run_test 247a "mount subdir as fileset"
19387
19388 test_247b() {
19389         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19390                 skip_env "Fileset feature is not supported"
19391
19392         local submount=${MOUNT}_$tdir
19393
19394         rm -rf $MOUNT/$tdir
19395         mkdir -p $submount || error "mkdir $submount failed"
19396         SKIP_FILESET=1
19397         FILESET="$FILESET/$tdir" mount_client $submount &&
19398                 error "mount $submount should fail"
19399         rmdir $submount
19400 }
19401 run_test 247b "mount subdir that dose not exist"
19402
19403 test_247c() {
19404         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19405                 skip_env "Fileset feature is not supported"
19406
19407         local submount=${MOUNT}_$tdir
19408
19409         mkdir -p $MOUNT/$tdir/dir1
19410         mkdir -p $submount || error "mkdir $submount failed"
19411         trap "cleanup_247 $submount" EXIT
19412         FILESET="$FILESET/$tdir" mount_client $submount ||
19413                 error "mount $submount failed"
19414         local fid=$($LFS path2fid $MOUNT/)
19415         $LFS fid2path $submount $fid && error "fid2path should fail"
19416         cleanup_247 $submount
19417 }
19418 run_test 247c "running fid2path outside subdirectory root"
19419
19420 test_247d() {
19421         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19422                 skip "Fileset feature is not supported"
19423
19424         local submount=${MOUNT}_$tdir
19425
19426         mkdir -p $MOUNT/$tdir/dir1
19427         mkdir -p $submount || error "mkdir $submount failed"
19428         FILESET="$FILESET/$tdir" mount_client $submount ||
19429                 error "mount $submount failed"
19430         trap "cleanup_247 $submount" EXIT
19431
19432         local td=$submount/dir1
19433         local fid=$($LFS path2fid $td)
19434         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19435
19436         # check that we get the same pathname back
19437         local rootpath
19438         local found
19439         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19440                 echo "$rootpath $fid"
19441                 found=$($LFS fid2path $rootpath "$fid")
19442                 [ -n "found" ] || error "fid2path should succeed"
19443                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19444         done
19445         # check wrong root path format
19446         rootpath=$submount"_wrong"
19447         found=$($LFS fid2path $rootpath "$fid")
19448         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19449
19450         cleanup_247 $submount
19451 }
19452 run_test 247d "running fid2path inside subdirectory root"
19453
19454 # LU-8037
19455 test_247e() {
19456         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19457                 grep -q subtree ||
19458                 skip "Fileset feature is not supported"
19459
19460         local submount=${MOUNT}_$tdir
19461
19462         mkdir $MOUNT/$tdir
19463         mkdir -p $submount || error "mkdir $submount failed"
19464         FILESET="$FILESET/.." mount_client $submount &&
19465                 error "mount $submount should fail"
19466         rmdir $submount
19467 }
19468 run_test 247e "mount .. as fileset"
19469
19470 test_247f() {
19471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19472         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19473                 skip "Need at least version 2.13.52"
19474         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19475                 grep -q subtree ||
19476                 skip "Fileset feature is not supported"
19477
19478         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19479         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19480                 error "mkdir remote failed"
19481         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19482         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19483                 error "mkdir striped failed"
19484         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19485
19486         local submount=${MOUNT}_$tdir
19487
19488         mkdir -p $submount || error "mkdir $submount failed"
19489
19490         local dir
19491         local fileset=$FILESET
19492
19493         for dir in $tdir/remote $tdir/remote/subdir \
19494                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19495                 FILESET="$fileset/$dir" mount_client $submount ||
19496                         error "mount $dir failed"
19497                 umount_client $submount
19498         done
19499 }
19500 run_test 247f "mount striped or remote directory as fileset"
19501
19502 test_248a() {
19503         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19504         [ -z "$fast_read_sav" ] && skip "no fast read support"
19505
19506         # create a large file for fast read verification
19507         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19508
19509         # make sure the file is created correctly
19510         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19511                 { rm -f $DIR/$tfile; skip "file creation error"; }
19512
19513         echo "Test 1: verify that fast read is 4 times faster on cache read"
19514
19515         # small read with fast read enabled
19516         $LCTL set_param -n llite.*.fast_read=1
19517         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19518                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19519                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19520         # small read with fast read disabled
19521         $LCTL set_param -n llite.*.fast_read=0
19522         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19523                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19524                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19525
19526         # verify that fast read is 4 times faster for cache read
19527         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19528                 error_not_in_vm "fast read was not 4 times faster: " \
19529                            "$t_fast vs $t_slow"
19530
19531         echo "Test 2: verify the performance between big and small read"
19532         $LCTL set_param -n llite.*.fast_read=1
19533
19534         # 1k non-cache read
19535         cancel_lru_locks osc
19536         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19537                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19538                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19539
19540         # 1M non-cache read
19541         cancel_lru_locks osc
19542         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19543                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19544                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19545
19546         # verify that big IO is not 4 times faster than small IO
19547         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19548                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19549
19550         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19551         rm -f $DIR/$tfile
19552 }
19553 run_test 248a "fast read verification"
19554
19555 test_248b() {
19556         # Default short_io_bytes=16384, try both smaller and larger sizes.
19557         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19558         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19559         echo "bs=53248 count=113 normal buffered write"
19560         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19561                 error "dd of initial data file failed"
19562         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19563
19564         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19565         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19566                 error "dd with sync normal writes failed"
19567         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19568
19569         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19570         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19571                 error "dd with sync small writes failed"
19572         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19573
19574         cancel_lru_locks osc
19575
19576         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19577         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19578         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19579         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19580                 iflag=direct || error "dd with O_DIRECT small read failed"
19581         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19582         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19583                 error "compare $TMP/$tfile.1 failed"
19584
19585         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19586         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19587
19588         # just to see what the maximum tunable value is, and test parsing
19589         echo "test invalid parameter 2MB"
19590         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19591                 error "too-large short_io_bytes allowed"
19592         echo "test maximum parameter 512KB"
19593         # if we can set a larger short_io_bytes, run test regardless of version
19594         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19595                 # older clients may not allow setting it this large, that's OK
19596                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19597                         skip "Need at least client version 2.13.50"
19598                 error "medium short_io_bytes failed"
19599         fi
19600         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19601         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19602
19603         echo "test large parameter 64KB"
19604         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19605         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19606
19607         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19608         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19609                 error "dd with sync large writes failed"
19610         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19611
19612         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19613         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19614         num=$((113 * 4096 / PAGE_SIZE))
19615         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19616         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19617                 error "dd with O_DIRECT large writes failed"
19618         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19619                 error "compare $DIR/$tfile.3 failed"
19620
19621         cancel_lru_locks osc
19622
19623         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19624         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19625                 error "dd with O_DIRECT large read failed"
19626         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19627                 error "compare $TMP/$tfile.2 failed"
19628
19629         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19630         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19631                 error "dd with O_DIRECT large read failed"
19632         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19633                 error "compare $TMP/$tfile.3 failed"
19634 }
19635 run_test 248b "test short_io read and write for both small and large sizes"
19636
19637 test_249() { # LU-7890
19638         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19639                 skip "Need at least version 2.8.54"
19640
19641         rm -f $DIR/$tfile
19642         $LFS setstripe -c 1 $DIR/$tfile
19643         # Offset 2T == 4k * 512M
19644         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19645                 error "dd to 2T offset failed"
19646 }
19647 run_test 249 "Write above 2T file size"
19648
19649 test_250() {
19650         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19651          && skip "no 16TB file size limit on ZFS"
19652
19653         $LFS setstripe -c 1 $DIR/$tfile
19654         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19655         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19656         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19657         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19658                 conv=notrunc,fsync && error "append succeeded"
19659         return 0
19660 }
19661 run_test 250 "Write above 16T limit"
19662
19663 test_251() {
19664         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19665
19666         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19667         #Skip once - writing the first stripe will succeed
19668         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19669         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19670                 error "short write happened"
19671
19672         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19673         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19674                 error "short read happened"
19675
19676         rm -f $DIR/$tfile
19677 }
19678 run_test 251 "Handling short read and write correctly"
19679
19680 test_252() {
19681         remote_mds_nodsh && skip "remote MDS with nodsh"
19682         remote_ost_nodsh && skip "remote OST with nodsh"
19683         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19684                 skip_env "ldiskfs only test"
19685         fi
19686
19687         local tgt
19688         local dev
19689         local out
19690         local uuid
19691         local num
19692         local gen
19693
19694         # check lr_reader on OST0000
19695         tgt=ost1
19696         dev=$(facet_device $tgt)
19697         out=$(do_facet $tgt $LR_READER $dev)
19698         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19699         echo "$out"
19700         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19701         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19702                 error "Invalid uuid returned by $LR_READER on target $tgt"
19703         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19704
19705         # check lr_reader -c on MDT0000
19706         tgt=mds1
19707         dev=$(facet_device $tgt)
19708         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19709                 skip "$LR_READER does not support additional options"
19710         fi
19711         out=$(do_facet $tgt $LR_READER -c $dev)
19712         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19713         echo "$out"
19714         num=$(echo "$out" | grep -c "mdtlov")
19715         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19716                 error "Invalid number of mdtlov clients returned by $LR_READER"
19717         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19718
19719         # check lr_reader -cr on MDT0000
19720         out=$(do_facet $tgt $LR_READER -cr $dev)
19721         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19722         echo "$out"
19723         echo "$out" | grep -q "^reply_data:$" ||
19724                 error "$LR_READER should have returned 'reply_data' section"
19725         num=$(echo "$out" | grep -c "client_generation")
19726         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19727 }
19728 run_test 252 "check lr_reader tool"
19729
19730 test_253() {
19731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19732         remote_mds_nodsh && skip "remote MDS with nodsh"
19733         remote_mgs_nodsh && skip "remote MGS with nodsh"
19734
19735         local ostidx=0
19736         local rc=0
19737         local ost_name=$(ostname_from_index $ostidx)
19738
19739         # on the mdt's osc
19740         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19741         do_facet $SINGLEMDS $LCTL get_param -n \
19742                 osp.$mdtosc_proc1.reserved_mb_high ||
19743                 skip  "remote MDS does not support reserved_mb_high"
19744
19745         rm -rf $DIR/$tdir
19746         wait_mds_ost_sync
19747         wait_delete_completed
19748         mkdir $DIR/$tdir
19749
19750         pool_add $TESTNAME || error "Pool creation failed"
19751         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19752
19753         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19754                 error "Setstripe failed"
19755
19756         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19757
19758         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19759                     grep "watermarks")
19760         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19761
19762         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19763                         osp.$mdtosc_proc1.prealloc_status)
19764         echo "prealloc_status $oa_status"
19765
19766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19767                 error "File creation should fail"
19768
19769         #object allocation was stopped, but we still able to append files
19770         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19771                 oflag=append || error "Append failed"
19772
19773         rm -f $DIR/$tdir/$tfile.0
19774
19775         # For this test, we want to delete the files we created to go out of
19776         # space but leave the watermark, so we remain nearly out of space
19777         ost_watermarks_enospc_delete_files $tfile $ostidx
19778
19779         wait_delete_completed
19780
19781         sleep_maxage
19782
19783         for i in $(seq 10 12); do
19784                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19785                         2>/dev/null || error "File creation failed after rm"
19786         done
19787
19788         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19789                         osp.$mdtosc_proc1.prealloc_status)
19790         echo "prealloc_status $oa_status"
19791
19792         if (( oa_status != 0 )); then
19793                 error "Object allocation still disable after rm"
19794         fi
19795 }
19796 run_test 253 "Check object allocation limit"
19797
19798 test_254() {
19799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19800         remote_mds_nodsh && skip "remote MDS with nodsh"
19801         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19802                 skip "MDS does not support changelog_size"
19803
19804         local cl_user
19805         local MDT0=$(facet_svc $SINGLEMDS)
19806
19807         changelog_register || error "changelog_register failed"
19808
19809         changelog_clear 0 || error "changelog_clear failed"
19810
19811         local size1=$(do_facet $SINGLEMDS \
19812                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19813         echo "Changelog size $size1"
19814
19815         rm -rf $DIR/$tdir
19816         $LFS mkdir -i 0 $DIR/$tdir
19817         # change something
19818         mkdir -p $DIR/$tdir/pics/2008/zachy
19819         touch $DIR/$tdir/pics/2008/zachy/timestamp
19820         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19821         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19822         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19823         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19824         rm $DIR/$tdir/pics/desktop.jpg
19825
19826         local size2=$(do_facet $SINGLEMDS \
19827                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19828         echo "Changelog size after work $size2"
19829
19830         (( $size2 > $size1 )) ||
19831                 error "new Changelog size=$size2 less than old size=$size1"
19832 }
19833 run_test 254 "Check changelog size"
19834
19835 ladvise_no_type()
19836 {
19837         local type=$1
19838         local file=$2
19839
19840         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19841                 awk -F: '{print $2}' | grep $type > /dev/null
19842         if [ $? -ne 0 ]; then
19843                 return 0
19844         fi
19845         return 1
19846 }
19847
19848 ladvise_no_ioctl()
19849 {
19850         local file=$1
19851
19852         lfs ladvise -a willread $file > /dev/null 2>&1
19853         if [ $? -eq 0 ]; then
19854                 return 1
19855         fi
19856
19857         lfs ladvise -a willread $file 2>&1 |
19858                 grep "Inappropriate ioctl for device" > /dev/null
19859         if [ $? -eq 0 ]; then
19860                 return 0
19861         fi
19862         return 1
19863 }
19864
19865 percent() {
19866         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19867 }
19868
19869 # run a random read IO workload
19870 # usage: random_read_iops <filename> <filesize> <iosize>
19871 random_read_iops() {
19872         local file=$1
19873         local fsize=$2
19874         local iosize=${3:-4096}
19875
19876         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19877                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19878 }
19879
19880 drop_file_oss_cache() {
19881         local file="$1"
19882         local nodes="$2"
19883
19884         $LFS ladvise -a dontneed $file 2>/dev/null ||
19885                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19886 }
19887
19888 ladvise_willread_performance()
19889 {
19890         local repeat=10
19891         local average_origin=0
19892         local average_cache=0
19893         local average_ladvise=0
19894
19895         for ((i = 1; i <= $repeat; i++)); do
19896                 echo "Iter $i/$repeat: reading without willread hint"
19897                 cancel_lru_locks osc
19898                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19899                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19900                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19901                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19902
19903                 cancel_lru_locks osc
19904                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19905                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19906                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19907
19908                 cancel_lru_locks osc
19909                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19910                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19911                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19912                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19913                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19914         done
19915         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19916         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19917         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19918
19919         speedup_cache=$(percent $average_cache $average_origin)
19920         speedup_ladvise=$(percent $average_ladvise $average_origin)
19921
19922         echo "Average uncached read: $average_origin"
19923         echo "Average speedup with OSS cached read: " \
19924                 "$average_cache = +$speedup_cache%"
19925         echo "Average speedup with ladvise willread: " \
19926                 "$average_ladvise = +$speedup_ladvise%"
19927
19928         local lowest_speedup=20
19929         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19930                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19931                         "got $average_cache%. Skipping ladvise willread check."
19932                 return 0
19933         fi
19934
19935         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19936         # it is still good to run until then to exercise 'ladvise willread'
19937         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19938                 [ "$ost1_FSTYPE" = "zfs" ] &&
19939                 echo "osd-zfs does not support dontneed or drop_caches" &&
19940                 return 0
19941
19942         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19943         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19944                 error_not_in_vm "Speedup with willread is less than " \
19945                         "$lowest_speedup%, got $average_ladvise%"
19946 }
19947
19948 test_255a() {
19949         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19950                 skip "lustre < 2.8.54 does not support ladvise "
19951         remote_ost_nodsh && skip "remote OST with nodsh"
19952
19953         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19954
19955         ladvise_no_type willread $DIR/$tfile &&
19956                 skip "willread ladvise is not supported"
19957
19958         ladvise_no_ioctl $DIR/$tfile &&
19959                 skip "ladvise ioctl is not supported"
19960
19961         local size_mb=100
19962         local size=$((size_mb * 1048576))
19963         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19964                 error "dd to $DIR/$tfile failed"
19965
19966         lfs ladvise -a willread $DIR/$tfile ||
19967                 error "Ladvise failed with no range argument"
19968
19969         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19970                 error "Ladvise failed with no -l or -e argument"
19971
19972         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19973                 error "Ladvise failed with only -e argument"
19974
19975         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19976                 error "Ladvise failed with only -l argument"
19977
19978         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19979                 error "End offset should not be smaller than start offset"
19980
19981         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19982                 error "End offset should not be equal to start offset"
19983
19984         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19985                 error "Ladvise failed with overflowing -s argument"
19986
19987         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19988                 error "Ladvise failed with overflowing -e argument"
19989
19990         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19991                 error "Ladvise failed with overflowing -l argument"
19992
19993         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19994                 error "Ladvise succeeded with conflicting -l and -e arguments"
19995
19996         echo "Synchronous ladvise should wait"
19997         local delay=4
19998 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19999         do_nodes $(comma_list $(osts_nodes)) \
20000                 $LCTL set_param fail_val=$delay fail_loc=0x237
20001
20002         local start_ts=$SECONDS
20003         lfs ladvise -a willread $DIR/$tfile ||
20004                 error "Ladvise failed with no range argument"
20005         local end_ts=$SECONDS
20006         local inteval_ts=$((end_ts - start_ts))
20007
20008         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20009                 error "Synchronous advice didn't wait reply"
20010         fi
20011
20012         echo "Asynchronous ladvise shouldn't wait"
20013         local start_ts=$SECONDS
20014         lfs ladvise -a willread -b $DIR/$tfile ||
20015                 error "Ladvise failed with no range argument"
20016         local end_ts=$SECONDS
20017         local inteval_ts=$((end_ts - start_ts))
20018
20019         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20020                 error "Asynchronous advice blocked"
20021         fi
20022
20023         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20024         ladvise_willread_performance
20025 }
20026 run_test 255a "check 'lfs ladvise -a willread'"
20027
20028 facet_meminfo() {
20029         local facet=$1
20030         local info=$2
20031
20032         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20033 }
20034
20035 test_255b() {
20036         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20037                 skip "lustre < 2.8.54 does not support ladvise "
20038         remote_ost_nodsh && skip "remote OST with nodsh"
20039
20040         lfs setstripe -c 1 -i 0 $DIR/$tfile
20041
20042         ladvise_no_type dontneed $DIR/$tfile &&
20043                 skip "dontneed ladvise is not supported"
20044
20045         ladvise_no_ioctl $DIR/$tfile &&
20046                 skip "ladvise ioctl is not supported"
20047
20048         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20049                 [ "$ost1_FSTYPE" = "zfs" ] &&
20050                 skip "zfs-osd does not support 'ladvise dontneed'"
20051
20052         local size_mb=100
20053         local size=$((size_mb * 1048576))
20054         # In order to prevent disturbance of other processes, only check 3/4
20055         # of the memory usage
20056         local kibibytes=$((size_mb * 1024 * 3 / 4))
20057
20058         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20059                 error "dd to $DIR/$tfile failed"
20060
20061         #force write to complete before dropping OST cache & checking memory
20062         sync
20063
20064         local total=$(facet_meminfo ost1 MemTotal)
20065         echo "Total memory: $total KiB"
20066
20067         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20068         local before_read=$(facet_meminfo ost1 Cached)
20069         echo "Cache used before read: $before_read KiB"
20070
20071         lfs ladvise -a willread $DIR/$tfile ||
20072                 error "Ladvise willread failed"
20073         local after_read=$(facet_meminfo ost1 Cached)
20074         echo "Cache used after read: $after_read KiB"
20075
20076         lfs ladvise -a dontneed $DIR/$tfile ||
20077                 error "Ladvise dontneed again failed"
20078         local no_read=$(facet_meminfo ost1 Cached)
20079         echo "Cache used after dontneed ladvise: $no_read KiB"
20080
20081         if [ $total -lt $((before_read + kibibytes)) ]; then
20082                 echo "Memory is too small, abort checking"
20083                 return 0
20084         fi
20085
20086         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20087                 error "Ladvise willread should use more memory" \
20088                         "than $kibibytes KiB"
20089         fi
20090
20091         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20092                 error "Ladvise dontneed should release more memory" \
20093                         "than $kibibytes KiB"
20094         fi
20095 }
20096 run_test 255b "check 'lfs ladvise -a dontneed'"
20097
20098 test_255c() {
20099         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20100                 skip "lustre < 2.10.50 does not support lockahead"
20101
20102         local ost1_imp=$(get_osc_import_name client ost1)
20103         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20104                          cut -d'.' -f2)
20105         local count
20106         local new_count
20107         local difference
20108         local i
20109         local rc
20110
20111         test_mkdir -p $DIR/$tdir
20112         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20113
20114         #test 10 returns only success/failure
20115         i=10
20116         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20117         rc=$?
20118         if [ $rc -eq 255 ]; then
20119                 error "Ladvise test${i} failed, ${rc}"
20120         fi
20121
20122         #test 11 counts lock enqueue requests, all others count new locks
20123         i=11
20124         count=$(do_facet ost1 \
20125                 $LCTL get_param -n ost.OSS.ost.stats)
20126         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20127
20128         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20129         rc=$?
20130         if [ $rc -eq 255 ]; then
20131                 error "Ladvise test${i} failed, ${rc}"
20132         fi
20133
20134         new_count=$(do_facet ost1 \
20135                 $LCTL get_param -n ost.OSS.ost.stats)
20136         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20137                    awk '{ print $2 }')
20138
20139         difference="$((new_count - count))"
20140         if [ $difference -ne $rc ]; then
20141                 error "Ladvise test${i}, bad enqueue count, returned " \
20142                       "${rc}, actual ${difference}"
20143         fi
20144
20145         for i in $(seq 12 21); do
20146                 # If we do not do this, we run the risk of having too many
20147                 # locks and starting lock cancellation while we are checking
20148                 # lock counts.
20149                 cancel_lru_locks osc
20150
20151                 count=$($LCTL get_param -n \
20152                        ldlm.namespaces.$imp_name.lock_unused_count)
20153
20154                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20155                 rc=$?
20156                 if [ $rc -eq 255 ]; then
20157                         error "Ladvise test ${i} failed, ${rc}"
20158                 fi
20159
20160                 new_count=$($LCTL get_param -n \
20161                        ldlm.namespaces.$imp_name.lock_unused_count)
20162                 difference="$((new_count - count))"
20163
20164                 # Test 15 output is divided by 100 to map down to valid return
20165                 if [ $i -eq 15 ]; then
20166                         rc="$((rc * 100))"
20167                 fi
20168
20169                 if [ $difference -ne $rc ]; then
20170                         error "Ladvise test ${i}, bad lock count, returned " \
20171                               "${rc}, actual ${difference}"
20172                 fi
20173         done
20174
20175         #test 22 returns only success/failure
20176         i=22
20177         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20178         rc=$?
20179         if [ $rc -eq 255 ]; then
20180                 error "Ladvise test${i} failed, ${rc}"
20181         fi
20182 }
20183 run_test 255c "suite of ladvise lockahead tests"
20184
20185 test_256() {
20186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20187         remote_mds_nodsh && skip "remote MDS with nodsh"
20188         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20189         changelog_users $SINGLEMDS | grep "^cl" &&
20190                 skip "active changelog user"
20191
20192         local cl_user
20193         local cat_sl
20194         local mdt_dev
20195
20196         mdt_dev=$(mdsdevname 1)
20197         echo $mdt_dev
20198
20199         changelog_register || error "changelog_register failed"
20200
20201         rm -rf $DIR/$tdir
20202         mkdir -p $DIR/$tdir
20203
20204         changelog_clear 0 || error "changelog_clear failed"
20205
20206         # change something
20207         touch $DIR/$tdir/{1..10}
20208
20209         # stop the MDT
20210         stop $SINGLEMDS || error "Fail to stop MDT"
20211
20212         # remount the MDT
20213
20214         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20215
20216         #after mount new plainllog is used
20217         touch $DIR/$tdir/{11..19}
20218         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20219         stack_trap "rm -f $tmpfile"
20220         cat_sl=$(do_facet $SINGLEMDS "sync; \
20221                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20222                  llog_reader $tmpfile | grep -c type=1064553b")
20223         do_facet $SINGLEMDS llog_reader $tmpfile
20224
20225         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20226
20227         changelog_clear 0 || error "changelog_clear failed"
20228
20229         cat_sl=$(do_facet $SINGLEMDS "sync; \
20230                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20231                  llog_reader $tmpfile | grep -c type=1064553b")
20232
20233         if (( cat_sl == 2 )); then
20234                 error "Empty plain llog was not deleted from changelog catalog"
20235         elif (( cat_sl != 1 )); then
20236                 error "Active plain llog shouldn't be deleted from catalog"
20237         fi
20238 }
20239 run_test 256 "Check llog delete for empty and not full state"
20240
20241 test_257() {
20242         remote_mds_nodsh && skip "remote MDS with nodsh"
20243         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20244                 skip "Need MDS version at least 2.8.55"
20245
20246         test_mkdir $DIR/$tdir
20247
20248         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20249                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20250         stat $DIR/$tdir
20251
20252 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20253         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20254         local facet=mds$((mdtidx + 1))
20255         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20256         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20257
20258         stop $facet || error "stop MDS failed"
20259         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20260                 error "start MDS fail"
20261         wait_recovery_complete $facet
20262 }
20263 run_test 257 "xattr locks are not lost"
20264
20265 # Verify we take the i_mutex when security requires it
20266 test_258a() {
20267 #define OBD_FAIL_IMUTEX_SEC 0x141c
20268         $LCTL set_param fail_loc=0x141c
20269         touch $DIR/$tfile
20270         chmod u+s $DIR/$tfile
20271         chmod a+rwx $DIR/$tfile
20272         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20273         RC=$?
20274         if [ $RC -ne 0 ]; then
20275                 error "error, failed to take i_mutex, rc=$?"
20276         fi
20277         rm -f $DIR/$tfile
20278 }
20279 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20280
20281 # Verify we do NOT take the i_mutex in the normal case
20282 test_258b() {
20283 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20284         $LCTL set_param fail_loc=0x141d
20285         touch $DIR/$tfile
20286         chmod a+rwx $DIR
20287         chmod a+rw $DIR/$tfile
20288         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20289         RC=$?
20290         if [ $RC -ne 0 ]; then
20291                 error "error, took i_mutex unnecessarily, rc=$?"
20292         fi
20293         rm -f $DIR/$tfile
20294
20295 }
20296 run_test 258b "verify i_mutex security behavior"
20297
20298 test_259() {
20299         local file=$DIR/$tfile
20300         local before
20301         local after
20302
20303         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20304
20305         stack_trap "rm -f $file" EXIT
20306
20307         wait_delete_completed
20308         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20309         echo "before: $before"
20310
20311         $LFS setstripe -i 0 -c 1 $file
20312         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20313         sync_all_data
20314         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20315         echo "after write: $after"
20316
20317 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20318         do_facet ost1 $LCTL set_param fail_loc=0x2301
20319         $TRUNCATE $file 0
20320         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20321         echo "after truncate: $after"
20322
20323         stop ost1
20324         do_facet ost1 $LCTL set_param fail_loc=0
20325         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20326         sleep 2
20327         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20328         echo "after restart: $after"
20329         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20330                 error "missing truncate?"
20331
20332         return 0
20333 }
20334 run_test 259 "crash at delayed truncate"
20335
20336 test_260() {
20337 #define OBD_FAIL_MDC_CLOSE               0x806
20338         $LCTL set_param fail_loc=0x80000806
20339         touch $DIR/$tfile
20340
20341 }
20342 run_test 260 "Check mdc_close fail"
20343
20344 ### Data-on-MDT sanity tests ###
20345 test_270a() {
20346         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20347                 skip "Need MDS version at least 2.10.55 for DoM"
20348
20349         # create DoM file
20350         local dom=$DIR/$tdir/dom_file
20351         local tmp=$DIR/$tdir/tmp_file
20352
20353         mkdir -p $DIR/$tdir
20354
20355         # basic checks for DoM component creation
20356         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20357                 error "Can set MDT layout to non-first entry"
20358
20359         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20360                 error "Can define multiple entries as MDT layout"
20361
20362         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20363
20364         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20365         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20366         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20367
20368         local mdtidx=$($LFS getstripe -m $dom)
20369         local mdtname=MDT$(printf %04x $mdtidx)
20370         local facet=mds$((mdtidx + 1))
20371         local space_check=1
20372
20373         # Skip free space checks with ZFS
20374         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20375
20376         # write
20377         sync
20378         local size_tmp=$((65536 * 3))
20379         local mdtfree1=$(do_facet $facet \
20380                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20381
20382         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20383         # check also direct IO along write
20384         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20385         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20386         sync
20387         cmp $tmp $dom || error "file data is different"
20388         [ $(stat -c%s $dom) == $size_tmp ] ||
20389                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20390         if [ $space_check == 1 ]; then
20391                 local mdtfree2=$(do_facet $facet \
20392                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20393
20394                 # increase in usage from by $size_tmp
20395                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20396                         error "MDT free space wrong after write: " \
20397                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20398         fi
20399
20400         # truncate
20401         local size_dom=10000
20402
20403         $TRUNCATE $dom $size_dom
20404         [ $(stat -c%s $dom) == $size_dom ] ||
20405                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20406         if [ $space_check == 1 ]; then
20407                 mdtfree1=$(do_facet $facet \
20408                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20409                 # decrease in usage from $size_tmp to new $size_dom
20410                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20411                   $(((size_tmp - size_dom) / 1024)) ] ||
20412                         error "MDT free space is wrong after truncate: " \
20413                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20414         fi
20415
20416         # append
20417         cat $tmp >> $dom
20418         sync
20419         size_dom=$((size_dom + size_tmp))
20420         [ $(stat -c%s $dom) == $size_dom ] ||
20421                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20422         if [ $space_check == 1 ]; then
20423                 mdtfree2=$(do_facet $facet \
20424                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20425                 # increase in usage by $size_tmp from previous
20426                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20427                         error "MDT free space is wrong after append: " \
20428                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20429         fi
20430
20431         # delete
20432         rm $dom
20433         if [ $space_check == 1 ]; then
20434                 mdtfree1=$(do_facet $facet \
20435                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20436                 # decrease in usage by $size_dom from previous
20437                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20438                         error "MDT free space is wrong after removal: " \
20439                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20440         fi
20441
20442         # combined striping
20443         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20444                 error "Can't create DoM + OST striping"
20445
20446         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20447         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20448         # check also direct IO along write
20449         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20450         sync
20451         cmp $tmp $dom || error "file data is different"
20452         [ $(stat -c%s $dom) == $size_tmp ] ||
20453                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20454         rm $dom $tmp
20455
20456         return 0
20457 }
20458 run_test 270a "DoM: basic functionality tests"
20459
20460 test_270b() {
20461         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20462                 skip "Need MDS version at least 2.10.55"
20463
20464         local dom=$DIR/$tdir/dom_file
20465         local max_size=1048576
20466
20467         mkdir -p $DIR/$tdir
20468         $LFS setstripe -E $max_size -L mdt $dom
20469
20470         # truncate over the limit
20471         $TRUNCATE $dom $(($max_size + 1)) &&
20472                 error "successful truncate over the maximum size"
20473         # write over the limit
20474         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20475                 error "successful write over the maximum size"
20476         # append over the limit
20477         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20478         echo "12345" >> $dom && error "successful append over the maximum size"
20479         rm $dom
20480
20481         return 0
20482 }
20483 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20484
20485 test_270c() {
20486         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20487                 skip "Need MDS version at least 2.10.55"
20488
20489         mkdir -p $DIR/$tdir
20490         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20491
20492         # check files inherit DoM EA
20493         touch $DIR/$tdir/first
20494         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20495                 error "bad pattern"
20496         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20497                 error "bad stripe count"
20498         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20499                 error "bad stripe size"
20500
20501         # check directory inherits DoM EA and uses it as default
20502         mkdir $DIR/$tdir/subdir
20503         touch $DIR/$tdir/subdir/second
20504         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20505                 error "bad pattern in sub-directory"
20506         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20507                 error "bad stripe count in sub-directory"
20508         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20509                 error "bad stripe size in sub-directory"
20510         return 0
20511 }
20512 run_test 270c "DoM: DoM EA inheritance tests"
20513
20514 test_270d() {
20515         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20516                 skip "Need MDS version at least 2.10.55"
20517
20518         mkdir -p $DIR/$tdir
20519         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20520
20521         # inherit default DoM striping
20522         mkdir $DIR/$tdir/subdir
20523         touch $DIR/$tdir/subdir/f1
20524
20525         # change default directory striping
20526         $LFS setstripe -c 1 $DIR/$tdir/subdir
20527         touch $DIR/$tdir/subdir/f2
20528         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20529                 error "wrong default striping in file 2"
20530         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20531                 error "bad pattern in file 2"
20532         return 0
20533 }
20534 run_test 270d "DoM: change striping from DoM to RAID0"
20535
20536 test_270e() {
20537         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20538                 skip "Need MDS version at least 2.10.55"
20539
20540         mkdir -p $DIR/$tdir/dom
20541         mkdir -p $DIR/$tdir/norm
20542         DOMFILES=20
20543         NORMFILES=10
20544         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20545         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20546
20547         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20548         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20549
20550         # find DoM files by layout
20551         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20552         [ $NUM -eq  $DOMFILES ] ||
20553                 error "lfs find -L: found $NUM, expected $DOMFILES"
20554         echo "Test 1: lfs find 20 DOM files by layout: OK"
20555
20556         # there should be 1 dir with default DOM striping
20557         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20558         [ $NUM -eq  1 ] ||
20559                 error "lfs find -L: found $NUM, expected 1 dir"
20560         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20561
20562         # find DoM files by stripe size
20563         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20564         [ $NUM -eq  $DOMFILES ] ||
20565                 error "lfs find -S: found $NUM, expected $DOMFILES"
20566         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20567
20568         # find files by stripe offset except DoM files
20569         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20570         [ $NUM -eq  $NORMFILES ] ||
20571                 error "lfs find -i: found $NUM, expected $NORMFILES"
20572         echo "Test 5: lfs find no DOM files by stripe index: OK"
20573         return 0
20574 }
20575 run_test 270e "DoM: lfs find with DoM files test"
20576
20577 test_270f() {
20578         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20579                 skip "Need MDS version at least 2.10.55"
20580
20581         local mdtname=${FSNAME}-MDT0000-mdtlov
20582         local dom=$DIR/$tdir/dom_file
20583         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20584                                                 lod.$mdtname.dom_stripesize)
20585         local dom_limit=131072
20586
20587         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20588         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20589                                                 lod.$mdtname.dom_stripesize)
20590         [ ${dom_limit} -eq ${dom_current} ] ||
20591                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20592
20593         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20594         $LFS setstripe -d $DIR/$tdir
20595         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20596                 error "Can't set directory default striping"
20597
20598         # exceed maximum stripe size
20599         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20600                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20601         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20602                 error "Able to create DoM component size more than LOD limit"
20603
20604         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20605         dom_current=$(do_facet mds1 $LCTL get_param -n \
20606                                                 lod.$mdtname.dom_stripesize)
20607         [ 0 -eq ${dom_current} ] ||
20608                 error "Can't set zero DoM stripe limit"
20609         rm $dom
20610
20611         # attempt to create DoM file on server with disabled DoM should
20612         # remove DoM entry from layout and be succeed
20613         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20614                 error "Can't create DoM file (DoM is disabled)"
20615         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20616                 error "File has DoM component while DoM is disabled"
20617         rm $dom
20618
20619         # attempt to create DoM file with only DoM stripe should return error
20620         $LFS setstripe -E $dom_limit -L mdt $dom &&
20621                 error "Able to create DoM-only file while DoM is disabled"
20622
20623         # too low values to be aligned with smallest stripe size 64K
20624         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20625         dom_current=$(do_facet mds1 $LCTL get_param -n \
20626                                                 lod.$mdtname.dom_stripesize)
20627         [ 30000 -eq ${dom_current} ] &&
20628                 error "Can set too small DoM stripe limit"
20629
20630         # 64K is a minimal stripe size in Lustre, expect limit of that size
20631         [ 65536 -eq ${dom_current} ] ||
20632                 error "Limit is not set to 64K but ${dom_current}"
20633
20634         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20635         dom_current=$(do_facet mds1 $LCTL get_param -n \
20636                                                 lod.$mdtname.dom_stripesize)
20637         echo $dom_current
20638         [ 2147483648 -eq ${dom_current} ] &&
20639                 error "Can set too large DoM stripe limit"
20640
20641         do_facet mds1 $LCTL set_param -n \
20642                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20643         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20644                 error "Can't create DoM component size after limit change"
20645         do_facet mds1 $LCTL set_param -n \
20646                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20647         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20648                 error "Can't create DoM file after limit decrease"
20649         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20650                 error "Can create big DoM component after limit decrease"
20651         touch ${dom}_def ||
20652                 error "Can't create file with old default layout"
20653
20654         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20655         return 0
20656 }
20657 run_test 270f "DoM: maximum DoM stripe size checks"
20658
20659 test_270g() {
20660         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20661                 skip "Need MDS version at least 2.13.52"
20662         local dom=$DIR/$tdir/$tfile
20663
20664         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20665         local lodname=${FSNAME}-MDT0000-mdtlov
20666
20667         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20668         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20669         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20670         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20671
20672         local dom_limit=1024
20673         local dom_threshold="50%"
20674
20675         $LFS setstripe -d $DIR/$tdir
20676         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20677                 error "Can't set directory default striping"
20678
20679         do_facet mds1 $LCTL set_param -n \
20680                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20681         # set 0 threshold and create DOM file to change tunable stripesize
20682         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20683         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20684                 error "Failed to create $dom file"
20685         # now tunable dom_cur_stripesize should reach maximum
20686         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20687                                         lod.${lodname}.dom_stripesize_cur_kb)
20688         [[ $dom_current == $dom_limit ]] ||
20689                 error "Current DOM stripesize is not maximum"
20690         rm $dom
20691
20692         # set threshold for further tests
20693         do_facet mds1 $LCTL set_param -n \
20694                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20695         echo "DOM threshold is $dom_threshold free space"
20696         local dom_def
20697         local dom_set
20698         # Spoof bfree to exceed threshold
20699         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20700         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20701         for spfree in 40 20 0 15 30 55; do
20702                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20703                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20704                         error "Failed to create $dom file"
20705                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20706                                         lod.${lodname}.dom_stripesize_cur_kb)
20707                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20708                 [[ $dom_def != $dom_current ]] ||
20709                         error "Default stripe size was not changed"
20710                 if [[ $spfree > 0 ]] ; then
20711                         dom_set=$($LFS getstripe -S $dom)
20712                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20713                                 error "DOM component size is still old"
20714                 else
20715                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20716                                 error "DoM component is set with no free space"
20717                 fi
20718                 rm $dom
20719                 dom_current=$dom_def
20720         done
20721 }
20722 run_test 270g "DoM: default DoM stripe size depends on free space"
20723
20724 test_270h() {
20725         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20726                 skip "Need MDS version at least 2.13.53"
20727
20728         local mdtname=${FSNAME}-MDT0000-mdtlov
20729         local dom=$DIR/$tdir/$tfile
20730         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20731
20732         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20733         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20734
20735         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20736         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20737                 error "can't create OST file"
20738         # mirrored file with DOM entry in the second mirror
20739         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20740                 error "can't create mirror with DoM component"
20741
20742         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20743
20744         # DOM component in the middle and has other enries in the same mirror,
20745         # should succeed but lost DoM component
20746         $LFS setstripe --copy=${dom}_1 $dom ||
20747                 error "Can't create file from OST|DOM mirror layout"
20748         # check new file has no DoM layout after all
20749         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20750                 error "File has DoM component while DoM is disabled"
20751 }
20752 run_test 270h "DoM: DoM stripe removal when disabled on server"
20753
20754 test_271a() {
20755         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20756                 skip "Need MDS version at least 2.10.55"
20757
20758         local dom=$DIR/$tdir/dom
20759
20760         mkdir -p $DIR/$tdir
20761
20762         $LFS setstripe -E 1024K -L mdt $dom
20763
20764         lctl set_param -n mdc.*.stats=clear
20765         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20766         cat $dom > /dev/null
20767         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20768         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20769         ls $dom
20770         rm -f $dom
20771 }
20772 run_test 271a "DoM: data is cached for read after write"
20773
20774 test_271b() {
20775         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20776                 skip "Need MDS version at least 2.10.55"
20777
20778         local dom=$DIR/$tdir/dom
20779
20780         mkdir -p $DIR/$tdir
20781
20782         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20783
20784         lctl set_param -n mdc.*.stats=clear
20785         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20786         cancel_lru_locks mdc
20787         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20788         # second stat to check size is cached on client
20789         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20790         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20791         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20792         rm -f $dom
20793 }
20794 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20795
20796 test_271ba() {
20797         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20798                 skip "Need MDS version at least 2.10.55"
20799
20800         local dom=$DIR/$tdir/dom
20801
20802         mkdir -p $DIR/$tdir
20803
20804         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20805
20806         lctl set_param -n mdc.*.stats=clear
20807         lctl set_param -n osc.*.stats=clear
20808         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20809         cancel_lru_locks mdc
20810         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20811         # second stat to check size is cached on client
20812         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20813         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20814         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20815         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20816         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20817         rm -f $dom
20818 }
20819 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20820
20821
20822 get_mdc_stats() {
20823         local mdtidx=$1
20824         local param=$2
20825         local mdt=MDT$(printf %04x $mdtidx)
20826
20827         if [ -z $param ]; then
20828                 lctl get_param -n mdc.*$mdt*.stats
20829         else
20830                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20831         fi
20832 }
20833
20834 test_271c() {
20835         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20836                 skip "Need MDS version at least 2.10.55"
20837
20838         local dom=$DIR/$tdir/dom
20839
20840         mkdir -p $DIR/$tdir
20841
20842         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20843
20844         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20845         local facet=mds$((mdtidx + 1))
20846
20847         cancel_lru_locks mdc
20848         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20849         createmany -o $dom 1000
20850         lctl set_param -n mdc.*.stats=clear
20851         smalliomany -w $dom 1000 200
20852         get_mdc_stats $mdtidx
20853         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20854         # Each file has 1 open, 1 IO enqueues, total 2000
20855         # but now we have also +1 getxattr for security.capability, total 3000
20856         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20857         unlinkmany $dom 1000
20858
20859         cancel_lru_locks mdc
20860         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20861         createmany -o $dom 1000
20862         lctl set_param -n mdc.*.stats=clear
20863         smalliomany -w $dom 1000 200
20864         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20865         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20866         # for OPEN and IO lock.
20867         [ $((enq - enq_2)) -ge 1000 ] ||
20868                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20869         unlinkmany $dom 1000
20870         return 0
20871 }
20872 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20873
20874 cleanup_271def_tests() {
20875         trap 0
20876         rm -f $1
20877 }
20878
20879 test_271d() {
20880         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20881                 skip "Need MDS version at least 2.10.57"
20882
20883         local dom=$DIR/$tdir/dom
20884         local tmp=$TMP/$tfile
20885         trap "cleanup_271def_tests $tmp" EXIT
20886
20887         mkdir -p $DIR/$tdir
20888
20889         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20890
20891         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20892
20893         cancel_lru_locks mdc
20894         dd if=/dev/urandom of=$tmp bs=1000 count=1
20895         dd if=$tmp of=$dom bs=1000 count=1
20896         cancel_lru_locks mdc
20897
20898         cat /etc/hosts >> $tmp
20899         lctl set_param -n mdc.*.stats=clear
20900
20901         # append data to the same file it should update local page
20902         echo "Append to the same page"
20903         cat /etc/hosts >> $dom
20904         local num=$(get_mdc_stats $mdtidx ost_read)
20905         local ra=$(get_mdc_stats $mdtidx req_active)
20906         local rw=$(get_mdc_stats $mdtidx req_waittime)
20907
20908         [ -z $num ] || error "$num READ RPC occured"
20909         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20910         echo "... DONE"
20911
20912         # compare content
20913         cmp $tmp $dom || error "file miscompare"
20914
20915         cancel_lru_locks mdc
20916         lctl set_param -n mdc.*.stats=clear
20917
20918         echo "Open and read file"
20919         cat $dom > /dev/null
20920         local num=$(get_mdc_stats $mdtidx ost_read)
20921         local ra=$(get_mdc_stats $mdtidx req_active)
20922         local rw=$(get_mdc_stats $mdtidx req_waittime)
20923
20924         [ -z $num ] || error "$num READ RPC occured"
20925         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20926         echo "... DONE"
20927
20928         # compare content
20929         cmp $tmp $dom || error "file miscompare"
20930
20931         return 0
20932 }
20933 run_test 271d "DoM: read on open (1K file in reply buffer)"
20934
20935 test_271f() {
20936         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20937                 skip "Need MDS version at least 2.10.57"
20938
20939         local dom=$DIR/$tdir/dom
20940         local tmp=$TMP/$tfile
20941         trap "cleanup_271def_tests $tmp" EXIT
20942
20943         mkdir -p $DIR/$tdir
20944
20945         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20946
20947         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20948
20949         cancel_lru_locks mdc
20950         dd if=/dev/urandom of=$tmp bs=265000 count=1
20951         dd if=$tmp of=$dom bs=265000 count=1
20952         cancel_lru_locks mdc
20953         cat /etc/hosts >> $tmp
20954         lctl set_param -n mdc.*.stats=clear
20955
20956         echo "Append to the same page"
20957         cat /etc/hosts >> $dom
20958         local num=$(get_mdc_stats $mdtidx ost_read)
20959         local ra=$(get_mdc_stats $mdtidx req_active)
20960         local rw=$(get_mdc_stats $mdtidx req_waittime)
20961
20962         [ -z $num ] || error "$num READ RPC occured"
20963         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20964         echo "... DONE"
20965
20966         # compare content
20967         cmp $tmp $dom || error "file miscompare"
20968
20969         cancel_lru_locks mdc
20970         lctl set_param -n mdc.*.stats=clear
20971
20972         echo "Open and read file"
20973         cat $dom > /dev/null
20974         local num=$(get_mdc_stats $mdtidx ost_read)
20975         local ra=$(get_mdc_stats $mdtidx req_active)
20976         local rw=$(get_mdc_stats $mdtidx req_waittime)
20977
20978         [ -z $num ] && num=0
20979         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20980         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20981         echo "... DONE"
20982
20983         # compare content
20984         cmp $tmp $dom || error "file miscompare"
20985
20986         return 0
20987 }
20988 run_test 271f "DoM: read on open (200K file and read tail)"
20989
20990 test_271g() {
20991         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20992                 skip "Skipping due to old client or server version"
20993
20994         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20995         # to get layout
20996         $CHECKSTAT -t file $DIR1/$tfile
20997
20998         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20999         MULTIOP_PID=$!
21000         sleep 1
21001         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21002         $LCTL set_param fail_loc=0x80000314
21003         rm $DIR1/$tfile || error "Unlink fails"
21004         RC=$?
21005         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21006         [ $RC -eq 0 ] || error "Failed write to stale object"
21007 }
21008 run_test 271g "Discard DoM data vs client flush race"
21009
21010 test_272a() {
21011         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21012                 skip "Need MDS version at least 2.11.50"
21013
21014         local dom=$DIR/$tdir/dom
21015         mkdir -p $DIR/$tdir
21016
21017         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21018         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21019                 error "failed to write data into $dom"
21020         local old_md5=$(md5sum $dom)
21021
21022         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21023                 error "failed to migrate to the same DoM component"
21024
21025         local new_md5=$(md5sum $dom)
21026
21027         [ "$old_md5" == "$new_md5" ] ||
21028                 error "md5sum differ: $old_md5, $new_md5"
21029
21030         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21031                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21032 }
21033 run_test 272a "DoM migration: new layout with the same DOM component"
21034
21035 test_272b() {
21036         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21037                 skip "Need MDS version at least 2.11.50"
21038
21039         local dom=$DIR/$tdir/dom
21040         mkdir -p $DIR/$tdir
21041         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21042
21043         local mdtidx=$($LFS getstripe -m $dom)
21044         local mdtname=MDT$(printf %04x $mdtidx)
21045         local facet=mds$((mdtidx + 1))
21046
21047         local mdtfree1=$(do_facet $facet \
21048                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21049         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21050                 error "failed to write data into $dom"
21051         local old_md5=$(md5sum $dom)
21052         cancel_lru_locks mdc
21053         local mdtfree1=$(do_facet $facet \
21054                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21055
21056         $LFS migrate -c2 $dom ||
21057                 error "failed to migrate to the new composite layout"
21058         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21059                 error "MDT stripe was not removed"
21060
21061         cancel_lru_locks mdc
21062         local new_md5=$(md5sum $dom)
21063         [ "$old_md5" == "$new_md5" ] ||
21064                 error "$old_md5 != $new_md5"
21065
21066         # Skip free space checks with ZFS
21067         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21068                 local mdtfree2=$(do_facet $facet \
21069                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21070                 [ $mdtfree2 -gt $mdtfree1 ] ||
21071                         error "MDT space is not freed after migration"
21072         fi
21073         return 0
21074 }
21075 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21076
21077 test_272c() {
21078         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21079                 skip "Need MDS version at least 2.11.50"
21080
21081         local dom=$DIR/$tdir/$tfile
21082         mkdir -p $DIR/$tdir
21083         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21084
21085         local mdtidx=$($LFS getstripe -m $dom)
21086         local mdtname=MDT$(printf %04x $mdtidx)
21087         local facet=mds$((mdtidx + 1))
21088
21089         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21090                 error "failed to write data into $dom"
21091         local old_md5=$(md5sum $dom)
21092         cancel_lru_locks mdc
21093         local mdtfree1=$(do_facet $facet \
21094                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21095
21096         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21097                 error "failed to migrate to the new composite layout"
21098         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21099                 error "MDT stripe was not removed"
21100
21101         cancel_lru_locks mdc
21102         local new_md5=$(md5sum $dom)
21103         [ "$old_md5" == "$new_md5" ] ||
21104                 error "$old_md5 != $new_md5"
21105
21106         # Skip free space checks with ZFS
21107         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21108                 local mdtfree2=$(do_facet $facet \
21109                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21110                 [ $mdtfree2 -gt $mdtfree1 ] ||
21111                         error "MDS space is not freed after migration"
21112         fi
21113         return 0
21114 }
21115 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21116
21117 test_272d() {
21118         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21119                 skip "Need MDS version at least 2.12.55"
21120
21121         local dom=$DIR/$tdir/$tfile
21122         mkdir -p $DIR/$tdir
21123         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21124
21125         local mdtidx=$($LFS getstripe -m $dom)
21126         local mdtname=MDT$(printf %04x $mdtidx)
21127         local facet=mds$((mdtidx + 1))
21128
21129         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21130                 error "failed to write data into $dom"
21131         local old_md5=$(md5sum $dom)
21132         cancel_lru_locks mdc
21133         local mdtfree1=$(do_facet $facet \
21134                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21135
21136         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21137                 error "failed mirroring to the new composite layout"
21138         $LFS mirror resync $dom ||
21139                 error "failed mirror resync"
21140         $LFS mirror split --mirror-id 1 -d $dom ||
21141                 error "failed mirror split"
21142
21143         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21144                 error "MDT stripe was not removed"
21145
21146         cancel_lru_locks mdc
21147         local new_md5=$(md5sum $dom)
21148         [ "$old_md5" == "$new_md5" ] ||
21149                 error "$old_md5 != $new_md5"
21150
21151         # Skip free space checks with ZFS
21152         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21153                 local mdtfree2=$(do_facet $facet \
21154                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21155                 [ $mdtfree2 -gt $mdtfree1 ] ||
21156                         error "MDS space is not freed after DOM mirror deletion"
21157         fi
21158         return 0
21159 }
21160 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21161
21162 test_272e() {
21163         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21164                 skip "Need MDS version at least 2.12.55"
21165
21166         local dom=$DIR/$tdir/$tfile
21167         mkdir -p $DIR/$tdir
21168         $LFS setstripe -c 2 $dom
21169
21170         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21171                 error "failed to write data into $dom"
21172         local old_md5=$(md5sum $dom)
21173         cancel_lru_locks mdc
21174
21175         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21176                 error "failed mirroring to the DOM layout"
21177         $LFS mirror resync $dom ||
21178                 error "failed mirror resync"
21179         $LFS mirror split --mirror-id 1 -d $dom ||
21180                 error "failed mirror split"
21181
21182         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21183                 error "MDT stripe was not removed"
21184
21185         cancel_lru_locks mdc
21186         local new_md5=$(md5sum $dom)
21187         [ "$old_md5" == "$new_md5" ] ||
21188                 error "$old_md5 != $new_md5"
21189
21190         return 0
21191 }
21192 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21193
21194 test_272f() {
21195         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21196                 skip "Need MDS version at least 2.12.55"
21197
21198         local dom=$DIR/$tdir/$tfile
21199         mkdir -p $DIR/$tdir
21200         $LFS setstripe -c 2 $dom
21201
21202         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21203                 error "failed to write data into $dom"
21204         local old_md5=$(md5sum $dom)
21205         cancel_lru_locks mdc
21206
21207         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21208                 error "failed migrating to the DOM file"
21209
21210         cancel_lru_locks mdc
21211         local new_md5=$(md5sum $dom)
21212         [ "$old_md5" != "$new_md5" ] &&
21213                 error "$old_md5 != $new_md5"
21214
21215         return 0
21216 }
21217 run_test 272f "DoM migration: OST-striped file to DOM file"
21218
21219 test_273a() {
21220         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21221                 skip "Need MDS version at least 2.11.50"
21222
21223         # Layout swap cannot be done if either file has DOM component,
21224         # this will never be supported, migration should be used instead
21225
21226         local dom=$DIR/$tdir/$tfile
21227         mkdir -p $DIR/$tdir
21228
21229         $LFS setstripe -c2 ${dom}_plain
21230         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21231         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21232                 error "can swap layout with DoM component"
21233         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21234                 error "can swap layout with DoM component"
21235
21236         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21237         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21238                 error "can swap layout with DoM component"
21239         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21240                 error "can swap layout with DoM component"
21241         return 0
21242 }
21243 run_test 273a "DoM: layout swapping should fail with DOM"
21244
21245 test_275() {
21246         remote_ost_nodsh && skip "remote OST with nodsh"
21247         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21248                 skip "Need OST version >= 2.10.57"
21249
21250         local file=$DIR/$tfile
21251         local oss
21252
21253         oss=$(comma_list $(osts_nodes))
21254
21255         dd if=/dev/urandom of=$file bs=1M count=2 ||
21256                 error "failed to create a file"
21257         cancel_lru_locks osc
21258
21259         #lock 1
21260         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21261                 error "failed to read a file"
21262
21263 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21264         $LCTL set_param fail_loc=0x8000031f
21265
21266         cancel_lru_locks osc &
21267         sleep 1
21268
21269 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21270         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21271         #IO takes another lock, but matches the PENDING one
21272         #and places it to the IO RPC
21273         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21274                 error "failed to read a file with PENDING lock"
21275 }
21276 run_test 275 "Read on a canceled duplicate lock"
21277
21278 test_276() {
21279         remote_ost_nodsh && skip "remote OST with nodsh"
21280         local pid
21281
21282         do_facet ost1 "(while true; do \
21283                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21284                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21285         pid=$!
21286
21287         for LOOP in $(seq 20); do
21288                 stop ost1
21289                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21290         done
21291         kill -9 $pid
21292         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21293                 rm $TMP/sanity_276_pid"
21294 }
21295 run_test 276 "Race between mount and obd_statfs"
21296
21297 test_277() {
21298         $LCTL set_param ldlm.namespaces.*.lru_size=0
21299         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21300         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21301                         grep ^used_mb | awk '{print $2}')
21302         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21303         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21304                 oflag=direct conv=notrunc
21305         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21306                         grep ^used_mb | awk '{print $2}')
21307         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21308 }
21309 run_test 277 "Direct IO shall drop page cache"
21310
21311 test_278() {
21312         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21313         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21314         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21315                 skip "needs the same host for mdt1 mdt2" && return
21316
21317         local pid1
21318         local pid2
21319
21320 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21321         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21322         stop mds2 &
21323         pid2=$!
21324
21325         stop mds1
21326
21327         echo "Starting MDTs"
21328         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21329         wait $pid2
21330 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21331 #will return NULL
21332         do_facet mds2 $LCTL set_param fail_loc=0
21333
21334         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21335         wait_recovery_complete mds2
21336 }
21337 run_test 278 "Race starting MDS between MDTs stop/start"
21338
21339 test_280() {
21340         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21341                 skip "Need MGS version at least 2.13.52"
21342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21343         combined_mgs_mds || skip "needs combined MGS/MDT"
21344
21345         umount_client $MOUNT
21346 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21347         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21348
21349         mount_client $MOUNT &
21350         sleep 1
21351         stop mgs || error "stop mgs failed"
21352         #for a race mgs would crash
21353         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21354         mount_client $MOUNT || error "mount client failed"
21355 }
21356 run_test 280 "Race between MGS umount and client llog processing"
21357
21358 cleanup_test_300() {
21359         trap 0
21360         umask $SAVE_UMASK
21361 }
21362 test_striped_dir() {
21363         local mdt_index=$1
21364         local stripe_count
21365         local stripe_index
21366
21367         mkdir -p $DIR/$tdir
21368
21369         SAVE_UMASK=$(umask)
21370         trap cleanup_test_300 RETURN EXIT
21371
21372         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21373                                                 $DIR/$tdir/striped_dir ||
21374                 error "set striped dir error"
21375
21376         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21377         [ "$mode" = "755" ] || error "expect 755 got $mode"
21378
21379         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21380                 error "getdirstripe failed"
21381         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21382         if [ "$stripe_count" != "2" ]; then
21383                 error "1:stripe_count is $stripe_count, expect 2"
21384         fi
21385         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21386         if [ "$stripe_count" != "2" ]; then
21387                 error "2:stripe_count is $stripe_count, expect 2"
21388         fi
21389
21390         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21391         if [ "$stripe_index" != "$mdt_index" ]; then
21392                 error "stripe_index is $stripe_index, expect $mdt_index"
21393         fi
21394
21395         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21396                 error "nlink error after create striped dir"
21397
21398         mkdir $DIR/$tdir/striped_dir/a
21399         mkdir $DIR/$tdir/striped_dir/b
21400
21401         stat $DIR/$tdir/striped_dir/a ||
21402                 error "create dir under striped dir failed"
21403         stat $DIR/$tdir/striped_dir/b ||
21404                 error "create dir under striped dir failed"
21405
21406         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21407                 error "nlink error after mkdir"
21408
21409         rmdir $DIR/$tdir/striped_dir/a
21410         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21411                 error "nlink error after rmdir"
21412
21413         rmdir $DIR/$tdir/striped_dir/b
21414         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21415                 error "nlink error after rmdir"
21416
21417         chattr +i $DIR/$tdir/striped_dir
21418         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21419                 error "immutable flags not working under striped dir!"
21420         chattr -i $DIR/$tdir/striped_dir
21421
21422         rmdir $DIR/$tdir/striped_dir ||
21423                 error "rmdir striped dir error"
21424
21425         cleanup_test_300
21426
21427         true
21428 }
21429
21430 test_300a() {
21431         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21432                 skip "skipped for lustre < 2.7.0"
21433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21434         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21435
21436         test_striped_dir 0 || error "failed on striped dir on MDT0"
21437         test_striped_dir 1 || error "failed on striped dir on MDT0"
21438 }
21439 run_test 300a "basic striped dir sanity test"
21440
21441 test_300b() {
21442         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21443                 skip "skipped for lustre < 2.7.0"
21444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21446
21447         local i
21448         local mtime1
21449         local mtime2
21450         local mtime3
21451
21452         test_mkdir $DIR/$tdir || error "mkdir fail"
21453         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21454                 error "set striped dir error"
21455         for i in {0..9}; do
21456                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21457                 sleep 1
21458                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21459                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21460                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21461                 sleep 1
21462                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21463                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21464                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21465         done
21466         true
21467 }
21468 run_test 300b "check ctime/mtime for striped dir"
21469
21470 test_300c() {
21471         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21472                 skip "skipped for lustre < 2.7.0"
21473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21475
21476         local file_count
21477
21478         mkdir -p $DIR/$tdir
21479         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21480                 error "set striped dir error"
21481
21482         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21483                 error "chown striped dir failed"
21484
21485         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21486                 error "create 5k files failed"
21487
21488         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21489
21490         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21491
21492         rm -rf $DIR/$tdir
21493 }
21494 run_test 300c "chown && check ls under striped directory"
21495
21496 test_300d() {
21497         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21498                 skip "skipped for lustre < 2.7.0"
21499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21500         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21501
21502         local stripe_count
21503         local file
21504
21505         mkdir -p $DIR/$tdir
21506         $LFS setstripe -c 2 $DIR/$tdir
21507
21508         #local striped directory
21509         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21510                 error "set striped dir error"
21511         #look at the directories for debug purposes
21512         ls -l $DIR/$tdir
21513         $LFS getdirstripe $DIR/$tdir
21514         ls -l $DIR/$tdir/striped_dir
21515         $LFS getdirstripe $DIR/$tdir/striped_dir
21516         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21517                 error "create 10 files failed"
21518
21519         #remote striped directory
21520         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21521                 error "set striped dir error"
21522         #look at the directories for debug purposes
21523         ls -l $DIR/$tdir
21524         $LFS getdirstripe $DIR/$tdir
21525         ls -l $DIR/$tdir/remote_striped_dir
21526         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21527         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21528                 error "create 10 files failed"
21529
21530         for file in $(find $DIR/$tdir); do
21531                 stripe_count=$($LFS getstripe -c $file)
21532                 [ $stripe_count -eq 2 ] ||
21533                         error "wrong stripe $stripe_count for $file"
21534         done
21535
21536         rm -rf $DIR/$tdir
21537 }
21538 run_test 300d "check default stripe under striped directory"
21539
21540 test_300e() {
21541         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21542                 skip "Need MDS version at least 2.7.55"
21543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21545
21546         local stripe_count
21547         local file
21548
21549         mkdir -p $DIR/$tdir
21550
21551         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21552                 error "set striped dir error"
21553
21554         touch $DIR/$tdir/striped_dir/a
21555         touch $DIR/$tdir/striped_dir/b
21556         touch $DIR/$tdir/striped_dir/c
21557
21558         mkdir $DIR/$tdir/striped_dir/dir_a
21559         mkdir $DIR/$tdir/striped_dir/dir_b
21560         mkdir $DIR/$tdir/striped_dir/dir_c
21561
21562         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21563                 error "set striped adir under striped dir error"
21564
21565         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21566                 error "set striped bdir under striped dir error"
21567
21568         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21569                 error "set striped cdir under striped dir error"
21570
21571         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21572                 error "rename dir under striped dir fails"
21573
21574         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21575                 error "rename dir under different stripes fails"
21576
21577         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21578                 error "rename file under striped dir should succeed"
21579
21580         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21581                 error "rename dir under striped dir should succeed"
21582
21583         rm -rf $DIR/$tdir
21584 }
21585 run_test 300e "check rename under striped directory"
21586
21587 test_300f() {
21588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21590         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21591                 skip "Need MDS version at least 2.7.55"
21592
21593         local stripe_count
21594         local file
21595
21596         rm -rf $DIR/$tdir
21597         mkdir -p $DIR/$tdir
21598
21599         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21600                 error "set striped dir error"
21601
21602         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21603                 error "set striped dir error"
21604
21605         touch $DIR/$tdir/striped_dir/a
21606         mkdir $DIR/$tdir/striped_dir/dir_a
21607         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21608                 error "create striped dir under striped dir fails"
21609
21610         touch $DIR/$tdir/striped_dir1/b
21611         mkdir $DIR/$tdir/striped_dir1/dir_b
21612         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21613                 error "create striped dir under striped dir fails"
21614
21615         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21616                 error "rename dir under different striped dir should fail"
21617
21618         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21619                 error "rename striped dir under diff striped dir should fail"
21620
21621         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21622                 error "rename file under diff striped dirs fails"
21623
21624         rm -rf $DIR/$tdir
21625 }
21626 run_test 300f "check rename cross striped directory"
21627
21628 test_300_check_default_striped_dir()
21629 {
21630         local dirname=$1
21631         local default_count=$2
21632         local default_index=$3
21633         local stripe_count
21634         local stripe_index
21635         local dir_stripe_index
21636         local dir
21637
21638         echo "checking $dirname $default_count $default_index"
21639         $LFS setdirstripe -D -c $default_count -i $default_index \
21640                                 -t all_char $DIR/$tdir/$dirname ||
21641                 error "set default stripe on striped dir error"
21642         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21643         [ $stripe_count -eq $default_count ] ||
21644                 error "expect $default_count get $stripe_count for $dirname"
21645
21646         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21647         [ $stripe_index -eq $default_index ] ||
21648                 error "expect $default_index get $stripe_index for $dirname"
21649
21650         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21651                                                 error "create dirs failed"
21652
21653         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21654         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21655         for dir in $(find $DIR/$tdir/$dirname/*); do
21656                 stripe_count=$($LFS getdirstripe -c $dir)
21657                 [ $stripe_count -eq $default_count ] ||
21658                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21659                 error "stripe count $default_count != $stripe_count for $dir"
21660
21661                 stripe_index=$($LFS getdirstripe -i $dir)
21662                 [ $default_index -eq -1 ] ||
21663                         [ $stripe_index -eq $default_index ] ||
21664                         error "$stripe_index != $default_index for $dir"
21665
21666                 #check default stripe
21667                 stripe_count=$($LFS getdirstripe -D -c $dir)
21668                 [ $stripe_count -eq $default_count ] ||
21669                 error "default count $default_count != $stripe_count for $dir"
21670
21671                 stripe_index=$($LFS getdirstripe -D -i $dir)
21672                 [ $stripe_index -eq $default_index ] ||
21673                 error "default index $default_index != $stripe_index for $dir"
21674         done
21675         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21676 }
21677
21678 test_300g() {
21679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21680         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21681                 skip "Need MDS version at least 2.7.55"
21682
21683         local dir
21684         local stripe_count
21685         local stripe_index
21686
21687         mkdir $DIR/$tdir
21688         mkdir $DIR/$tdir/normal_dir
21689
21690         #Checking when client cache stripe index
21691         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21692         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21693                 error "create striped_dir failed"
21694
21695         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21696                 error "create dir0 fails"
21697         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21698         [ $stripe_index -eq 0 ] ||
21699                 error "dir0 expect index 0 got $stripe_index"
21700
21701         mkdir $DIR/$tdir/striped_dir/dir1 ||
21702                 error "create dir1 fails"
21703         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21704         [ $stripe_index -eq 1 ] ||
21705                 error "dir1 expect index 1 got $stripe_index"
21706
21707         #check default stripe count/stripe index
21708         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21709         test_300_check_default_striped_dir normal_dir 1 0
21710         test_300_check_default_striped_dir normal_dir 2 1
21711         test_300_check_default_striped_dir normal_dir 2 -1
21712
21713         #delete default stripe information
21714         echo "delete default stripeEA"
21715         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21716                 error "set default stripe on striped dir error"
21717
21718         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21719         for dir in $(find $DIR/$tdir/normal_dir/*); do
21720                 stripe_count=$($LFS getdirstripe -c $dir)
21721                 [ $stripe_count -eq 0 ] ||
21722                         error "expect 1 get $stripe_count for $dir"
21723                 stripe_index=$($LFS getdirstripe -i $dir)
21724                 [ $stripe_index -eq 0 ] ||
21725                         error "expect 0 get $stripe_index for $dir"
21726         done
21727 }
21728 run_test 300g "check default striped directory for normal directory"
21729
21730 test_300h() {
21731         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21732         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21733                 skip "Need MDS version at least 2.7.55"
21734
21735         local dir
21736         local stripe_count
21737
21738         mkdir $DIR/$tdir
21739         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21740                 error "set striped dir error"
21741
21742         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21743         test_300_check_default_striped_dir striped_dir 1 0
21744         test_300_check_default_striped_dir striped_dir 2 1
21745         test_300_check_default_striped_dir striped_dir 2 -1
21746
21747         #delete default stripe information
21748         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21749                 error "set default stripe on striped dir error"
21750
21751         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21752         for dir in $(find $DIR/$tdir/striped_dir/*); do
21753                 stripe_count=$($LFS getdirstripe -c $dir)
21754                 [ $stripe_count -eq 0 ] ||
21755                         error "expect 1 get $stripe_count for $dir"
21756         done
21757 }
21758 run_test 300h "check default striped directory for striped directory"
21759
21760 test_300i() {
21761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21763         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21764                 skip "Need MDS version at least 2.7.55"
21765
21766         local stripe_count
21767         local file
21768
21769         mkdir $DIR/$tdir
21770
21771         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21772                 error "set striped dir error"
21773
21774         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21775                 error "create files under striped dir failed"
21776
21777         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21778                 error "set striped hashdir error"
21779
21780         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21781                 error "create dir0 under hash dir failed"
21782         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21783                 error "create dir1 under hash dir failed"
21784
21785         # unfortunately, we need to umount to clear dir layout cache for now
21786         # once we fully implement dir layout, we can drop this
21787         umount_client $MOUNT || error "umount failed"
21788         mount_client $MOUNT || error "mount failed"
21789
21790         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21791         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21792         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21793
21794         #set the stripe to be unknown hash type
21795         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21796         $LCTL set_param fail_loc=0x1901
21797         for ((i = 0; i < 10; i++)); do
21798                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21799                         error "stat f-$i failed"
21800                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21801         done
21802
21803         touch $DIR/$tdir/striped_dir/f0 &&
21804                 error "create under striped dir with unknown hash should fail"
21805
21806         $LCTL set_param fail_loc=0
21807
21808         umount_client $MOUNT || error "umount failed"
21809         mount_client $MOUNT || error "mount failed"
21810
21811         return 0
21812 }
21813 run_test 300i "client handle unknown hash type striped directory"
21814
21815 test_300j() {
21816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21818         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21819                 skip "Need MDS version at least 2.7.55"
21820
21821         local stripe_count
21822         local file
21823
21824         mkdir $DIR/$tdir
21825
21826         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21827         $LCTL set_param fail_loc=0x1702
21828         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21829                 error "set striped dir error"
21830
21831         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21832                 error "create files under striped dir failed"
21833
21834         $LCTL set_param fail_loc=0
21835
21836         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21837
21838         return 0
21839 }
21840 run_test 300j "test large update record"
21841
21842 test_300k() {
21843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21845         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21846                 skip "Need MDS version at least 2.7.55"
21847
21848         # this test needs a huge transaction
21849         local kb
21850         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21851              osd*.$FSNAME-MDT0000.kbytestotal")
21852         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21853
21854         local stripe_count
21855         local file
21856
21857         mkdir $DIR/$tdir
21858
21859         #define OBD_FAIL_LARGE_STRIPE   0x1703
21860         $LCTL set_param fail_loc=0x1703
21861         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21862                 error "set striped dir error"
21863         $LCTL set_param fail_loc=0
21864
21865         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21866                 error "getstripeddir fails"
21867         rm -rf $DIR/$tdir/striped_dir ||
21868                 error "unlink striped dir fails"
21869
21870         return 0
21871 }
21872 run_test 300k "test large striped directory"
21873
21874 test_300l() {
21875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21876         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21877         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21878                 skip "Need MDS version at least 2.7.55"
21879
21880         local stripe_index
21881
21882         test_mkdir -p $DIR/$tdir/striped_dir
21883         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21884                         error "chown $RUNAS_ID failed"
21885         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21886                 error "set default striped dir failed"
21887
21888         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21889         $LCTL set_param fail_loc=0x80000158
21890         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21891
21892         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21893         [ $stripe_index -eq 1 ] ||
21894                 error "expect 1 get $stripe_index for $dir"
21895 }
21896 run_test 300l "non-root user to create dir under striped dir with stale layout"
21897
21898 test_300m() {
21899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21900         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21901         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21902                 skip "Need MDS version at least 2.7.55"
21903
21904         mkdir -p $DIR/$tdir/striped_dir
21905         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21906                 error "set default stripes dir error"
21907
21908         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21909
21910         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21911         [ $stripe_count -eq 0 ] ||
21912                         error "expect 0 get $stripe_count for a"
21913
21914         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21915                 error "set default stripes dir error"
21916
21917         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21918
21919         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21920         [ $stripe_count -eq 0 ] ||
21921                         error "expect 0 get $stripe_count for b"
21922
21923         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21924                 error "set default stripes dir error"
21925
21926         mkdir $DIR/$tdir/striped_dir/c &&
21927                 error "default stripe_index is invalid, mkdir c should fails"
21928
21929         rm -rf $DIR/$tdir || error "rmdir fails"
21930 }
21931 run_test 300m "setstriped directory on single MDT FS"
21932
21933 cleanup_300n() {
21934         local list=$(comma_list $(mdts_nodes))
21935
21936         trap 0
21937         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21938 }
21939
21940 test_300n() {
21941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21943         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21944                 skip "Need MDS version at least 2.7.55"
21945         remote_mds_nodsh && skip "remote MDS with nodsh"
21946
21947         local stripe_index
21948         local list=$(comma_list $(mdts_nodes))
21949
21950         trap cleanup_300n RETURN EXIT
21951         mkdir -p $DIR/$tdir
21952         chmod 777 $DIR/$tdir
21953         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21954                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21955                 error "create striped dir succeeds with gid=0"
21956
21957         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21958         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21959                 error "create striped dir fails with gid=-1"
21960
21961         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21962         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21963                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21964                 error "set default striped dir succeeds with gid=0"
21965
21966
21967         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21968         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21969                 error "set default striped dir fails with gid=-1"
21970
21971
21972         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21973         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21974                                         error "create test_dir fails"
21975         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21976                                         error "create test_dir1 fails"
21977         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21978                                         error "create test_dir2 fails"
21979         cleanup_300n
21980 }
21981 run_test 300n "non-root user to create dir under striped dir with default EA"
21982
21983 test_300o() {
21984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21985         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21986         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21987                 skip "Need MDS version at least 2.7.55"
21988
21989         local numfree1
21990         local numfree2
21991
21992         mkdir -p $DIR/$tdir
21993
21994         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21995         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21996         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21997                 skip "not enough free inodes $numfree1 $numfree2"
21998         fi
21999
22000         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22001         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22002         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22003                 skip "not enough free space $numfree1 $numfree2"
22004         fi
22005
22006         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22007                 error "setdirstripe fails"
22008
22009         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22010                 error "create dirs fails"
22011
22012         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22013         ls $DIR/$tdir/striped_dir > /dev/null ||
22014                 error "ls striped dir fails"
22015         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22016                 error "unlink big striped dir fails"
22017 }
22018 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22019
22020 test_300p() {
22021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22022         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22023         remote_mds_nodsh && skip "remote MDS with nodsh"
22024
22025         mkdir -p $DIR/$tdir
22026
22027         #define OBD_FAIL_OUT_ENOSPC     0x1704
22028         do_facet mds2 lctl set_param fail_loc=0x80001704
22029         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22030                  && error "create striped directory should fail"
22031
22032         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22033
22034         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22035         true
22036 }
22037 run_test 300p "create striped directory without space"
22038
22039 test_300q() {
22040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22042
22043         local fd=$(free_fd)
22044         local cmd="exec $fd<$tdir"
22045         cd $DIR
22046         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22047         eval $cmd
22048         cmd="exec $fd<&-"
22049         trap "eval $cmd" EXIT
22050         cd $tdir || error "cd $tdir fails"
22051         rmdir  ../$tdir || error "rmdir $tdir fails"
22052         mkdir local_dir && error "create dir succeeds"
22053         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22054         eval $cmd
22055         return 0
22056 }
22057 run_test 300q "create remote directory under orphan directory"
22058
22059 test_300r() {
22060         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22061                 skip "Need MDS version at least 2.7.55" && return
22062         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22063
22064         mkdir $DIR/$tdir
22065
22066         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22067                 error "set striped dir error"
22068
22069         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22070                 error "getstripeddir fails"
22071
22072         local stripe_count
22073         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22074                       awk '/lmv_stripe_count:/ { print $2 }')
22075
22076         [ $MDSCOUNT -ne $stripe_count ] &&
22077                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22078
22079         rm -rf $DIR/$tdir/striped_dir ||
22080                 error "unlink striped dir fails"
22081 }
22082 run_test 300r "test -1 striped directory"
22083
22084 test_300s_helper() {
22085         local count=$1
22086
22087         local stripe_dir=$DIR/$tdir/striped_dir.$count
22088
22089         $LFS mkdir -c $count $stripe_dir ||
22090                 error "lfs mkdir -c error"
22091
22092         $LFS getdirstripe $stripe_dir ||
22093                 error "lfs getdirstripe fails"
22094
22095         local stripe_count
22096         stripe_count=$($LFS getdirstripe $stripe_dir |
22097                       awk '/lmv_stripe_count:/ { print $2 }')
22098
22099         [ $count -ne $stripe_count ] &&
22100                 error_noexit "bad stripe count $stripe_count expected $count"
22101
22102         local dupe_stripes
22103         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22104                 awk '/0x/ {count[$1] += 1}; END {
22105                         for (idx in count) {
22106                                 if (count[idx]>1) {
22107                                         print "index " idx " count " count[idx]
22108                                 }
22109                         }
22110                 }')
22111
22112         if [[ -n "$dupe_stripes" ]] ; then
22113                 lfs getdirstripe $stripe_dir
22114                 error_noexit "Dupe MDT above: $dupe_stripes "
22115         fi
22116
22117         rm -rf $stripe_dir ||
22118                 error_noexit "unlink $stripe_dir fails"
22119 }
22120
22121 test_300s() {
22122         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22123                 skip "Need MDS version at least 2.7.55" && return
22124         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22125
22126         mkdir $DIR/$tdir
22127         for count in $(seq 2 $MDSCOUNT); do
22128                 test_300s_helper $count
22129         done
22130 }
22131 run_test 300s "test lfs mkdir -c without -i"
22132
22133
22134 prepare_remote_file() {
22135         mkdir $DIR/$tdir/src_dir ||
22136                 error "create remote source failed"
22137
22138         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22139                  error "cp to remote source failed"
22140         touch $DIR/$tdir/src_dir/a
22141
22142         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22143                 error "create remote target dir failed"
22144
22145         touch $DIR/$tdir/tgt_dir/b
22146
22147         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22148                 error "rename dir cross MDT failed!"
22149
22150         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22151                 error "src_child still exists after rename"
22152
22153         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22154                 error "missing file(a) after rename"
22155
22156         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22157                 error "diff after rename"
22158 }
22159
22160 test_310a() {
22161         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22163
22164         local remote_file=$DIR/$tdir/tgt_dir/b
22165
22166         mkdir -p $DIR/$tdir
22167
22168         prepare_remote_file || error "prepare remote file failed"
22169
22170         #open-unlink file
22171         $OPENUNLINK $remote_file $remote_file ||
22172                 error "openunlink $remote_file failed"
22173         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22174 }
22175 run_test 310a "open unlink remote file"
22176
22177 test_310b() {
22178         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22180
22181         local remote_file=$DIR/$tdir/tgt_dir/b
22182
22183         mkdir -p $DIR/$tdir
22184
22185         prepare_remote_file || error "prepare remote file failed"
22186
22187         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22188         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22189         $CHECKSTAT -t file $remote_file || error "check file failed"
22190 }
22191 run_test 310b "unlink remote file with multiple links while open"
22192
22193 test_310c() {
22194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22195         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22196
22197         local remote_file=$DIR/$tdir/tgt_dir/b
22198
22199         mkdir -p $DIR/$tdir
22200
22201         prepare_remote_file || error "prepare remote file failed"
22202
22203         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22204         multiop_bg_pause $remote_file O_uc ||
22205                         error "mulitop failed for remote file"
22206         MULTIPID=$!
22207         $MULTIOP $DIR/$tfile Ouc
22208         kill -USR1 $MULTIPID
22209         wait $MULTIPID
22210 }
22211 run_test 310c "open-unlink remote file with multiple links"
22212
22213 #LU-4825
22214 test_311() {
22215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22216         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22217         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22218                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22219         remote_mds_nodsh && skip "remote MDS with nodsh"
22220
22221         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22222         local mdts=$(comma_list $(mdts_nodes))
22223
22224         mkdir -p $DIR/$tdir
22225         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22226         createmany -o $DIR/$tdir/$tfile. 1000
22227
22228         # statfs data is not real time, let's just calculate it
22229         old_iused=$((old_iused + 1000))
22230
22231         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22232                         osp.*OST0000*MDT0000.create_count")
22233         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22234                                 osp.*OST0000*MDT0000.max_create_count")
22235         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22236
22237         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22238         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22239         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22240
22241         unlinkmany $DIR/$tdir/$tfile. 1000
22242
22243         do_nodes $mdts "$LCTL set_param -n \
22244                         osp.*OST0000*.max_create_count=$max_count"
22245         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22246                 do_nodes $mdts "$LCTL set_param -n \
22247                                 osp.*OST0000*.create_count=$count"
22248         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22249                         grep "=0" && error "create_count is zero"
22250
22251         local new_iused
22252         for i in $(seq 120); do
22253                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22254                 # system may be too busy to destroy all objs in time, use
22255                 # a somewhat small value to not fail autotest
22256                 [ $((old_iused - new_iused)) -gt 400 ] && break
22257                 sleep 1
22258         done
22259
22260         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22261         [ $((old_iused - new_iused)) -gt 400 ] ||
22262                 error "objs not destroyed after unlink"
22263 }
22264 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22265
22266 zfs_oid_to_objid()
22267 {
22268         local ost=$1
22269         local objid=$2
22270
22271         local vdevdir=$(dirname $(facet_vdevice $ost))
22272         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22273         local zfs_zapid=$(do_facet $ost $cmd |
22274                           grep -w "/O/0/d$((objid%32))" -C 5 |
22275                           awk '/Object/{getline; print $1}')
22276         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22277                           awk "/$objid = /"'{printf $3}')
22278
22279         echo $zfs_objid
22280 }
22281
22282 zfs_object_blksz() {
22283         local ost=$1
22284         local objid=$2
22285
22286         local vdevdir=$(dirname $(facet_vdevice $ost))
22287         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22288         local blksz=$(do_facet $ost $cmd $objid |
22289                       awk '/dblk/{getline; printf $4}')
22290
22291         case "${blksz: -1}" in
22292                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22293                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22294                 *) ;;
22295         esac
22296
22297         echo $blksz
22298 }
22299
22300 test_312() { # LU-4856
22301         remote_ost_nodsh && skip "remote OST with nodsh"
22302         [ "$ost1_FSTYPE" = "zfs" ] ||
22303                 skip_env "the test only applies to zfs"
22304
22305         local max_blksz=$(do_facet ost1 \
22306                           $ZFS get -p recordsize $(facet_device ost1) |
22307                           awk '!/VALUE/{print $3}')
22308
22309         # to make life a little bit easier
22310         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22311         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22312
22313         local tf=$DIR/$tdir/$tfile
22314         touch $tf
22315         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22316
22317         # Get ZFS object id
22318         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22319         # block size change by sequential overwrite
22320         local bs
22321
22322         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22323                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22324
22325                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22326                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22327         done
22328         rm -f $tf
22329
22330         # block size change by sequential append write
22331         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22332         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22333         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22334         local count
22335
22336         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22337                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22338                         oflag=sync conv=notrunc
22339
22340                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22341                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22342                         error "blksz error, actual $blksz, " \
22343                                 "expected: 2 * $count * $PAGE_SIZE"
22344         done
22345         rm -f $tf
22346
22347         # random write
22348         touch $tf
22349         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22350         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22351
22352         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22353         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22354         [ $blksz -eq $PAGE_SIZE ] ||
22355                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22356
22357         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22358         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22359         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22360
22361         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22362         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22363         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22364 }
22365 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22366
22367 test_313() {
22368         remote_ost_nodsh && skip "remote OST with nodsh"
22369
22370         local file=$DIR/$tfile
22371
22372         rm -f $file
22373         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22374
22375         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22376         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22377         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22378                 error "write should failed"
22379         do_facet ost1 "$LCTL set_param fail_loc=0"
22380         rm -f $file
22381 }
22382 run_test 313 "io should fail after last_rcvd update fail"
22383
22384 test_314() {
22385         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22386
22387         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22388         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22389         rm -f $DIR/$tfile
22390         wait_delete_completed
22391         do_facet ost1 "$LCTL set_param fail_loc=0"
22392 }
22393 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22394
22395 test_315() { # LU-618
22396         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22397
22398         local file=$DIR/$tfile
22399         rm -f $file
22400
22401         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22402                 error "multiop file write failed"
22403         $MULTIOP $file oO_RDONLY:r4063232_c &
22404         PID=$!
22405
22406         sleep 2
22407
22408         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22409         kill -USR1 $PID
22410
22411         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22412         rm -f $file
22413 }
22414 run_test 315 "read should be accounted"
22415
22416 test_316() {
22417         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22418         large_xattr_enabled || skip_env "ea_inode feature disabled"
22419
22420         rm -rf $DIR/$tdir/d
22421         mkdir -p $DIR/$tdir/d
22422         chown nobody $DIR/$tdir/d
22423         touch $DIR/$tdir/d/file
22424
22425         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22426 }
22427 run_test 316 "lfs mv"
22428
22429 test_317() {
22430         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22431                 skip "Need MDS version at least 2.11.53"
22432         if [ "$ost1_FSTYPE" == "zfs" ]; then
22433                 skip "LU-10370: no implementation for ZFS"
22434         fi
22435
22436         local trunc_sz
22437         local grant_blk_size
22438
22439         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22440                         awk '/grant_block_size:/ { print $2; exit; }')
22441         #
22442         # Create File of size 5M. Truncate it to below size's and verify
22443         # blocks count.
22444         #
22445         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22446                 error "Create file $DIR/$tfile failed"
22447         stack_trap "rm -f $DIR/$tfile" EXIT
22448
22449         for trunc_sz in 2097152 4097 4000 509 0; do
22450                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22451                         error "truncate $tfile to $trunc_sz failed"
22452                 local sz=$(stat --format=%s $DIR/$tfile)
22453                 local blk=$(stat --format=%b $DIR/$tfile)
22454                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22455                                      grant_blk_size) * 8))
22456
22457                 if [[ $blk -ne $trunc_blk ]]; then
22458                         $(which stat) $DIR/$tfile
22459                         error "Expected Block $trunc_blk got $blk for $tfile"
22460                 fi
22461
22462                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22463                         error "Expected Size $trunc_sz got $sz for $tfile"
22464         done
22465
22466         #
22467         # sparse file test
22468         # Create file with a hole and write actual two blocks. Block count
22469         # must be 16.
22470         #
22471         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22472                 conv=fsync || error "Create file : $DIR/$tfile"
22473
22474         # Calculate the final truncate size.
22475         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22476
22477         #
22478         # truncate to size $trunc_sz bytes. Strip the last block
22479         # The block count must drop to 8
22480         #
22481         $TRUNCATE $DIR/$tfile $trunc_sz ||
22482                 error "truncate $tfile to $trunc_sz failed"
22483
22484         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22485         sz=$(stat --format=%s $DIR/$tfile)
22486         blk=$(stat --format=%b $DIR/$tfile)
22487
22488         if [[ $blk -ne $trunc_bsz ]]; then
22489                 $(which stat) $DIR/$tfile
22490                 error "Expected Block $trunc_bsz got $blk for $tfile"
22491         fi
22492
22493         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22494                 error "Expected Size $trunc_sz got $sz for $tfile"
22495 }
22496 run_test 317 "Verify blocks get correctly update after truncate"
22497
22498 test_318() {
22499         local old_max_active=$($LCTL get_param -n \
22500                             llite.*.max_read_ahead_async_active 2>/dev/null)
22501
22502         $LCTL set_param llite.*.max_read_ahead_async_active=256
22503         local max_active=$($LCTL get_param -n \
22504                            llite.*.max_read_ahead_async_active 2>/dev/null)
22505         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22506
22507         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22508                 error "set max_read_ahead_async_active should succeed"
22509
22510         $LCTL set_param llite.*.max_read_ahead_async_active=512
22511         max_active=$($LCTL get_param -n \
22512                      llite.*.max_read_ahead_async_active 2>/dev/null)
22513         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22514
22515         # restore @max_active
22516         [ $old_max_active -ne 0 ] && $LCTL set_param \
22517                 llite.*.max_read_ahead_async_active=$old_max_active
22518
22519         local old_threshold=$($LCTL get_param -n \
22520                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22521         local max_per_file_mb=$($LCTL get_param -n \
22522                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22523
22524         local invalid=$(($max_per_file_mb + 1))
22525         $LCTL set_param \
22526                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22527                         && error "set $invalid should fail"
22528
22529         local valid=$(($invalid - 1))
22530         $LCTL set_param \
22531                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22532                         error "set $valid should succeed"
22533         local threshold=$($LCTL get_param -n \
22534                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22535         [ $threshold -eq $valid ] || error \
22536                 "expect threshold $valid got $threshold"
22537         $LCTL set_param \
22538                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22539 }
22540 run_test 318 "Verify async readahead tunables"
22541
22542 test_319() {
22543         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22544
22545         local before=$(date +%s)
22546         local evict
22547         local mdir=$DIR/$tdir
22548         local file=$mdir/xxx
22549
22550         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22551         touch $file
22552
22553 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22554         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22555         $LFS mv -m1 $file &
22556
22557         sleep 1
22558         dd if=$file of=/dev/null
22559         wait
22560         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22561           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22562
22563         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22564 }
22565 run_test 319 "lost lease lock on migrate error"
22566
22567 test_398a() { # LU-4198
22568         local ost1_imp=$(get_osc_import_name client ost1)
22569         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22570                          cut -d'.' -f2)
22571
22572         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22573         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22574
22575         # request a new lock on client
22576         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22577
22578         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22579         local lock_count=$($LCTL get_param -n \
22580                            ldlm.namespaces.$imp_name.lru_size)
22581         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22582
22583         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22584
22585         # no lock cached, should use lockless IO and not enqueue new lock
22586         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22587         lock_count=$($LCTL get_param -n \
22588                      ldlm.namespaces.$imp_name.lru_size)
22589         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22590 }
22591 run_test 398a "direct IO should cancel lock otherwise lockless"
22592
22593 test_398b() { # LU-4198
22594         which fio || skip_env "no fio installed"
22595         $LFS setstripe -c -1 $DIR/$tfile
22596
22597         local size=12
22598         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22599
22600         local njobs=4
22601         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22602         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22603                 --numjobs=$njobs --fallocate=none \
22604                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22605                 --filename=$DIR/$tfile &
22606         bg_pid=$!
22607
22608         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22609         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22610                 --numjobs=$njobs --fallocate=none \
22611                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22612                 --filename=$DIR/$tfile || true
22613         wait $bg_pid
22614
22615         rm -rf $DIR/$tfile
22616 }
22617 run_test 398b "DIO and buffer IO race"
22618
22619 test_398c() { # LU-4198
22620         local ost1_imp=$(get_osc_import_name client ost1)
22621         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22622                          cut -d'.' -f2)
22623
22624         which fio || skip_env "no fio installed"
22625
22626         saved_debug=$($LCTL get_param -n debug)
22627         $LCTL set_param debug=0
22628
22629         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22630         ((size /= 1024)) # by megabytes
22631         ((size /= 2)) # write half of the OST at most
22632         [ $size -gt 40 ] && size=40 #reduce test time anyway
22633
22634         $LFS setstripe -c 1 $DIR/$tfile
22635
22636         # it seems like ldiskfs reserves more space than necessary if the
22637         # writing blocks are not mapped, so it extends the file firstly
22638         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22639         cancel_lru_locks osc
22640
22641         # clear and verify rpc_stats later
22642         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22643
22644         local njobs=4
22645         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22646         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22647                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22648                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22649                 --filename=$DIR/$tfile
22650         [ $? -eq 0 ] || error "fio write error"
22651
22652         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
22653                 error "Locks were requested while doing AIO"
22654
22655         # get the percentage of 1-page I/O
22656         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22657                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22658                 awk '{print $7}')
22659         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22660
22661         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22662         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22663                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22664                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22665                 --filename=$DIR/$tfile
22666         [ $? -eq 0 ] || error "fio mixed read write error"
22667
22668         echo "AIO with large block size ${size}M"
22669         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22670                 --numjobs=1 --fallocate=none --ioengine=libaio \
22671                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22672                 --filename=$DIR/$tfile
22673         [ $? -eq 0 ] || error "fio large block size failed"
22674
22675         rm -rf $DIR/$tfile
22676         $LCTL set_param debug="$saved_debug"
22677 }
22678 run_test 398c "run fio to test AIO"
22679
22680 test_398d() { #  LU-13846
22681         test -f aiocp || skip_env "no aiocp installed"
22682         local aio_file=$DIR/aio_file
22683
22684         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22685
22686         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22687         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22688
22689         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22690
22691         # make sure we don't crash and fail properly
22692         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22693                 error "aio not aligned with PAGE SIZE should fail"
22694
22695         rm -rf $DIR/$tfile $aio_file
22696 }
22697 run_test 398d "run aiocp to verify block size > stripe size"
22698
22699 test_398e() {
22700         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22701         touch $DIR/$tfile.new
22702         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22703 }
22704 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22705
22706 test_fake_rw() {
22707         local read_write=$1
22708         if [ "$read_write" = "write" ]; then
22709                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22710         elif [ "$read_write" = "read" ]; then
22711                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22712         else
22713                 error "argument error"
22714         fi
22715
22716         # turn off debug for performance testing
22717         local saved_debug=$($LCTL get_param -n debug)
22718         $LCTL set_param debug=0
22719
22720         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22721
22722         # get ost1 size - $FSNAME-OST0000
22723         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22724         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22725         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22726
22727         if [ "$read_write" = "read" ]; then
22728                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22729         fi
22730
22731         local start_time=$(date +%s.%N)
22732         $dd_cmd bs=1M count=$blocks oflag=sync ||
22733                 error "real dd $read_write error"
22734         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22735
22736         if [ "$read_write" = "write" ]; then
22737                 rm -f $DIR/$tfile
22738         fi
22739
22740         # define OBD_FAIL_OST_FAKE_RW           0x238
22741         do_facet ost1 $LCTL set_param fail_loc=0x238
22742
22743         local start_time=$(date +%s.%N)
22744         $dd_cmd bs=1M count=$blocks oflag=sync ||
22745                 error "fake dd $read_write error"
22746         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22747
22748         if [ "$read_write" = "write" ]; then
22749                 # verify file size
22750                 cancel_lru_locks osc
22751                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22752                         error "$tfile size not $blocks MB"
22753         fi
22754         do_facet ost1 $LCTL set_param fail_loc=0
22755
22756         echo "fake $read_write $duration_fake vs. normal $read_write" \
22757                 "$duration in seconds"
22758         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22759                 error_not_in_vm "fake write is slower"
22760
22761         $LCTL set_param -n debug="$saved_debug"
22762         rm -f $DIR/$tfile
22763 }
22764 test_399a() { # LU-7655 for OST fake write
22765         remote_ost_nodsh && skip "remote OST with nodsh"
22766
22767         test_fake_rw write
22768 }
22769 run_test 399a "fake write should not be slower than normal write"
22770
22771 test_399b() { # LU-8726 for OST fake read
22772         remote_ost_nodsh && skip "remote OST with nodsh"
22773         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22774                 skip_env "ldiskfs only test"
22775         fi
22776
22777         test_fake_rw read
22778 }
22779 run_test 399b "fake read should not be slower than normal read"
22780
22781 test_400a() { # LU-1606, was conf-sanity test_74
22782         if ! which $CC > /dev/null 2>&1; then
22783                 skip_env "$CC is not installed"
22784         fi
22785
22786         local extra_flags=''
22787         local out=$TMP/$tfile
22788         local prefix=/usr/include/lustre
22789         local prog
22790
22791         # Oleg removes c files in his test rig so test if any c files exist
22792         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22793                 skip_env "Needed c test files are missing"
22794
22795         if ! [[ -d $prefix ]]; then
22796                 # Assume we're running in tree and fixup the include path.
22797                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22798                 extra_flags+=" -L$LUSTRE/utils/.lib"
22799         fi
22800
22801         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22802                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22803                         error "client api broken"
22804         done
22805         rm -f $out
22806 }
22807 run_test 400a "Lustre client api program can compile and link"
22808
22809 test_400b() { # LU-1606, LU-5011
22810         local header
22811         local out=$TMP/$tfile
22812         local prefix=/usr/include/linux/lustre
22813
22814         # We use a hard coded prefix so that this test will not fail
22815         # when run in tree. There are headers in lustre/include/lustre/
22816         # that are not packaged (like lustre_idl.h) and have more
22817         # complicated include dependencies (like config.h and lnet/types.h).
22818         # Since this test about correct packaging we just skip them when
22819         # they don't exist (see below) rather than try to fixup cppflags.
22820
22821         if ! which $CC > /dev/null 2>&1; then
22822                 skip_env "$CC is not installed"
22823         fi
22824
22825         for header in $prefix/*.h; do
22826                 if ! [[ -f "$header" ]]; then
22827                         continue
22828                 fi
22829
22830                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22831                         continue # lustre_ioctl.h is internal header
22832                 fi
22833
22834                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22835                         error "cannot compile '$header'"
22836         done
22837         rm -f $out
22838 }
22839 run_test 400b "packaged headers can be compiled"
22840
22841 test_401a() { #LU-7437
22842         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22843         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22844
22845         #count the number of parameters by "list_param -R"
22846         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22847         #count the number of parameters by listing proc files
22848         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22849         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22850         echo "proc_dirs='$proc_dirs'"
22851         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22852         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22853                       sort -u | wc -l)
22854
22855         [ $params -eq $procs ] ||
22856                 error "found $params parameters vs. $procs proc files"
22857
22858         # test the list_param -D option only returns directories
22859         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22860         #count the number of parameters by listing proc directories
22861         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22862                 sort -u | wc -l)
22863
22864         [ $params -eq $procs ] ||
22865                 error "found $params parameters vs. $procs proc files"
22866 }
22867 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22868
22869 test_401b() {
22870         # jobid_var may not allow arbitrary values, so use jobid_name
22871         # if available
22872         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22873                 local testname=jobid_name tmp='testing%p'
22874         else
22875                 local testname=jobid_var tmp=testing
22876         fi
22877
22878         local save=$($LCTL get_param -n $testname)
22879
22880         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22881                 error "no error returned when setting bad parameters"
22882
22883         local jobid_new=$($LCTL get_param -n foe $testname baz)
22884         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22885
22886         $LCTL set_param -n fog=bam $testname=$save bat=fog
22887         local jobid_old=$($LCTL get_param -n foe $testname bag)
22888         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22889 }
22890 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22891
22892 test_401c() {
22893         # jobid_var may not allow arbitrary values, so use jobid_name
22894         # if available
22895         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22896                 local testname=jobid_name
22897         else
22898                 local testname=jobid_var
22899         fi
22900
22901         local jobid_var_old=$($LCTL get_param -n $testname)
22902         local jobid_var_new
22903
22904         $LCTL set_param $testname= &&
22905                 error "no error returned for 'set_param a='"
22906
22907         jobid_var_new=$($LCTL get_param -n $testname)
22908         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22909                 error "$testname was changed by setting without value"
22910
22911         $LCTL set_param $testname &&
22912                 error "no error returned for 'set_param a'"
22913
22914         jobid_var_new=$($LCTL get_param -n $testname)
22915         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22916                 error "$testname was changed by setting without value"
22917 }
22918 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22919
22920 test_401d() {
22921         # jobid_var may not allow arbitrary values, so use jobid_name
22922         # if available
22923         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22924                 local testname=jobid_name new_value='foo=bar%p'
22925         else
22926                 local testname=jobid_var new_valuie=foo=bar
22927         fi
22928
22929         local jobid_var_old=$($LCTL get_param -n $testname)
22930         local jobid_var_new
22931
22932         $LCTL set_param $testname=$new_value ||
22933                 error "'set_param a=b' did not accept a value containing '='"
22934
22935         jobid_var_new=$($LCTL get_param -n $testname)
22936         [[ "$jobid_var_new" == "$new_value" ]] ||
22937                 error "'set_param a=b' failed on a value containing '='"
22938
22939         # Reset the $testname to test the other format
22940         $LCTL set_param $testname=$jobid_var_old
22941         jobid_var_new=$($LCTL get_param -n $testname)
22942         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22943                 error "failed to reset $testname"
22944
22945         $LCTL set_param $testname $new_value ||
22946                 error "'set_param a b' did not accept a value containing '='"
22947
22948         jobid_var_new=$($LCTL get_param -n $testname)
22949         [[ "$jobid_var_new" == "$new_value" ]] ||
22950                 error "'set_param a b' failed on a value containing '='"
22951
22952         $LCTL set_param $testname $jobid_var_old
22953         jobid_var_new=$($LCTL get_param -n $testname)
22954         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22955                 error "failed to reset $testname"
22956 }
22957 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22958
22959 test_402() {
22960         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22961         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22962                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22963         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22964                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22965                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22966         remote_mds_nodsh && skip "remote MDS with nodsh"
22967
22968         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22969 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22970         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22971         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22972                 echo "Touch failed - OK"
22973 }
22974 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22975
22976 test_403() {
22977         local file1=$DIR/$tfile.1
22978         local file2=$DIR/$tfile.2
22979         local tfile=$TMP/$tfile
22980
22981         rm -f $file1 $file2 $tfile
22982
22983         touch $file1
22984         ln $file1 $file2
22985
22986         # 30 sec OBD_TIMEOUT in ll_getattr()
22987         # right before populating st_nlink
22988         $LCTL set_param fail_loc=0x80001409
22989         stat -c %h $file1 > $tfile &
22990
22991         # create an alias, drop all locks and reclaim the dentry
22992         < $file2
22993         cancel_lru_locks mdc
22994         cancel_lru_locks osc
22995         sysctl -w vm.drop_caches=2
22996
22997         wait
22998
22999         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23000
23001         rm -f $tfile $file1 $file2
23002 }
23003 run_test 403 "i_nlink should not drop to zero due to aliasing"
23004
23005 test_404() { # LU-6601
23006         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23007                 skip "Need server version newer than 2.8.52"
23008         remote_mds_nodsh && skip "remote MDS with nodsh"
23009
23010         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23011                 awk '/osp .*-osc-MDT/ { print $4}')
23012
23013         local osp
23014         for osp in $mosps; do
23015                 echo "Deactivate: " $osp
23016                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23017                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23018                         awk -vp=$osp '$4 == p { print $2 }')
23019                 [ $stat = IN ] || {
23020                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23021                         error "deactivate error"
23022                 }
23023                 echo "Activate: " $osp
23024                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23025                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23026                         awk -vp=$osp '$4 == p { print $2 }')
23027                 [ $stat = UP ] || {
23028                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23029                         error "activate error"
23030                 }
23031         done
23032 }
23033 run_test 404 "validate manual {de}activated works properly for OSPs"
23034
23035 test_405() {
23036         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23037         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23038                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23039                         skip "Layout swap lock is not supported"
23040
23041         check_swap_layouts_support
23042         check_swap_layout_no_dom $DIR
23043
23044         test_mkdir $DIR/$tdir
23045         swap_lock_test -d $DIR/$tdir ||
23046                 error "One layout swap locked test failed"
23047 }
23048 run_test 405 "Various layout swap lock tests"
23049
23050 test_406() {
23051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23052         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23053         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23055         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23056                 skip "Need MDS version at least 2.8.50"
23057
23058         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23059         local test_pool=$TESTNAME
23060
23061         pool_add $test_pool || error "pool_add failed"
23062         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23063                 error "pool_add_targets failed"
23064
23065         save_layout_restore_at_exit $MOUNT
23066
23067         # parent set default stripe count only, child will stripe from both
23068         # parent and fs default
23069         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23070                 error "setstripe $MOUNT failed"
23071         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23072         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23073         for i in $(seq 10); do
23074                 local f=$DIR/$tdir/$tfile.$i
23075                 touch $f || error "touch failed"
23076                 local count=$($LFS getstripe -c $f)
23077                 [ $count -eq $OSTCOUNT ] ||
23078                         error "$f stripe count $count != $OSTCOUNT"
23079                 local offset=$($LFS getstripe -i $f)
23080                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23081                 local size=$($LFS getstripe -S $f)
23082                 [ $size -eq $((def_stripe_size * 2)) ] ||
23083                         error "$f stripe size $size != $((def_stripe_size * 2))"
23084                 local pool=$($LFS getstripe -p $f)
23085                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23086         done
23087
23088         # change fs default striping, delete parent default striping, now child
23089         # will stripe from new fs default striping only
23090         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23091                 error "change $MOUNT default stripe failed"
23092         $LFS setstripe -c 0 $DIR/$tdir ||
23093                 error "delete $tdir default stripe failed"
23094         for i in $(seq 11 20); do
23095                 local f=$DIR/$tdir/$tfile.$i
23096                 touch $f || error "touch $f failed"
23097                 local count=$($LFS getstripe -c $f)
23098                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23099                 local offset=$($LFS getstripe -i $f)
23100                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23101                 local size=$($LFS getstripe -S $f)
23102                 [ $size -eq $def_stripe_size ] ||
23103                         error "$f stripe size $size != $def_stripe_size"
23104                 local pool=$($LFS getstripe -p $f)
23105                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23106         done
23107
23108         unlinkmany $DIR/$tdir/$tfile. 1 20
23109
23110         local f=$DIR/$tdir/$tfile
23111         pool_remove_all_targets $test_pool $f
23112         pool_remove $test_pool $f
23113 }
23114 run_test 406 "DNE support fs default striping"
23115
23116 test_407() {
23117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23118         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23119                 skip "Need MDS version at least 2.8.55"
23120         remote_mds_nodsh && skip "remote MDS with nodsh"
23121
23122         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23123                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23124         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23125                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23126         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23127
23128         #define OBD_FAIL_DT_TXN_STOP    0x2019
23129         for idx in $(seq $MDSCOUNT); do
23130                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23131         done
23132         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23133         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23134                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23135         true
23136 }
23137 run_test 407 "transaction fail should cause operation fail"
23138
23139 test_408() {
23140         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23141
23142         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23143         lctl set_param fail_loc=0x8000040a
23144         # let ll_prepare_partial_page() fail
23145         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23146
23147         rm -f $DIR/$tfile
23148
23149         # create at least 100 unused inodes so that
23150         # shrink_icache_memory(0) should not return 0
23151         touch $DIR/$tfile-{0..100}
23152         rm -f $DIR/$tfile-{0..100}
23153         sync
23154
23155         echo 2 > /proc/sys/vm/drop_caches
23156 }
23157 run_test 408 "drop_caches should not hang due to page leaks"
23158
23159 test_409()
23160 {
23161         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23162
23163         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23164         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23165         touch $DIR/$tdir/guard || error "(2) Fail to create"
23166
23167         local PREFIX=$(str_repeat 'A' 128)
23168         echo "Create 1K hard links start at $(date)"
23169         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23170                 error "(3) Fail to hard link"
23171
23172         echo "Links count should be right although linkEA overflow"
23173         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23174         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23175         [ $linkcount -eq 1001 ] ||
23176                 error "(5) Unexpected hard links count: $linkcount"
23177
23178         echo "List all links start at $(date)"
23179         ls -l $DIR/$tdir/foo > /dev/null ||
23180                 error "(6) Fail to list $DIR/$tdir/foo"
23181
23182         echo "Unlink hard links start at $(date)"
23183         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23184                 error "(7) Fail to unlink"
23185         echo "Unlink hard links finished at $(date)"
23186 }
23187 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23188
23189 test_410()
23190 {
23191         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23192                 skip "Need client version at least 2.9.59"
23193         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23194                 skip "Need MODULES build"
23195
23196         # Create a file, and stat it from the kernel
23197         local testfile=$DIR/$tfile
23198         touch $testfile
23199
23200         local run_id=$RANDOM
23201         local my_ino=$(stat --format "%i" $testfile)
23202
23203         # Try to insert the module. This will always fail as the
23204         # module is designed to not be inserted.
23205         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23206             &> /dev/null
23207
23208         # Anything but success is a test failure
23209         dmesg | grep -q \
23210             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23211             error "no inode match"
23212 }
23213 run_test 410 "Test inode number returned from kernel thread"
23214
23215 cleanup_test411_cgroup() {
23216         trap 0
23217         rmdir "$1"
23218 }
23219
23220 test_411() {
23221         local cg_basedir=/sys/fs/cgroup/memory
23222         # LU-9966
23223         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23224                 skip "no setup for cgroup"
23225
23226         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23227                 error "test file creation failed"
23228         cancel_lru_locks osc
23229
23230         # Create a very small memory cgroup to force a slab allocation error
23231         local cgdir=$cg_basedir/osc_slab_alloc
23232         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23233         trap "cleanup_test411_cgroup $cgdir" EXIT
23234         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23235         echo 1M > $cgdir/memory.limit_in_bytes
23236
23237         # Should not LBUG, just be killed by oom-killer
23238         # dd will return 0 even allocation failure in some environment.
23239         # So don't check return value
23240         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23241         cleanup_test411_cgroup $cgdir
23242
23243         return 0
23244 }
23245 run_test 411 "Slab allocation error with cgroup does not LBUG"
23246
23247 test_412() {
23248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23249         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23250                 skip "Need server version at least 2.10.55"
23251         fi
23252
23253         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23254                 error "mkdir failed"
23255         $LFS getdirstripe $DIR/$tdir
23256         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23257         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23258                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23259         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23260         [ $stripe_count -eq 2 ] ||
23261                 error "expect 2 get $stripe_count"
23262 }
23263 run_test 412 "mkdir on specific MDTs"
23264
23265 test_qos_mkdir() {
23266         local mkdir_cmd=$1
23267         local stripe_count=$2
23268         local mdts=$(comma_list $(mdts_nodes))
23269
23270         local testdir
23271         local lmv_qos_prio_free
23272         local lmv_qos_threshold_rr
23273         local lmv_qos_maxage
23274         local lod_qos_prio_free
23275         local lod_qos_threshold_rr
23276         local lod_qos_maxage
23277         local count
23278         local i
23279
23280         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23281         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23282         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23283                 head -n1)
23284         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23285         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23286         stack_trap "$LCTL set_param \
23287                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23288         stack_trap "$LCTL set_param \
23289                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23290         stack_trap "$LCTL set_param \
23291                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23292
23293         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23294                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23295         lod_qos_prio_free=${lod_qos_prio_free%%%}
23296         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23297                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23298         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23299         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23300                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23301         stack_trap "do_nodes $mdts $LCTL set_param \
23302                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23303         stack_trap "do_nodes $mdts $LCTL set_param \
23304                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23305                 EXIT
23306         stack_trap "do_nodes $mdts $LCTL set_param \
23307                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23308
23309         echo
23310         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23311
23312         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23313         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23314
23315         testdir=$DIR/$tdir-s$stripe_count/rr
23316
23317         for i in $(seq $((100 * MDSCOUNT))); do
23318                 eval $mkdir_cmd $testdir/subdir$i ||
23319                         error "$mkdir_cmd subdir$i failed"
23320         done
23321
23322         for i in $(seq $MDSCOUNT); do
23323                 count=$($LFS getdirstripe -i $testdir/* |
23324                                 grep ^$((i - 1))$ | wc -l)
23325                 echo "$count directories created on MDT$((i - 1))"
23326                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23327
23328                 if [ $stripe_count -gt 1 ]; then
23329                         count=$($LFS getdirstripe $testdir/* |
23330                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23331                         echo "$count stripes created on MDT$((i - 1))"
23332                         # deviation should < 5% of average
23333                         [ $count -lt $((95 * stripe_count)) ] ||
23334                         [ $count -gt $((105 * stripe_count)) ] &&
23335                                 error "stripes are not evenly distributed"
23336                 fi
23337         done
23338
23339         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23340         do_nodes $mdts $LCTL set_param \
23341                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23342
23343         echo
23344         echo "Check for uneven MDTs: "
23345
23346         local ffree
23347         local bavail
23348         local max
23349         local min
23350         local max_index
23351         local min_index
23352         local tmp
23353
23354         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23355         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23356         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23357
23358         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23359         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23360         max_index=0
23361         min_index=0
23362         for ((i = 1; i < ${#ffree[@]}; i++)); do
23363                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23364                 if [ $tmp -gt $max ]; then
23365                         max=$tmp
23366                         max_index=$i
23367                 fi
23368                 if [ $tmp -lt $min ]; then
23369                         min=$tmp
23370                         min_index=$i
23371                 fi
23372         done
23373
23374         [ ${ffree[min_index]} -eq 0 ] &&
23375                 skip "no free files in MDT$min_index"
23376         [ ${ffree[min_index]} -gt 100000000 ] &&
23377                 skip "too much free files in MDT$min_index"
23378
23379         # Check if we need to generate uneven MDTs
23380         local threshold=50
23381         local diff=$(((max - min) * 100 / min))
23382         local value="$(generate_string 1024)"
23383
23384         while [ $diff -lt $threshold ]; do
23385                 # generate uneven MDTs, create till $threshold% diff
23386                 echo -n "weight diff=$diff% must be > $threshold% ..."
23387                 count=$((${ffree[min_index]} / 10))
23388                 # 50 sec per 10000 files in vm
23389                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23390                         skip "$count files to create"
23391                 echo "Fill MDT$min_index with $count files"
23392                 [ -d $DIR/$tdir-MDT$min_index ] ||
23393                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23394                         error "mkdir $tdir-MDT$min_index failed"
23395                 for i in $(seq $count); do
23396                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23397                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23398                                 error "create f$j_$i failed"
23399                         setfattr -n user.413b -v $value \
23400                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23401                                 error "setfattr f$j_$i failed"
23402                 done
23403
23404                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23405                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23406                 max=$(((${ffree[max_index]} >> 8) * \
23407                         (${bavail[max_index]} * bsize >> 16)))
23408                 min=$(((${ffree[min_index]} >> 8) * \
23409                         (${bavail[min_index]} * bsize >> 16)))
23410                 diff=$(((max - min) * 100 / min))
23411         done
23412
23413         echo "MDT filesfree available: ${ffree[@]}"
23414         echo "MDT blocks available: ${bavail[@]}"
23415         echo "weight diff=$diff%"
23416
23417         echo
23418         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23419
23420         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23421         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23422         # decrease statfs age, so that it can be updated in time
23423         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23424         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23425
23426         sleep 1
23427
23428         testdir=$DIR/$tdir-s$stripe_count/qos
23429
23430         for i in $(seq $((100 * MDSCOUNT))); do
23431                 eval $mkdir_cmd $testdir/subdir$i ||
23432                         error "$mkdir_cmd subdir$i failed"
23433         done
23434
23435         for i in $(seq $MDSCOUNT); do
23436                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23437                         wc -l)
23438                 echo "$count directories created on MDT$((i - 1))"
23439
23440                 if [ $stripe_count -gt 1 ]; then
23441                         count=$($LFS getdirstripe $testdir/* |
23442                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23443                         echo "$count stripes created on MDT$((i - 1))"
23444                 fi
23445         done
23446
23447         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23448         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23449
23450         # D-value should > 10% of averge
23451         [ $((max - min)) -lt 10 ] &&
23452                 error "subdirs shouldn't be evenly distributed"
23453
23454         # ditto
23455         if [ $stripe_count -gt 1 ]; then
23456                 max=$($LFS getdirstripe $testdir/* |
23457                         grep -P "^\s+$max_index\t" | wc -l)
23458                 min=$($LFS getdirstripe $testdir/* |
23459                         grep -P "^\s+$min_index\t" | wc -l)
23460                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23461                         error "stripes shouldn't be evenly distributed"|| true
23462         fi
23463 }
23464
23465 test_413a() {
23466         [ $MDSCOUNT -lt 2 ] &&
23467                 skip "We need at least 2 MDTs for this test"
23468
23469         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23470                 skip "Need server version at least 2.12.52"
23471
23472         local stripe_count
23473
23474         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23475                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23476                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23477                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23478                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23479         done
23480 }
23481 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23482
23483 test_413b() {
23484         [ $MDSCOUNT -lt 2 ] &&
23485                 skip "We need at least 2 MDTs for this test"
23486
23487         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23488                 skip "Need server version at least 2.12.52"
23489
23490         local stripe_count
23491
23492         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23493                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23494                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23495                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23496                 $LFS setdirstripe -D -c $stripe_count \
23497                         $DIR/$tdir-s$stripe_count/rr ||
23498                         error "setdirstripe failed"
23499                 $LFS setdirstripe -D -c $stripe_count \
23500                         $DIR/$tdir-s$stripe_count/qos ||
23501                         error "setdirstripe failed"
23502                 test_qos_mkdir "mkdir" $stripe_count
23503         done
23504 }
23505 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23506
23507 test_414() {
23508 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23509         $LCTL set_param fail_loc=0x80000521
23510         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23511         rm -f $DIR/$tfile
23512 }
23513 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23514
23515 test_415() {
23516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23517         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23518                 skip "Need server version at least 2.11.52"
23519
23520         # LU-11102
23521         local total
23522         local setattr_pid
23523         local start_time
23524         local end_time
23525         local duration
23526
23527         total=500
23528         # this test may be slow on ZFS
23529         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23530
23531         # though this test is designed for striped directory, let's test normal
23532         # directory too since lock is always saved as CoS lock.
23533         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23534         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23535
23536         (
23537                 while true; do
23538                         touch $DIR/$tdir
23539                 done
23540         ) &
23541         setattr_pid=$!
23542
23543         start_time=$(date +%s)
23544         for i in $(seq $total); do
23545                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23546                         > /dev/null
23547         done
23548         end_time=$(date +%s)
23549         duration=$((end_time - start_time))
23550
23551         kill -9 $setattr_pid
23552
23553         echo "rename $total files took $duration sec"
23554         [ $duration -lt 100 ] || error "rename took $duration sec"
23555 }
23556 run_test 415 "lock revoke is not missing"
23557
23558 test_416() {
23559         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23560                 skip "Need server version at least 2.11.55"
23561
23562         # define OBD_FAIL_OSD_TXN_START    0x19a
23563         do_facet mds1 lctl set_param fail_loc=0x19a
23564
23565         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23566
23567         true
23568 }
23569 run_test 416 "transaction start failure won't cause system hung"
23570
23571 cleanup_417() {
23572         trap 0
23573         do_nodes $(comma_list $(mdts_nodes)) \
23574                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23575         do_nodes $(comma_list $(mdts_nodes)) \
23576                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23577         do_nodes $(comma_list $(mdts_nodes)) \
23578                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23579 }
23580
23581 test_417() {
23582         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23583         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23584                 skip "Need MDS version at least 2.11.56"
23585
23586         trap cleanup_417 RETURN EXIT
23587
23588         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23589         do_nodes $(comma_list $(mdts_nodes)) \
23590                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23591         $LFS migrate -m 0 $DIR/$tdir.1 &&
23592                 error "migrate dir $tdir.1 should fail"
23593
23594         do_nodes $(comma_list $(mdts_nodes)) \
23595                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23596         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23597                 error "create remote dir $tdir.2 should fail"
23598
23599         do_nodes $(comma_list $(mdts_nodes)) \
23600                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23601         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23602                 error "create striped dir $tdir.3 should fail"
23603         true
23604 }
23605 run_test 417 "disable remote dir, striped dir and dir migration"
23606
23607 # Checks that the outputs of df [-i] and lfs df [-i] match
23608 #
23609 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23610 check_lfs_df() {
23611         local dir=$2
23612         local inodes
23613         local df_out
23614         local lfs_df_out
23615         local count
23616         local passed=false
23617
23618         # blocks or inodes
23619         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23620
23621         for count in {1..100}; do
23622                 cancel_lru_locks
23623                 sync; sleep 0.2
23624
23625                 # read the lines of interest
23626                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23627                         error "df $inodes $dir | tail -n +2 failed"
23628                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23629                         error "lfs df $inodes $dir | grep summary: failed"
23630
23631                 # skip first substrings of each output as they are different
23632                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23633                 # compare the two outputs
23634                 passed=true
23635                 for i in {1..5}; do
23636                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23637                 done
23638                 $passed && break
23639         done
23640
23641         if ! $passed; then
23642                 df -P $inodes $dir
23643                 echo
23644                 lfs df $inodes $dir
23645                 error "df and lfs df $1 output mismatch: "      \
23646                       "df ${inodes}: ${df_out[*]}, "            \
23647                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23648         fi
23649 }
23650
23651 test_418() {
23652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23653
23654         local dir=$DIR/$tdir
23655         local numfiles=$((RANDOM % 4096 + 2))
23656         local numblocks=$((RANDOM % 256 + 1))
23657
23658         wait_delete_completed
23659         test_mkdir $dir
23660
23661         # check block output
23662         check_lfs_df blocks $dir
23663         # check inode output
23664         check_lfs_df inodes $dir
23665
23666         # create a single file and retest
23667         echo "Creating a single file and testing"
23668         createmany -o $dir/$tfile- 1 &>/dev/null ||
23669                 error "creating 1 file in $dir failed"
23670         check_lfs_df blocks $dir
23671         check_lfs_df inodes $dir
23672
23673         # create a random number of files
23674         echo "Creating $((numfiles - 1)) files and testing"
23675         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23676                 error "creating $((numfiles - 1)) files in $dir failed"
23677
23678         # write a random number of blocks to the first test file
23679         echo "Writing $numblocks 4K blocks and testing"
23680         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23681                 count=$numblocks &>/dev/null ||
23682                 error "dd to $dir/${tfile}-0 failed"
23683
23684         # retest
23685         check_lfs_df blocks $dir
23686         check_lfs_df inodes $dir
23687
23688         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23689                 error "unlinking $numfiles files in $dir failed"
23690 }
23691 run_test 418 "df and lfs df outputs match"
23692
23693 test_419()
23694 {
23695         local dir=$DIR/$tdir
23696
23697         mkdir -p $dir
23698         touch $dir/file
23699
23700         cancel_lru_locks mdc
23701
23702         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23703         $LCTL set_param fail_loc=0x1410
23704         cat $dir/file
23705         $LCTL set_param fail_loc=0
23706         rm -rf $dir
23707 }
23708 run_test 419 "Verify open file by name doesn't crash kernel"
23709
23710 test_420()
23711 {
23712         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23713                 skip "Need MDS version at least 2.12.53"
23714
23715         local SAVE_UMASK=$(umask)
23716         local dir=$DIR/$tdir
23717         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23718
23719         mkdir -p $dir
23720         umask 0000
23721         mkdir -m03777 $dir/testdir
23722         ls -dn $dir/testdir
23723         # Need to remove trailing '.' when SELinux is enabled
23724         local dirperms=$(ls -dn $dir/testdir |
23725                          awk '{ sub(/\.$/, "", $1); print $1}')
23726         [ $dirperms == "drwxrwsrwt" ] ||
23727                 error "incorrect perms on $dir/testdir"
23728
23729         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23730                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23731         ls -n $dir/testdir/testfile
23732         local fileperms=$(ls -n $dir/testdir/testfile |
23733                           awk '{ sub(/\.$/, "", $1); print $1}')
23734         [ $fileperms == "-rwxr-xr-x" ] ||
23735                 error "incorrect perms on $dir/testdir/testfile"
23736
23737         umask $SAVE_UMASK
23738 }
23739 run_test 420 "clear SGID bit on non-directories for non-members"
23740
23741 test_421a() {
23742         local cnt
23743         local fid1
23744         local fid2
23745
23746         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23747                 skip "Need MDS version at least 2.12.54"
23748
23749         test_mkdir $DIR/$tdir
23750         createmany -o $DIR/$tdir/f 3
23751         cnt=$(ls -1 $DIR/$tdir | wc -l)
23752         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23753
23754         fid1=$(lfs path2fid $DIR/$tdir/f1)
23755         fid2=$(lfs path2fid $DIR/$tdir/f2)
23756         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23757
23758         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23759         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23760
23761         cnt=$(ls -1 $DIR/$tdir | wc -l)
23762         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23763
23764         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23765         createmany -o $DIR/$tdir/f 3
23766         cnt=$(ls -1 $DIR/$tdir | wc -l)
23767         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23768
23769         fid1=$(lfs path2fid $DIR/$tdir/f1)
23770         fid2=$(lfs path2fid $DIR/$tdir/f2)
23771         echo "remove using fsname $FSNAME"
23772         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23773
23774         cnt=$(ls -1 $DIR/$tdir | wc -l)
23775         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23776 }
23777 run_test 421a "simple rm by fid"
23778
23779 test_421b() {
23780         local cnt
23781         local FID1
23782         local FID2
23783
23784         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23785                 skip "Need MDS version at least 2.12.54"
23786
23787         test_mkdir $DIR/$tdir
23788         createmany -o $DIR/$tdir/f 3
23789         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23790         MULTIPID=$!
23791
23792         FID1=$(lfs path2fid $DIR/$tdir/f1)
23793         FID2=$(lfs path2fid $DIR/$tdir/f2)
23794         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23795
23796         kill -USR1 $MULTIPID
23797         wait
23798
23799         cnt=$(ls $DIR/$tdir | wc -l)
23800         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23801 }
23802 run_test 421b "rm by fid on open file"
23803
23804 test_421c() {
23805         local cnt
23806         local FIDS
23807
23808         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23809                 skip "Need MDS version at least 2.12.54"
23810
23811         test_mkdir $DIR/$tdir
23812         createmany -o $DIR/$tdir/f 3
23813         touch $DIR/$tdir/$tfile
23814         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23815         cnt=$(ls -1 $DIR/$tdir | wc -l)
23816         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23817
23818         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23819         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23820
23821         cnt=$(ls $DIR/$tdir | wc -l)
23822         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23823 }
23824 run_test 421c "rm by fid against hardlinked files"
23825
23826 test_421d() {
23827         local cnt
23828         local FIDS
23829
23830         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23831                 skip "Need MDS version at least 2.12.54"
23832
23833         test_mkdir $DIR/$tdir
23834         createmany -o $DIR/$tdir/f 4097
23835         cnt=$(ls -1 $DIR/$tdir | wc -l)
23836         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23837
23838         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23839         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23840
23841         cnt=$(ls $DIR/$tdir | wc -l)
23842         rm -rf $DIR/$tdir
23843         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23844 }
23845 run_test 421d "rmfid en masse"
23846
23847 test_421e() {
23848         local cnt
23849         local FID
23850
23851         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23852         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23853                 skip "Need MDS version at least 2.12.54"
23854
23855         mkdir -p $DIR/$tdir
23856         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23857         createmany -o $DIR/$tdir/striped_dir/f 512
23858         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23859         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23860
23861         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23862                 sed "s/[/][^:]*://g")
23863         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23864
23865         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23866         rm -rf $DIR/$tdir
23867         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23868 }
23869 run_test 421e "rmfid in DNE"
23870
23871 test_421f() {
23872         local cnt
23873         local FID
23874
23875         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23876                 skip "Need MDS version at least 2.12.54"
23877
23878         test_mkdir $DIR/$tdir
23879         touch $DIR/$tdir/f
23880         cnt=$(ls -1 $DIR/$tdir | wc -l)
23881         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23882
23883         FID=$(lfs path2fid $DIR/$tdir/f)
23884         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23885         # rmfid should fail
23886         cnt=$(ls -1 $DIR/$tdir | wc -l)
23887         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23888
23889         chmod a+rw $DIR/$tdir
23890         ls -la $DIR/$tdir
23891         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23892         # rmfid should fail
23893         cnt=$(ls -1 $DIR/$tdir | wc -l)
23894         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23895
23896         rm -f $DIR/$tdir/f
23897         $RUNAS touch $DIR/$tdir/f
23898         FID=$(lfs path2fid $DIR/$tdir/f)
23899         echo "rmfid as root"
23900         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23901         cnt=$(ls -1 $DIR/$tdir | wc -l)
23902         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23903
23904         rm -f $DIR/$tdir/f
23905         $RUNAS touch $DIR/$tdir/f
23906         cnt=$(ls -1 $DIR/$tdir | wc -l)
23907         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23908         FID=$(lfs path2fid $DIR/$tdir/f)
23909         # rmfid w/o user_fid2path mount option should fail
23910         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23911         cnt=$(ls -1 $DIR/$tdir | wc -l)
23912         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23913
23914         umount_client $MOUNT || error "failed to umount client"
23915         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23916                 error "failed to mount client'"
23917
23918         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23919         # rmfid should succeed
23920         cnt=$(ls -1 $DIR/$tdir | wc -l)
23921         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23922
23923         # rmfid shouldn't allow to remove files due to dir's permission
23924         chmod a+rwx $DIR/$tdir
23925         touch $DIR/$tdir/f
23926         ls -la $DIR/$tdir
23927         FID=$(lfs path2fid $DIR/$tdir/f)
23928         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23929
23930         umount_client $MOUNT || error "failed to umount client"
23931         mount_client $MOUNT "$MOUNT_OPTS" ||
23932                 error "failed to mount client'"
23933
23934 }
23935 run_test 421f "rmfid checks permissions"
23936
23937 test_421g() {
23938         local cnt
23939         local FIDS
23940
23941         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23942         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23943                 skip "Need MDS version at least 2.12.54"
23944
23945         mkdir -p $DIR/$tdir
23946         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23947         createmany -o $DIR/$tdir/striped_dir/f 512
23948         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23949         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23950
23951         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23952                 sed "s/[/][^:]*://g")
23953
23954         rm -f $DIR/$tdir/striped_dir/f1*
23955         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23956         removed=$((512 - cnt))
23957
23958         # few files have been just removed, so we expect
23959         # rmfid to fail on their fids
23960         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23961         [ $removed != $errors ] && error "$errors != $removed"
23962
23963         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23964         rm -rf $DIR/$tdir
23965         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23966 }
23967 run_test 421g "rmfid to return errors properly"
23968
23969 test_422() {
23970         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23971         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23972         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23973         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23974         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23975
23976         local amc=$(at_max_get client)
23977         local amo=$(at_max_get mds1)
23978         local timeout=`lctl get_param -n timeout`
23979
23980         at_max_set 0 client
23981         at_max_set 0 mds1
23982
23983 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23984         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23985                         fail_val=$(((2*timeout + 10)*1000))
23986         touch $DIR/$tdir/d3/file &
23987         sleep 2
23988 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23989         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23990                         fail_val=$((2*timeout + 5))
23991         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23992         local pid=$!
23993         sleep 1
23994         kill -9 $pid
23995         sleep $((2 * timeout))
23996         echo kill $pid
23997         kill -9 $pid
23998         lctl mark touch
23999         touch $DIR/$tdir/d2/file3
24000         touch $DIR/$tdir/d2/file4
24001         touch $DIR/$tdir/d2/file5
24002
24003         wait
24004         at_max_set $amc client
24005         at_max_set $amo mds1
24006
24007         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24008         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24009                 error "Watchdog is always throttled"
24010 }
24011 run_test 422 "kill a process with RPC in progress"
24012
24013 stat_test() {
24014     df -h $MOUNT &
24015     df -h $MOUNT &
24016     df -h $MOUNT &
24017     df -h $MOUNT &
24018     df -h $MOUNT &
24019     df -h $MOUNT &
24020 }
24021
24022 test_423() {
24023     local _stats
24024     # ensure statfs cache is expired
24025     sleep 2;
24026
24027     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24028     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24029
24030     return 0
24031 }
24032 run_test 423 "statfs should return a right data"
24033
24034 test_424() {
24035 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24036         $LCTL set_param fail_loc=0x80000522
24037         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24038         rm -f $DIR/$tfile
24039 }
24040 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24041
24042 test_425() {
24043         test_mkdir -c -1 $DIR/$tdir
24044         $LFS setstripe -c -1 $DIR/$tdir
24045
24046         lru_resize_disable "" 100
24047         stack_trap "lru_resize_enable" EXIT
24048
24049         sleep 5
24050
24051         for i in $(seq $((MDSCOUNT * 125))); do
24052                 local t=$DIR/$tdir/$tfile_$i
24053
24054                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24055                         error_noexit "Create file $t"
24056         done
24057         stack_trap "rm -rf $DIR/$tdir" EXIT
24058
24059         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24060                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24061                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24062
24063                 [ $lock_count -le $lru_size ] ||
24064                         error "osc lock count $lock_count > lru size $lru_size"
24065         done
24066
24067         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24068                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24069                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24070
24071                 [ $lock_count -le $lru_size ] ||
24072                         error "mdc lock count $lock_count > lru size $lru_size"
24073         done
24074 }
24075 run_test 425 "lock count should not exceed lru size"
24076
24077 test_426() {
24078         splice-test -r $DIR/$tfile
24079         splice-test -rd $DIR/$tfile
24080         splice-test $DIR/$tfile
24081         splice-test -d $DIR/$tfile
24082 }
24083 run_test 426 "splice test on Lustre"
24084
24085 lseek_test_430() {
24086         local offset
24087         local file=$1
24088
24089         # data at [200K, 400K)
24090         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24091                 error "256K->512K dd fails"
24092         # data at [2M, 3M)
24093         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24094                 error "2M->3M dd fails"
24095         # data at [4M, 5M)
24096         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24097                 error "4M->5M dd fails"
24098         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24099         # start at first component hole #1
24100         printf "Seeking hole from 1000 ... "
24101         offset=$(lseek_test -l 1000 $file)
24102         echo $offset
24103         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24104         printf "Seeking data from 1000 ... "
24105         offset=$(lseek_test -d 1000 $file)
24106         echo $offset
24107         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24108
24109         # start at first component data block
24110         printf "Seeking hole from 300000 ... "
24111         offset=$(lseek_test -l 300000 $file)
24112         echo $offset
24113         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24114         printf "Seeking data from 300000 ... "
24115         offset=$(lseek_test -d 300000 $file)
24116         echo $offset
24117         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24118
24119         # start at the first component but beyond end of object size
24120         printf "Seeking hole from 1000000 ... "
24121         offset=$(lseek_test -l 1000000 $file)
24122         echo $offset
24123         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24124         printf "Seeking data from 1000000 ... "
24125         offset=$(lseek_test -d 1000000 $file)
24126         echo $offset
24127         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24128
24129         # start at second component stripe 2 (empty file)
24130         printf "Seeking hole from 1500000 ... "
24131         offset=$(lseek_test -l 1500000 $file)
24132         echo $offset
24133         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24134         printf "Seeking data from 1500000 ... "
24135         offset=$(lseek_test -d 1500000 $file)
24136         echo $offset
24137         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24138
24139         # start at second component stripe 1 (all data)
24140         printf "Seeking hole from 3000000 ... "
24141         offset=$(lseek_test -l 3000000 $file)
24142         echo $offset
24143         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24144         printf "Seeking data from 3000000 ... "
24145         offset=$(lseek_test -d 3000000 $file)
24146         echo $offset
24147         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24148
24149         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24150                 error "2nd dd fails"
24151         echo "Add data block at 640K...1280K"
24152
24153         # start at before new data block, in hole
24154         printf "Seeking hole from 600000 ... "
24155         offset=$(lseek_test -l 600000 $file)
24156         echo $offset
24157         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24158         printf "Seeking data from 600000 ... "
24159         offset=$(lseek_test -d 600000 $file)
24160         echo $offset
24161         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24162
24163         # start at the first component new data block
24164         printf "Seeking hole from 1000000 ... "
24165         offset=$(lseek_test -l 1000000 $file)
24166         echo $offset
24167         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24168         printf "Seeking data from 1000000 ... "
24169         offset=$(lseek_test -d 1000000 $file)
24170         echo $offset
24171         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24172
24173         # start at second component stripe 2, new data
24174         printf "Seeking hole from 1200000 ... "
24175         offset=$(lseek_test -l 1200000 $file)
24176         echo $offset
24177         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24178         printf "Seeking data from 1200000 ... "
24179         offset=$(lseek_test -d 1200000 $file)
24180         echo $offset
24181         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24182
24183         # start beyond file end
24184         printf "Using offset > filesize ... "
24185         lseek_test -l 4000000 $file && error "lseek should fail"
24186         printf "Using offset > filesize ... "
24187         lseek_test -d 4000000 $file && error "lseek should fail"
24188
24189         printf "Done\n\n"
24190 }
24191
24192 test_430a() {
24193         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24194                 skip "MDT does not support SEEK_HOLE"
24195
24196         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24197                 skip "OST does not support SEEK_HOLE"
24198
24199         local file=$DIR/$tdir/$tfile
24200
24201         mkdir -p $DIR/$tdir
24202
24203         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24204         # OST stripe #1 will have continuous data at [1M, 3M)
24205         # OST stripe #2 is empty
24206         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24207         lseek_test_430 $file
24208         rm $file
24209         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24210         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24211         lseek_test_430 $file
24212         rm $file
24213         $LFS setstripe -c2 -S 512K $file
24214         echo "Two stripes, stripe size 512K"
24215         lseek_test_430 $file
24216         rm $file
24217         # FLR with stale mirror
24218         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24219                        -N -c2 -S 1M $file
24220         echo "Mirrored file:"
24221         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24222         echo "Plain 2 stripes 1M"
24223         lseek_test_430 $file
24224         rm $file
24225 }
24226 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24227
24228 test_430b() {
24229         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24230                 skip "OST does not support SEEK_HOLE"
24231
24232         local offset
24233         local file=$DIR/$tdir/$tfile
24234
24235         mkdir -p $DIR/$tdir
24236         # Empty layout lseek should fail
24237         $MCREATE $file
24238         # seek from 0
24239         printf "Seeking hole from 0 ... "
24240         lseek_test -l 0 $file && error "lseek should fail"
24241         printf "Seeking data from 0 ... "
24242         lseek_test -d 0 $file && error "lseek should fail"
24243         rm $file
24244
24245         # 1M-hole file
24246         $LFS setstripe -E 1M -c2 -E eof $file
24247         $TRUNCATE $file 1048576
24248         printf "Seeking hole from 1000000 ... "
24249         offset=$(lseek_test -l 1000000 $file)
24250         echo $offset
24251         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24252         printf "Seeking data from 1000000 ... "
24253         lseek_test -d 1000000 $file && error "lseek should fail"
24254         rm $file
24255
24256         # full component followed by non-inited one
24257         $LFS setstripe -E 1M -c2 -E eof $file
24258         dd if=/dev/urandom of=$file bs=1M count=1
24259         printf "Seeking hole from 1000000 ... "
24260         offset=$(lseek_test -l 1000000 $file)
24261         echo $offset
24262         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24263         printf "Seeking hole from 1048576 ... "
24264         lseek_test -l 1048576 $file && error "lseek should fail"
24265         # init second component and truncate back
24266         echo "123" >> $file
24267         $TRUNCATE $file 1048576
24268         printf "Seeking hole from 1000000 ... "
24269         offset=$(lseek_test -l 1000000 $file)
24270         echo $offset
24271         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24272         printf "Seeking hole from 1048576 ... "
24273         lseek_test -l 1048576 $file && error "lseek should fail"
24274         # boundary checks for big values
24275         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24276         offset=$(lseek_test -d 0 $file.10g)
24277         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24278         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24279         offset=$(lseek_test -d 0 $file.100g)
24280         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24281         return 0
24282 }
24283 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24284
24285 test_430c() {
24286         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24287                 skip "OST does not support SEEK_HOLE"
24288
24289         local file=$DIR/$tdir/$tfile
24290         local start
24291
24292         mkdir -p $DIR/$tdir
24293         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24294
24295         # cp version 8.33+ prefers lseek over fiemap
24296         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24297                 start=$SECONDS
24298                 time cp $file /dev/null
24299                 (( SECONDS - start < 5 )) ||
24300                         error "cp: too long runtime $((SECONDS - start))"
24301
24302         fi
24303         # tar version 1.29+ supports SEEK_HOLE/DATA
24304         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24305                 start=$SECONDS
24306                 time tar cS $file - | cat > /dev/null
24307                 (( SECONDS - start < 5 )) ||
24308                         error "tar: too long runtime $((SECONDS - start))"
24309         fi
24310 }
24311 run_test 430c "lseek: external tools check"
24312
24313 test_431() { # LU-14187
24314         local file=$DIR/$tdir/$tfile
24315
24316         mkdir -p $DIR/$tdir
24317         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24318         dd if=/dev/urandom of=$file bs=4k count=1
24319         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24320         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24321         #define OBD_FAIL_OST_RESTART_IO 0x251
24322         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24323         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24324         cp $file $file.0
24325         cancel_lru_locks
24326         sync_all_data
24327         echo 3 > /proc/sys/vm/drop_caches
24328         diff  $file $file.0 || error "data diff"
24329 }
24330 run_test 431 "Restart transaction for IO"
24331
24332 prep_801() {
24333         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24334         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24335                 skip "Need server version at least 2.9.55"
24336
24337         start_full_debug_logging
24338 }
24339
24340 post_801() {
24341         stop_full_debug_logging
24342 }
24343
24344 barrier_stat() {
24345         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24346                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24347                            awk '/The barrier for/ { print $7 }')
24348                 echo $st
24349         else
24350                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24351                 echo \'$st\'
24352         fi
24353 }
24354
24355 barrier_expired() {
24356         local expired
24357
24358         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24359                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24360                           awk '/will be expired/ { print $7 }')
24361         else
24362                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24363         fi
24364
24365         echo $expired
24366 }
24367
24368 test_801a() {
24369         prep_801
24370
24371         echo "Start barrier_freeze at: $(date)"
24372         #define OBD_FAIL_BARRIER_DELAY          0x2202
24373         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24374         # Do not reduce barrier time - See LU-11873
24375         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24376
24377         sleep 2
24378         local b_status=$(barrier_stat)
24379         echo "Got barrier status at: $(date)"
24380         [ "$b_status" = "'freezing_p1'" ] ||
24381                 error "(1) unexpected barrier status $b_status"
24382
24383         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24384         wait
24385         b_status=$(barrier_stat)
24386         [ "$b_status" = "'frozen'" ] ||
24387                 error "(2) unexpected barrier status $b_status"
24388
24389         local expired=$(barrier_expired)
24390         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24391         sleep $((expired + 3))
24392
24393         b_status=$(barrier_stat)
24394         [ "$b_status" = "'expired'" ] ||
24395                 error "(3) unexpected barrier status $b_status"
24396
24397         # Do not reduce barrier time - See LU-11873
24398         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24399                 error "(4) fail to freeze barrier"
24400
24401         b_status=$(barrier_stat)
24402         [ "$b_status" = "'frozen'" ] ||
24403                 error "(5) unexpected barrier status $b_status"
24404
24405         echo "Start barrier_thaw at: $(date)"
24406         #define OBD_FAIL_BARRIER_DELAY          0x2202
24407         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24408         do_facet mgs $LCTL barrier_thaw $FSNAME &
24409
24410         sleep 2
24411         b_status=$(barrier_stat)
24412         echo "Got barrier status at: $(date)"
24413         [ "$b_status" = "'thawing'" ] ||
24414                 error "(6) unexpected barrier status $b_status"
24415
24416         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24417         wait
24418         b_status=$(barrier_stat)
24419         [ "$b_status" = "'thawed'" ] ||
24420                 error "(7) unexpected barrier status $b_status"
24421
24422         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24423         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24424         do_facet mgs $LCTL barrier_freeze $FSNAME
24425
24426         b_status=$(barrier_stat)
24427         [ "$b_status" = "'failed'" ] ||
24428                 error "(8) unexpected barrier status $b_status"
24429
24430         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24431         do_facet mgs $LCTL barrier_thaw $FSNAME
24432
24433         post_801
24434 }
24435 run_test 801a "write barrier user interfaces and stat machine"
24436
24437 test_801b() {
24438         prep_801
24439
24440         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24441         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24442         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24443         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24444         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24445
24446         cancel_lru_locks mdc
24447
24448         # 180 seconds should be long enough
24449         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24450
24451         local b_status=$(barrier_stat)
24452         [ "$b_status" = "'frozen'" ] ||
24453                 error "(6) unexpected barrier status $b_status"
24454
24455         mkdir $DIR/$tdir/d0/d10 &
24456         mkdir_pid=$!
24457
24458         touch $DIR/$tdir/d1/f13 &
24459         touch_pid=$!
24460
24461         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24462         ln_pid=$!
24463
24464         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24465         mv_pid=$!
24466
24467         rm -f $DIR/$tdir/d4/f12 &
24468         rm_pid=$!
24469
24470         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24471
24472         # To guarantee taht the 'stat' is not blocked
24473         b_status=$(barrier_stat)
24474         [ "$b_status" = "'frozen'" ] ||
24475                 error "(8) unexpected barrier status $b_status"
24476
24477         # let above commands to run at background
24478         sleep 5
24479
24480         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24481         ps -p $touch_pid || error "(10) touch should be blocked"
24482         ps -p $ln_pid || error "(11) link should be blocked"
24483         ps -p $mv_pid || error "(12) rename should be blocked"
24484         ps -p $rm_pid || error "(13) unlink should be blocked"
24485
24486         b_status=$(barrier_stat)
24487         [ "$b_status" = "'frozen'" ] ||
24488                 error "(14) unexpected barrier status $b_status"
24489
24490         do_facet mgs $LCTL barrier_thaw $FSNAME
24491         b_status=$(barrier_stat)
24492         [ "$b_status" = "'thawed'" ] ||
24493                 error "(15) unexpected barrier status $b_status"
24494
24495         wait $mkdir_pid || error "(16) mkdir should succeed"
24496         wait $touch_pid || error "(17) touch should succeed"
24497         wait $ln_pid || error "(18) link should succeed"
24498         wait $mv_pid || error "(19) rename should succeed"
24499         wait $rm_pid || error "(20) unlink should succeed"
24500
24501         post_801
24502 }
24503 run_test 801b "modification will be blocked by write barrier"
24504
24505 test_801c() {
24506         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24507
24508         prep_801
24509
24510         stop mds2 || error "(1) Fail to stop mds2"
24511
24512         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24513
24514         local b_status=$(barrier_stat)
24515         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24516                 do_facet mgs $LCTL barrier_thaw $FSNAME
24517                 error "(2) unexpected barrier status $b_status"
24518         }
24519
24520         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24521                 error "(3) Fail to rescan barrier bitmap"
24522
24523         # Do not reduce barrier time - See LU-11873
24524         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24525
24526         b_status=$(barrier_stat)
24527         [ "$b_status" = "'frozen'" ] ||
24528                 error "(4) unexpected barrier status $b_status"
24529
24530         do_facet mgs $LCTL barrier_thaw $FSNAME
24531         b_status=$(barrier_stat)
24532         [ "$b_status" = "'thawed'" ] ||
24533                 error "(5) unexpected barrier status $b_status"
24534
24535         local devname=$(mdsdevname 2)
24536
24537         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24538
24539         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24540                 error "(7) Fail to rescan barrier bitmap"
24541
24542         post_801
24543 }
24544 run_test 801c "rescan barrier bitmap"
24545
24546 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24547 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24548 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24549 saved_MOUNT_OPTS=$MOUNT_OPTS
24550
24551 cleanup_802a() {
24552         trap 0
24553
24554         stopall
24555         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24556         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24557         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24558         MOUNT_OPTS=$saved_MOUNT_OPTS
24559         setupall
24560 }
24561
24562 test_802a() {
24563         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24564         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24565         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24566                 skip "Need server version at least 2.9.55"
24567
24568         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24569
24570         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24571
24572         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24573                 error "(2) Fail to copy"
24574
24575         trap cleanup_802a EXIT
24576
24577         # sync by force before remount as readonly
24578         sync; sync_all_data; sleep 3; sync_all_data
24579
24580         stopall
24581
24582         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24583         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24584         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24585
24586         echo "Mount the server as read only"
24587         setupall server_only || error "(3) Fail to start servers"
24588
24589         echo "Mount client without ro should fail"
24590         mount_client $MOUNT &&
24591                 error "(4) Mount client without 'ro' should fail"
24592
24593         echo "Mount client with ro should succeed"
24594         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24595         mount_client $MOUNT ||
24596                 error "(5) Mount client with 'ro' should succeed"
24597
24598         echo "Modify should be refused"
24599         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24600
24601         echo "Read should be allowed"
24602         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24603                 error "(7) Read should succeed under ro mode"
24604
24605         cleanup_802a
24606 }
24607 run_test 802a "simulate readonly device"
24608
24609 test_802b() {
24610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24611         remote_mds_nodsh && skip "remote MDS with nodsh"
24612
24613         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24614                 skip "readonly option not available"
24615
24616         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24617
24618         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24619                 error "(2) Fail to copy"
24620
24621         # write back all cached data before setting MDT to readonly
24622         cancel_lru_locks
24623         sync_all_data
24624
24625         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24626         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24627
24628         echo "Modify should be refused"
24629         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24630
24631         echo "Read should be allowed"
24632         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24633                 error "(7) Read should succeed under ro mode"
24634
24635         # disable readonly
24636         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24637 }
24638 run_test 802b "be able to set MDTs to readonly"
24639
24640 test_803a() {
24641         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24642         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24643                 skip "MDS needs to be newer than 2.10.54"
24644
24645         mkdir -p $DIR/$tdir
24646         # Create some objects on all MDTs to trigger related logs objects
24647         for idx in $(seq $MDSCOUNT); do
24648                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24649                         $DIR/$tdir/dir${idx} ||
24650                         error "Fail to create $DIR/$tdir/dir${idx}"
24651         done
24652
24653         sync; sleep 3
24654         wait_delete_completed # ensure old test cleanups are finished
24655         echo "before create:"
24656         $LFS df -i $MOUNT
24657         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24658
24659         for i in {1..10}; do
24660                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24661                         error "Fail to create $DIR/$tdir/foo$i"
24662         done
24663
24664         sync; sleep 3
24665         echo "after create:"
24666         $LFS df -i $MOUNT
24667         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24668
24669         # allow for an llog to be cleaned up during the test
24670         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24671                 error "before ($before_used) + 10 > after ($after_used)"
24672
24673         for i in {1..10}; do
24674                 rm -rf $DIR/$tdir/foo$i ||
24675                         error "Fail to remove $DIR/$tdir/foo$i"
24676         done
24677
24678         sleep 3 # avoid MDT return cached statfs
24679         wait_delete_completed
24680         echo "after unlink:"
24681         $LFS df -i $MOUNT
24682         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24683
24684         # allow for an llog to be created during the test
24685         [ $after_used -le $((before_used + 1)) ] ||
24686                 error "after ($after_used) > before ($before_used) + 1"
24687 }
24688 run_test 803a "verify agent object for remote object"
24689
24690 test_803b() {
24691         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24692         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24693                 skip "MDS needs to be newer than 2.13.56"
24694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24695
24696         for i in $(seq 0 $((MDSCOUNT - 1))); do
24697                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24698         done
24699
24700         local before=0
24701         local after=0
24702
24703         local tmp
24704
24705         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24706         for i in $(seq 0 $((MDSCOUNT - 1))); do
24707                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24708                         awk '/getattr/ { print $2 }')
24709                 before=$((before + tmp))
24710         done
24711         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24712         for i in $(seq 0 $((MDSCOUNT - 1))); do
24713                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24714                         awk '/getattr/ { print $2 }')
24715                 after=$((after + tmp))
24716         done
24717
24718         [ $before -eq $after ] || error "getattr count $before != $after"
24719 }
24720 run_test 803b "remote object can getattr from cache"
24721
24722 test_804() {
24723         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24724         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24725                 skip "MDS needs to be newer than 2.10.54"
24726         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24727
24728         mkdir -p $DIR/$tdir
24729         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24730                 error "Fail to create $DIR/$tdir/dir0"
24731
24732         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24733         local dev=$(mdsdevname 2)
24734
24735         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24736                 grep ${fid} || error "NOT found agent entry for dir0"
24737
24738         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24739                 error "Fail to create $DIR/$tdir/dir1"
24740
24741         touch $DIR/$tdir/dir1/foo0 ||
24742                 error "Fail to create $DIR/$tdir/dir1/foo0"
24743         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24744         local rc=0
24745
24746         for idx in $(seq $MDSCOUNT); do
24747                 dev=$(mdsdevname $idx)
24748                 do_facet mds${idx} \
24749                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24750                         grep ${fid} && rc=$idx
24751         done
24752
24753         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24754                 error "Fail to rename foo0 to foo1"
24755         if [ $rc -eq 0 ]; then
24756                 for idx in $(seq $MDSCOUNT); do
24757                         dev=$(mdsdevname $idx)
24758                         do_facet mds${idx} \
24759                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24760                         grep ${fid} && rc=$idx
24761                 done
24762         fi
24763
24764         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24765                 error "Fail to rename foo1 to foo2"
24766         if [ $rc -eq 0 ]; then
24767                 for idx in $(seq $MDSCOUNT); do
24768                         dev=$(mdsdevname $idx)
24769                         do_facet mds${idx} \
24770                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24771                         grep ${fid} && rc=$idx
24772                 done
24773         fi
24774
24775         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24776
24777         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24778                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24779         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24780                 error "Fail to rename foo2 to foo0"
24781         unlink $DIR/$tdir/dir1/foo0 ||
24782                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24783         rm -rf $DIR/$tdir/dir0 ||
24784                 error "Fail to rm $DIR/$tdir/dir0"
24785
24786         for idx in $(seq $MDSCOUNT); do
24787                 dev=$(mdsdevname $idx)
24788                 rc=0
24789
24790                 stop mds${idx}
24791                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24792                         rc=$?
24793                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24794                         error "mount mds$idx failed"
24795                 df $MOUNT > /dev/null 2>&1
24796
24797                 # e2fsck should not return error
24798                 [ $rc -eq 0 ] ||
24799                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24800         done
24801 }
24802 run_test 804 "verify agent entry for remote entry"
24803
24804 cleanup_805() {
24805         do_facet $SINGLEMDS zfs set quota=$old $fsset
24806         unlinkmany $DIR/$tdir/f- 1000000
24807         trap 0
24808 }
24809
24810 test_805() {
24811         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24812         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24813         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24814                 skip "netfree not implemented before 0.7"
24815         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24816                 skip "Need MDS version at least 2.10.57"
24817
24818         local fsset
24819         local freekb
24820         local usedkb
24821         local old
24822         local quota
24823         local pref="osd-zfs.$FSNAME-MDT0000."
24824
24825         # limit available space on MDS dataset to meet nospace issue
24826         # quickly. then ZFS 0.7.2 can use reserved space if asked
24827         # properly (using netfree flag in osd_declare_destroy()
24828         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24829         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24830                 gawk '{print $3}')
24831         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24832         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24833         let "usedkb=usedkb-freekb"
24834         let "freekb=freekb/2"
24835         if let "freekb > 5000"; then
24836                 let "freekb=5000"
24837         fi
24838         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24839         trap cleanup_805 EXIT
24840         mkdir $DIR/$tdir
24841         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24842                 error "Can't set PFL layout"
24843         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24844         rm -rf $DIR/$tdir || error "not able to remove"
24845         do_facet $SINGLEMDS zfs set quota=$old $fsset
24846         trap 0
24847 }
24848 run_test 805 "ZFS can remove from full fs"
24849
24850 # Size-on-MDS test
24851 check_lsom_data()
24852 {
24853         local file=$1
24854         local size=$($LFS getsom -s $file)
24855         local expect=$(stat -c %s $file)
24856
24857         [[ $size == $expect ]] ||
24858                 error "$file expected size: $expect, got: $size"
24859
24860         local blocks=$($LFS getsom -b $file)
24861         expect=$(stat -c %b $file)
24862         [[ $blocks == $expect ]] ||
24863                 error "$file expected blocks: $expect, got: $blocks"
24864 }
24865
24866 check_lsom_size()
24867 {
24868         local size=$($LFS getsom -s $1)
24869         local expect=$2
24870
24871         [[ $size == $expect ]] ||
24872                 error "$file expected size: $expect, got: $size"
24873 }
24874
24875 test_806() {
24876         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24877                 skip "Need MDS version at least 2.11.52"
24878
24879         local bs=1048576
24880
24881         touch $DIR/$tfile || error "touch $tfile failed"
24882
24883         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24884         save_lustre_params client "llite.*.xattr_cache" > $save
24885         lctl set_param llite.*.xattr_cache=0
24886         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24887
24888         # single-threaded write
24889         echo "Test SOM for single-threaded write"
24890         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24891                 error "write $tfile failed"
24892         check_lsom_size $DIR/$tfile $bs
24893
24894         local num=32
24895         local size=$(($num * $bs))
24896         local offset=0
24897         local i
24898
24899         echo "Test SOM for single client multi-threaded($num) write"
24900         $TRUNCATE $DIR/$tfile 0
24901         for ((i = 0; i < $num; i++)); do
24902                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24903                 local pids[$i]=$!
24904                 offset=$((offset + $bs))
24905         done
24906         for (( i=0; i < $num; i++ )); do
24907                 wait ${pids[$i]}
24908         done
24909         check_lsom_size $DIR/$tfile $size
24910
24911         $TRUNCATE $DIR/$tfile 0
24912         for ((i = 0; i < $num; i++)); do
24913                 offset=$((offset - $bs))
24914                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24915                 local pids[$i]=$!
24916         done
24917         for (( i=0; i < $num; i++ )); do
24918                 wait ${pids[$i]}
24919         done
24920         check_lsom_size $DIR/$tfile $size
24921
24922         # multi-client writes
24923         num=$(get_node_count ${CLIENTS//,/ })
24924         size=$(($num * $bs))
24925         offset=0
24926         i=0
24927
24928         echo "Test SOM for multi-client ($num) writes"
24929         $TRUNCATE $DIR/$tfile 0
24930         for client in ${CLIENTS//,/ }; do
24931                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24932                 local pids[$i]=$!
24933                 i=$((i + 1))
24934                 offset=$((offset + $bs))
24935         done
24936         for (( i=0; i < $num; i++ )); do
24937                 wait ${pids[$i]}
24938         done
24939         check_lsom_size $DIR/$tfile $offset
24940
24941         i=0
24942         $TRUNCATE $DIR/$tfile 0
24943         for client in ${CLIENTS//,/ }; do
24944                 offset=$((offset - $bs))
24945                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24946                 local pids[$i]=$!
24947                 i=$((i + 1))
24948         done
24949         for (( i=0; i < $num; i++ )); do
24950                 wait ${pids[$i]}
24951         done
24952         check_lsom_size $DIR/$tfile $size
24953
24954         # verify truncate
24955         echo "Test SOM for truncate"
24956         $TRUNCATE $DIR/$tfile 1048576
24957         check_lsom_size $DIR/$tfile 1048576
24958         $TRUNCATE $DIR/$tfile 1234
24959         check_lsom_size $DIR/$tfile 1234
24960
24961         # verify SOM blocks count
24962         echo "Verify SOM block count"
24963         $TRUNCATE $DIR/$tfile 0
24964         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24965                 error "failed to write file $tfile"
24966         check_lsom_data $DIR/$tfile
24967 }
24968 run_test 806 "Verify Lazy Size on MDS"
24969
24970 test_807() {
24971         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24972         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24973                 skip "Need MDS version at least 2.11.52"
24974
24975         # Registration step
24976         changelog_register || error "changelog_register failed"
24977         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24978         changelog_users $SINGLEMDS | grep -q $cl_user ||
24979                 error "User $cl_user not found in changelog_users"
24980
24981         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24982         save_lustre_params client "llite.*.xattr_cache" > $save
24983         lctl set_param llite.*.xattr_cache=0
24984         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24985
24986         rm -rf $DIR/$tdir || error "rm $tdir failed"
24987         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24988         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24989         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24990         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24991                 error "truncate $tdir/trunc failed"
24992
24993         local bs=1048576
24994         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24995                 error "write $tfile failed"
24996
24997         # multi-client wirtes
24998         local num=$(get_node_count ${CLIENTS//,/ })
24999         local offset=0
25000         local i=0
25001
25002         echo "Test SOM for multi-client ($num) writes"
25003         touch $DIR/$tfile || error "touch $tfile failed"
25004         $TRUNCATE $DIR/$tfile 0
25005         for client in ${CLIENTS//,/ }; do
25006                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25007                 local pids[$i]=$!
25008                 i=$((i + 1))
25009                 offset=$((offset + $bs))
25010         done
25011         for (( i=0; i < $num; i++ )); do
25012                 wait ${pids[$i]}
25013         done
25014
25015         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25016         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25017         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25018         check_lsom_data $DIR/$tdir/trunc
25019         check_lsom_data $DIR/$tdir/single_dd
25020         check_lsom_data $DIR/$tfile
25021
25022         rm -rf $DIR/$tdir
25023         # Deregistration step
25024         changelog_deregister || error "changelog_deregister failed"
25025 }
25026 run_test 807 "verify LSOM syncing tool"
25027
25028 check_som_nologged()
25029 {
25030         local lines=$($LFS changelog $FSNAME-MDT0000 |
25031                 grep 'x=trusted.som' | wc -l)
25032         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25033 }
25034
25035 test_808() {
25036         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25037                 skip "Need MDS version at least 2.11.55"
25038
25039         # Registration step
25040         changelog_register || error "changelog_register failed"
25041
25042         touch $DIR/$tfile || error "touch $tfile failed"
25043         check_som_nologged
25044
25045         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25046                 error "write $tfile failed"
25047         check_som_nologged
25048
25049         $TRUNCATE $DIR/$tfile 1234
25050         check_som_nologged
25051
25052         $TRUNCATE $DIR/$tfile 1048576
25053         check_som_nologged
25054
25055         # Deregistration step
25056         changelog_deregister || error "changelog_deregister failed"
25057 }
25058 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25059
25060 check_som_nodata()
25061 {
25062         $LFS getsom $1
25063         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25064 }
25065
25066 test_809() {
25067         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25068                 skip "Need MDS version at least 2.11.56"
25069
25070         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25071                 error "failed to create DoM-only file $DIR/$tfile"
25072         touch $DIR/$tfile || error "touch $tfile failed"
25073         check_som_nodata $DIR/$tfile
25074
25075         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25076                 error "write $tfile failed"
25077         check_som_nodata $DIR/$tfile
25078
25079         $TRUNCATE $DIR/$tfile 1234
25080         check_som_nodata $DIR/$tfile
25081
25082         $TRUNCATE $DIR/$tfile 4097
25083         check_som_nodata $DIR/$file
25084 }
25085 run_test 809 "Verify no SOM xattr store for DoM-only files"
25086
25087 test_810() {
25088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25089         $GSS && skip_env "could not run with gss"
25090         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25091                 skip "OST < 2.12.58 doesn't align checksum"
25092
25093         set_checksums 1
25094         stack_trap "set_checksums $ORIG_CSUM" EXIT
25095         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25096
25097         local csum
25098         local before
25099         local after
25100         for csum in $CKSUM_TYPES; do
25101                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25102                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25103                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25104                         eval set -- $i
25105                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25106                         before=$(md5sum $DIR/$tfile)
25107                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25108                         after=$(md5sum $DIR/$tfile)
25109                         [ "$before" == "$after" ] ||
25110                                 error "$csum: $before != $after bs=$1 seek=$2"
25111                 done
25112         done
25113 }
25114 run_test 810 "partial page writes on ZFS (LU-11663)"
25115
25116 test_812a() {
25117         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25118                 skip "OST < 2.12.51 doesn't support this fail_loc"
25119
25120         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25121         # ensure ost1 is connected
25122         stat $DIR/$tfile >/dev/null || error "can't stat"
25123         wait_osc_import_state client ost1 FULL
25124         # no locks, no reqs to let the connection idle
25125         cancel_lru_locks osc
25126
25127         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25128 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25129         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25130         wait_osc_import_state client ost1 CONNECTING
25131         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25132
25133         stat $DIR/$tfile >/dev/null || error "can't stat file"
25134 }
25135 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25136
25137 test_812b() { # LU-12378
25138         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25139                 skip "OST < 2.12.51 doesn't support this fail_loc"
25140
25141         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25142         # ensure ost1 is connected
25143         stat $DIR/$tfile >/dev/null || error "can't stat"
25144         wait_osc_import_state client ost1 FULL
25145         # no locks, no reqs to let the connection idle
25146         cancel_lru_locks osc
25147
25148         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25149 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25150         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25151         wait_osc_import_state client ost1 CONNECTING
25152         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25153
25154         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25155         wait_osc_import_state client ost1 IDLE
25156 }
25157 run_test 812b "do not drop no resend request for idle connect"
25158
25159 test_813() {
25160         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25161         [ -z "$file_heat_sav" ] && skip "no file heat support"
25162
25163         local readsample
25164         local writesample
25165         local readbyte
25166         local writebyte
25167         local readsample1
25168         local writesample1
25169         local readbyte1
25170         local writebyte1
25171
25172         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25173         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25174
25175         $LCTL set_param -n llite.*.file_heat=1
25176         echo "Turn on file heat"
25177         echo "Period second: $period_second, Decay percentage: $decay_pct"
25178
25179         echo "QQQQ" > $DIR/$tfile
25180         echo "QQQQ" > $DIR/$tfile
25181         echo "QQQQ" > $DIR/$tfile
25182         cat $DIR/$tfile > /dev/null
25183         cat $DIR/$tfile > /dev/null
25184         cat $DIR/$tfile > /dev/null
25185         cat $DIR/$tfile > /dev/null
25186
25187         local out=$($LFS heat_get $DIR/$tfile)
25188
25189         $LFS heat_get $DIR/$tfile
25190         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25191         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25192         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25193         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25194
25195         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25196         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25197         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25198         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25199
25200         sleep $((period_second + 3))
25201         echo "Sleep $((period_second + 3)) seconds..."
25202         # The recursion formula to calculate the heat of the file f is as
25203         # follow:
25204         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25205         # Where Hi is the heat value in the period between time points i*I and
25206         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25207         # to the weight of Ci.
25208         out=$($LFS heat_get $DIR/$tfile)
25209         $LFS heat_get $DIR/$tfile
25210         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25211         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25212         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25213         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25214
25215         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25216                 error "read sample ($readsample) is wrong"
25217         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25218                 error "write sample ($writesample) is wrong"
25219         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25220                 error "read bytes ($readbyte) is wrong"
25221         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25222                 error "write bytes ($writebyte) is wrong"
25223
25224         echo "QQQQ" > $DIR/$tfile
25225         echo "QQQQ" > $DIR/$tfile
25226         echo "QQQQ" > $DIR/$tfile
25227         cat $DIR/$tfile > /dev/null
25228         cat $DIR/$tfile > /dev/null
25229         cat $DIR/$tfile > /dev/null
25230         cat $DIR/$tfile > /dev/null
25231
25232         sleep $((period_second + 3))
25233         echo "Sleep $((period_second + 3)) seconds..."
25234
25235         out=$($LFS heat_get $DIR/$tfile)
25236         $LFS heat_get $DIR/$tfile
25237         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25238         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25239         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25240         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25241
25242         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25243                 4 * $decay_pct) / 100") -eq 1 ] ||
25244                 error "read sample ($readsample1) is wrong"
25245         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25246                 3 * $decay_pct) / 100") -eq 1 ] ||
25247                 error "write sample ($writesample1) is wrong"
25248         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25249                 20 * $decay_pct) / 100") -eq 1 ] ||
25250                 error "read bytes ($readbyte1) is wrong"
25251         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25252                 15 * $decay_pct) / 100") -eq 1 ] ||
25253                 error "write bytes ($writebyte1) is wrong"
25254
25255         echo "Turn off file heat for the file $DIR/$tfile"
25256         $LFS heat_set -o $DIR/$tfile
25257
25258         echo "QQQQ" > $DIR/$tfile
25259         echo "QQQQ" > $DIR/$tfile
25260         echo "QQQQ" > $DIR/$tfile
25261         cat $DIR/$tfile > /dev/null
25262         cat $DIR/$tfile > /dev/null
25263         cat $DIR/$tfile > /dev/null
25264         cat $DIR/$tfile > /dev/null
25265
25266         out=$($LFS heat_get $DIR/$tfile)
25267         $LFS heat_get $DIR/$tfile
25268         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25269         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25270         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25271         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25272
25273         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25274         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25275         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25276         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25277
25278         echo "Trun on file heat for the file $DIR/$tfile"
25279         $LFS heat_set -O $DIR/$tfile
25280
25281         echo "QQQQ" > $DIR/$tfile
25282         echo "QQQQ" > $DIR/$tfile
25283         echo "QQQQ" > $DIR/$tfile
25284         cat $DIR/$tfile > /dev/null
25285         cat $DIR/$tfile > /dev/null
25286         cat $DIR/$tfile > /dev/null
25287         cat $DIR/$tfile > /dev/null
25288
25289         out=$($LFS heat_get $DIR/$tfile)
25290         $LFS heat_get $DIR/$tfile
25291         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25292         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25293         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25294         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25295
25296         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25297         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25298         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25299         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25300
25301         $LFS heat_set -c $DIR/$tfile
25302         $LCTL set_param -n llite.*.file_heat=0
25303         echo "Turn off file heat support for the Lustre filesystem"
25304
25305         echo "QQQQ" > $DIR/$tfile
25306         echo "QQQQ" > $DIR/$tfile
25307         echo "QQQQ" > $DIR/$tfile
25308         cat $DIR/$tfile > /dev/null
25309         cat $DIR/$tfile > /dev/null
25310         cat $DIR/$tfile > /dev/null
25311         cat $DIR/$tfile > /dev/null
25312
25313         out=$($LFS heat_get $DIR/$tfile)
25314         $LFS heat_get $DIR/$tfile
25315         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25316         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25317         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25318         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25319
25320         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25321         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25322         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25323         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25324
25325         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25326         rm -f $DIR/$tfile
25327 }
25328 run_test 813 "File heat verfication"
25329
25330 test_814()
25331 {
25332         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25333         echo -n y >> $DIR/$tfile
25334         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25335         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25336 }
25337 run_test 814 "sparse cp works as expected (LU-12361)"
25338
25339 test_815()
25340 {
25341         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25342         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25343 }
25344 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25345
25346 test_816() {
25347         local ost1_imp=$(get_osc_import_name client ost1)
25348         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25349                          cut -d'.' -f2)
25350
25351         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25352         # ensure ost1 is connected
25353
25354         stat $DIR/$tfile >/dev/null || error "can't stat"
25355         wait_osc_import_state client ost1 FULL
25356         # no locks, no reqs to let the connection idle
25357         cancel_lru_locks osc
25358         lru_resize_disable osc
25359         local before
25360         local now
25361         before=$($LCTL get_param -n \
25362                  ldlm.namespaces.$imp_name.lru_size)
25363
25364         wait_osc_import_state client ost1 IDLE
25365         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25366         now=$($LCTL get_param -n \
25367               ldlm.namespaces.$imp_name.lru_size)
25368         [ $before == $now ] || error "lru_size changed $before != $now"
25369 }
25370 run_test 816 "do not reset lru_resize on idle reconnect"
25371
25372 cleanup_817() {
25373         umount $tmpdir
25374         exportfs -u localhost:$DIR/nfsexp
25375         rm -rf $DIR/nfsexp
25376 }
25377
25378 test_817() {
25379         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25380
25381         mkdir -p $DIR/nfsexp
25382         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25383                 error "failed to export nfs"
25384
25385         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25386         stack_trap cleanup_817 EXIT
25387
25388         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25389                 error "failed to mount nfs to $tmpdir"
25390
25391         cp /bin/true $tmpdir
25392         $DIR/nfsexp/true || error "failed to execute 'true' command"
25393 }
25394 run_test 817 "nfsd won't cache write lock for exec file"
25395
25396 test_818() {
25397         mkdir $DIR/$tdir
25398         $LFS setstripe -c1 -i0 $DIR/$tfile
25399         $LFS setstripe -c1 -i1 $DIR/$tfile
25400         stop $SINGLEMDS
25401         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25402         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25403         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25404                 error "start $SINGLEMDS failed"
25405         rm -rf $DIR/$tdir
25406 }
25407 run_test 818 "unlink with failed llog"
25408
25409 test_819a() {
25410         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25411         cancel_lru_locks osc
25412         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25413         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25414         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25415         rm -f $TDIR/$tfile
25416 }
25417 run_test 819a "too big niobuf in read"
25418
25419 test_819b() {
25420         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25421         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25423         cancel_lru_locks osc
25424         sleep 1
25425         rm -f $TDIR/$tfile
25426 }
25427 run_test 819b "too big niobuf in write"
25428
25429
25430 function test_820_start_ost() {
25431         sleep 5
25432
25433         for num in $(seq $OSTCOUNT); do
25434                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25435         done
25436 }
25437
25438 test_820() {
25439         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25440
25441         mkdir $DIR/$tdir
25442         umount_client $MOUNT || error "umount failed"
25443         for num in $(seq $OSTCOUNT); do
25444                 stop ost$num
25445         done
25446
25447         # mount client with no active OSTs
25448         # so that the client can't initialize max LOV EA size
25449         # from OSC notifications
25450         mount_client $MOUNT || error "mount failed"
25451         # delay OST starting to keep this 0 max EA size for a while
25452         test_820_start_ost &
25453
25454         # create a directory on MDS2
25455         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25456                 error "Failed to create directory"
25457         # open intent should update default EA size
25458         # see mdc_update_max_ea_from_body()
25459         # notice this is the very first RPC to MDS2
25460         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25461         ret=$?
25462         echo $out
25463         # With SSK, this situation can lead to -EPERM being returned.
25464         # In that case, simply retry.
25465         if [ $ret -ne 0 ] && $SHARED_KEY; then
25466                 if echo "$out" | grep -q "not permitted"; then
25467                         cp /etc/services $DIR/$tdir/mds2
25468                         ret=$?
25469                 fi
25470         fi
25471         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25472 }
25473 run_test 820 "update max EA from open intent"
25474
25475 test_822() {
25476         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25477
25478         save_lustre_params mds1 \
25479                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25480         do_facet $SINGLEMDS "$LCTL set_param -n \
25481                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25482         do_facet $SINGLEMDS "$LCTL set_param -n \
25483                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25484
25485         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25486         local maxage=$(do_facet mds1 $LCTL get_param -n \
25487                        osp.$FSNAME-OST0000*MDT0000.maxage)
25488         sleep $((maxage + 1))
25489
25490         #define OBD_FAIL_NET_ERROR_RPC          0x532
25491         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
25492
25493         stack_trap "restore_lustre_params < $p; rm $p"
25494
25495         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
25496                       osp.$FSNAME-OST0000*MDT0000.create_count")
25497         for i in $(seq 1 $count); do
25498                 touch $DIR/$tfile.${i} || error "touch failed"
25499         done
25500 }
25501 run_test 822 "test precreate failure"
25502
25503 #
25504 # tests that do cleanup/setup should be run at the end
25505 #
25506
25507 test_900() {
25508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25509         local ls
25510
25511         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25512         $LCTL set_param fail_loc=0x903
25513
25514         cancel_lru_locks MGC
25515
25516         FAIL_ON_ERROR=true cleanup
25517         FAIL_ON_ERROR=true setup
25518 }
25519 run_test 900 "umount should not race with any mgc requeue thread"
25520
25521 # LUS-6253/LU-11185
25522 test_901() {
25523         local oldc
25524         local newc
25525         local olds
25526         local news
25527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25528
25529         # some get_param have a bug to handle dot in param name
25530         cancel_lru_locks MGC
25531         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25532         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25533         umount_client $MOUNT || error "umount failed"
25534         mount_client $MOUNT || error "mount failed"
25535         cancel_lru_locks MGC
25536         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25537         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25538
25539         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25540         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25541
25542         return 0
25543 }
25544 run_test 901 "don't leak a mgc lock on client umount"
25545
25546 # LU-13377
25547 test_902() {
25548         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25549                 skip "client does not have LU-13377 fix"
25550         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25551         $LCTL set_param fail_loc=0x1415
25552         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25553         cancel_lru_locks osc
25554         rm -f $DIR/$tfile
25555 }
25556 run_test 902 "test short write doesn't hang lustre"
25557
25558 complete $SECONDS
25559 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25560 check_and_cleanup_lustre
25561 if [ "$I_MOUNTED" != "yes" ]; then
25562         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25563 fi
25564 exit_status