Whamcloud - gitweb
LU-14779 utils: no DNS lookups for NID in get_param
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         mkdir_on_mdt0 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         mkdir_on_mdt0 $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange ||
2759                 error "pool_add_targets failed"
2760         test_mkdir $DIR/$tdir
2761         $LFS setstripe -p $pool $DIR/$tdir
2762         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2763         $LFS getstripe $DIR/$tdir/$tfile
2764 }
2765 run_test 27I "check that root dir striping does not break parent dir one"
2766
2767 test_27J() {
2768         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2769                 skip "Need MDS version newer than 2.12.51"
2770
2771         test_mkdir $DIR/$tdir
2772         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2773         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2774
2775         # create foreign file (raw way)
2776         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2777                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2778
2779         ! $LFS setstripe --foreign --flags foo \
2780                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2781                         error "creating $tfile with '--flags foo' should fail"
2782
2783         ! $LFS setstripe --foreign --flags 0xffffffff \
2784                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2785                         error "creating $tfile w/ 0xffffffff flags should fail"
2786
2787         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2788                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2789
2790         # verify foreign file (raw way)
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2794         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2796         parse_foreign_file -f $DIR/$tdir/$tfile |
2797                 grep "lov_foreign_size: 73" ||
2798                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2799         parse_foreign_file -f $DIR/$tdir/$tfile |
2800                 grep "lov_foreign_type: 1" ||
2801                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2802         parse_foreign_file -f $DIR/$tdir/$tfile |
2803                 grep "lov_foreign_flags: 0x0000DA08" ||
2804                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2805         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2806                 grep "lov_foreign_value: 0x" |
2807                 sed -e 's/lov_foreign_value: 0x//')
2808         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2809         [[ $lov = ${lov2// /} ]] ||
2810                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2811
2812         # create foreign file (lfs + API)
2813         $LFS setstripe --foreign=none --flags 0xda08 \
2814                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2815                 error "$DIR/$tdir/${tfile}2: create failed"
2816
2817         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2818                 grep "lfm_magic:.*0x0BD70BD0" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2820         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2821         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2823         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2824                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2825         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2826                 grep "lfm_flags:.*0x0000DA08" ||
2827                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2828         $LFS getstripe $DIR/$tdir/${tfile}2 |
2829                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2830                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2831
2832         # modify striping should fail
2833         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2834                 error "$DIR/$tdir/$tfile: setstripe should fail"
2835         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2837
2838         # R/W should fail
2839         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2840         cat $DIR/$tdir/${tfile}2 &&
2841                 error "$DIR/$tdir/${tfile}2: read should fail"
2842         cat /etc/passwd > $DIR/$tdir/$tfile &&
2843                 error "$DIR/$tdir/$tfile: write should fail"
2844         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2845                 error "$DIR/$tdir/${tfile}2: write should fail"
2846
2847         # chmod should work
2848         chmod 222 $DIR/$tdir/$tfile ||
2849                 error "$DIR/$tdir/$tfile: chmod failed"
2850         chmod 222 $DIR/$tdir/${tfile}2 ||
2851                 error "$DIR/$tdir/${tfile}2: chmod failed"
2852
2853         # chown should work
2854         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2855                 error "$DIR/$tdir/$tfile: chown failed"
2856         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2857                 error "$DIR/$tdir/${tfile}2: chown failed"
2858
2859         # rename should work
2860         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2861                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2862         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2863                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2864
2865         #remove foreign file
2866         rm $DIR/$tdir/${tfile}.new ||
2867                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2868         rm $DIR/$tdir/${tfile}2.new ||
2869                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2870 }
2871 run_test 27J "basic ops on file with foreign LOV"
2872
2873 test_27K() {
2874         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2875                 skip "Need MDS version newer than 2.12.49"
2876
2877         test_mkdir $DIR/$tdir
2878         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2879         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2880
2881         # create foreign dir (raw way)
2882         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2883                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2884
2885         ! $LFS setdirstripe --foreign --flags foo \
2886                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2887                         error "creating $tdir with '--flags foo' should fail"
2888
2889         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2890                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2891                         error "creating $tdir w/ 0xffffffff flags should fail"
2892
2893         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2894                 error "create_foreign_dir FAILED"
2895
2896         # verify foreign dir (raw way)
2897         parse_foreign_dir -d $DIR/$tdir/$tdir |
2898                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2899                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2900         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2902         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2903                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2904         parse_foreign_dir -d $DIR/$tdir/$tdir |
2905                 grep "lmv_foreign_flags: 55813$" ||
2906                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2907         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2908                 grep "lmv_foreign_value: 0x" |
2909                 sed 's/lmv_foreign_value: 0x//')
2910         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2911                 sed 's/ //g')
2912         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2913
2914         # create foreign dir (lfs + API)
2915         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2916                 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/$tdir/${tdir}2: create failed"
2918
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2920                 grep "lfm_magic:.*0x0CD50CD0" ||
2921                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2922         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2923         # - sizeof(lfm_type) - sizeof(lfm_flags)
2924         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2926         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2927                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2928         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2929                 grep "lfm_flags:.*0x0000DA05" ||
2930                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2931         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2932                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2933                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2934
2935         # file create in dir should fail
2936         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2937         touch $DIR/$tdir/${tdir}2/$tfile &&
2938                 "$DIR/${tdir}2: file create should fail"
2939
2940         # chmod should work
2941         chmod 777 $DIR/$tdir/$tdir ||
2942                 error "$DIR/$tdir: chmod failed"
2943         chmod 777 $DIR/$tdir/${tdir}2 ||
2944                 error "$DIR/${tdir}2: chmod failed"
2945
2946         # chown should work
2947         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2948                 error "$DIR/$tdir: chown failed"
2949         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2950                 error "$DIR/${tdir}2: chown failed"
2951
2952         # rename should work
2953         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2954                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2955         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2956                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2957
2958         #remove foreign dir
2959         rmdir $DIR/$tdir/${tdir}.new ||
2960                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2961         rmdir $DIR/$tdir/${tdir}2.new ||
2962                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2963 }
2964 run_test 27K "basic ops on dir with foreign LMV"
2965
2966 test_27L() {
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968
2969         local POOL=${POOL:-$TESTNAME}
2970
2971         pool_add $POOL || error "pool_add failed"
2972
2973         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2974                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2975                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2976 }
2977 run_test 27L "lfs pool_list gives correct pool name"
2978
2979 test_27M() {
2980         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2981                 skip "Need MDS version >= than 2.12.57"
2982         remote_mds_nodsh && skip "remote MDS with nodsh"
2983         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2984
2985         test_mkdir $DIR/$tdir
2986
2987         # Set default striping on directory
2988         $LFS setstripe -C 4 $DIR/$tdir
2989
2990         echo 1 > $DIR/$tdir/${tfile}.1
2991         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2992         local setcount=4
2993         [ $count -eq $setcount ] ||
2994                 error "(1) stripe count $count, should be $setcount"
2995
2996         # Capture existing append_stripe_count setting for restore
2997         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2998         local mdts=$(comma_list $(mdts_nodes))
2999         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3000
3001         local appendcount=$orig_count
3002         echo 1 >> $DIR/$tdir/${tfile}.2_append
3003         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3004         [ $count -eq $appendcount ] ||
3005                 error "(2)stripe count $count, should be $appendcount for append"
3006
3007         # Disable O_APPEND striping, verify it works
3008         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3009
3010         # Should now get the default striping, which is 4
3011         setcount=4
3012         echo 1 >> $DIR/$tdir/${tfile}.3_append
3013         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3014         [ $count -eq $setcount ] ||
3015                 error "(3) stripe count $count, should be $setcount"
3016
3017         # Try changing the stripe count for append files
3018         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3019
3020         # Append striping is now 2 (directory default is still 4)
3021         appendcount=2
3022         echo 1 >> $DIR/$tdir/${tfile}.4_append
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3024         [ $count -eq $appendcount ] ||
3025                 error "(4) stripe count $count, should be $appendcount for append"
3026
3027         # Test append stripe count of -1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3029         appendcount=$OSTCOUNT
3030         echo 1 >> $DIR/$tdir/${tfile}.5
3031         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3032         [ $count -eq $appendcount ] ||
3033                 error "(5) stripe count $count, should be $appendcount for append"
3034
3035         # Set append striping back to default of 1
3036         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3037
3038         # Try a new default striping, PFL + DOM
3039         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3040
3041         # Create normal DOM file, DOM returns stripe count == 0
3042         setcount=0
3043         touch $DIR/$tdir/${tfile}.6
3044         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3045         [ $count -eq $setcount ] ||
3046                 error "(6) stripe count $count, should be $setcount"
3047
3048         # Show
3049         appendcount=1
3050         echo 1 >> $DIR/$tdir/${tfile}.7_append
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3052         [ $count -eq $appendcount ] ||
3053                 error "(7) stripe count $count, should be $appendcount for append"
3054
3055         # Clean up DOM layout
3056         $LFS setstripe -d $DIR/$tdir
3057
3058         # Now test that append striping works when layout is from root
3059         $LFS setstripe -c 2 $MOUNT
3060         # Make a special directory for this
3061         mkdir $DIR/${tdir}/${tdir}.2
3062         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3063
3064         # Verify for normal file
3065         setcount=2
3066         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3067         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3068         [ $count -eq $setcount ] ||
3069                 error "(8) stripe count $count, should be $setcount"
3070
3071         appendcount=1
3072         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3073         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3074         [ $count -eq $appendcount ] ||
3075                 error "(9) stripe count $count, should be $appendcount for append"
3076
3077         # Now test O_APPEND striping with pools
3078         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3079         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3080
3081         # Create the pool
3082         pool_add $TESTNAME || error "pool creation failed"
3083         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3084
3085         echo 1 >> $DIR/$tdir/${tfile}.10_append
3086
3087         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3088         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3089
3090         # Check that count is still correct
3091         appendcount=1
3092         echo 1 >> $DIR/$tdir/${tfile}.11_append
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3094         [ $count -eq $appendcount ] ||
3095                 error "(11) stripe count $count, should be $appendcount for append"
3096
3097         # Disable O_APPEND stripe count, verify pool works separately
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3099
3100         echo 1 >> $DIR/$tdir/${tfile}.12_append
3101
3102         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3103         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3104
3105         # Remove pool setting, verify it's not applied
3106         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3107
3108         echo 1 >> $DIR/$tdir/${tfile}.13_append
3109
3110         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3111         [ "$pool" = "" ] || error "(13) pool found: $pool"
3112 }
3113 run_test 27M "test O_APPEND striping"
3114
3115 test_27N() {
3116         combined_mgs_mds && skip "needs separate MGS/MDT"
3117
3118         pool_add $TESTNAME || error "pool_add failed"
3119         do_facet mgs "$LCTL pool_list $FSNAME" |
3120                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3121                 error "lctl pool_list on MGS failed"
3122 }
3123 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3124
3125 clean_foreign_symlink() {
3126         trap 0
3127         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3128         for i in $DIR/$tdir/* ; do
3129                 $LFS unlink_foreign $i || true
3130         done
3131 }
3132
3133 test_27O() {
3134         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3135                 skip "Need MDS version newer than 2.12.51"
3136
3137         test_mkdir $DIR/$tdir
3138         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3139         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3140
3141         trap clean_foreign_symlink EXIT
3142
3143         # enable foreign_symlink behaviour
3144         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3145
3146         # foreign symlink LOV format is a partial path by default
3147
3148         # create foreign file (lfs + API)
3149         $LFS setstripe --foreign=symlink --flags 0xda05 \
3150                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3151                 error "$DIR/$tdir/${tfile}: create failed"
3152
3153         $LFS getstripe -v $DIR/$tdir/${tfile} |
3154                 grep "lfm_magic:.*0x0BD70BD0" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3156         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3158         $LFS getstripe -v $DIR/$tdir/${tfile} |
3159                 grep "lfm_flags:.*0x0000DA05" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3161         $LFS getstripe $DIR/$tdir/${tfile} |
3162                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3163                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3164
3165         # modify striping should fail
3166         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3167                 error "$DIR/$tdir/$tfile: setstripe should fail"
3168
3169         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3170         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3171         cat /etc/passwd > $DIR/$tdir/$tfile &&
3172                 error "$DIR/$tdir/$tfile: write should fail"
3173
3174         # rename should succeed
3175         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3176                 error "$DIR/$tdir/$tfile: rename has failed"
3177
3178         #remove foreign_symlink file should fail
3179         rm $DIR/$tdir/${tfile}.new &&
3180                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3181
3182         #test fake symlink
3183         mkdir /tmp/${uuid1} ||
3184                 error "/tmp/${uuid1}: mkdir has failed"
3185         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3186                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3188         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3190         #read should succeed now
3191         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3192                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3193         #write should succeed now
3194         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3196         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3198         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3199                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3200
3201         #check that getstripe still works
3202         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3203                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3204
3205         # chmod should still succeed
3206         chmod 644 $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3208
3209         # chown should still succeed
3210         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3211                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3212
3213         # rename should still succeed
3214         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3215                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3216
3217         #remove foreign_symlink file should still fail
3218         rm $DIR/$tdir/${tfile} &&
3219                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3220
3221         #use special ioctl() to unlink foreign_symlink file
3222         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3223                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3224
3225 }
3226 run_test 27O "basic ops on foreign file of symlink type"
3227
3228 test_27P() {
3229         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3230                 skip "Need MDS version newer than 2.12.49"
3231
3232         test_mkdir $DIR/$tdir
3233         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3234         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3235
3236         trap clean_foreign_symlink EXIT
3237
3238         # enable foreign_symlink behaviour
3239         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3240
3241         # foreign symlink LMV format is a partial path by default
3242
3243         # create foreign dir (lfs + API)
3244         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3245                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3246                 error "$DIR/$tdir/${tdir}: create failed"
3247
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3249                 grep "lfm_magic:.*0x0CD50CD0" ||
3250                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3251         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3253         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3254                 grep "lfm_flags:.*0x0000DA05" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3256         $LFS getdirstripe $DIR/$tdir/${tdir} |
3257                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3258                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3259
3260         # file create in dir should fail
3261         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3262         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3263
3264         # rename should succeed
3265         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3266                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3267
3268         #remove foreign_symlink dir should fail
3269         rmdir $DIR/$tdir/${tdir}.new &&
3270                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3271
3272         #test fake symlink
3273         mkdir -p /tmp/${uuid1}/${uuid2} ||
3274                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3275         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3276                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3277         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3278         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3279                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3280         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3281                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3282
3283         #check that getstripe fails now that foreign_symlink enabled
3284         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3285                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3286
3287         # file create in dir should work now
3288         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3289                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3290         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3291                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3292         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3293                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3294
3295         # chmod should still succeed
3296         chmod 755 $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3298
3299         # chown should still succeed
3300         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3301                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3302
3303         # rename should still succeed
3304         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3305                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3306
3307         #remove foreign_symlink dir should still fail
3308         rmdir $DIR/$tdir/${tdir} &&
3309                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3310
3311         #use special ioctl() to unlink foreign_symlink file
3312         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3313                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3314
3315         #created file should still exist
3316         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3317                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3318         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3319                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3320 }
3321 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3322
3323 test_27Q() {
3324         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3325         stack_trap "rm -f $TMP/$tfile*"
3326
3327         test_mkdir $DIR/$tdir-1
3328         test_mkdir $DIR/$tdir-2
3329
3330         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3331         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3334         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3335
3336         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3337         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3338
3339         # Create some bad symlinks and ensure that we don't loop
3340         # forever or something. These should return ELOOP (40) and
3341         # ENOENT (2) but I don't want to test for that because there's
3342         # always some weirdo architecture that needs to ruin
3343         # everything by defining these error numbers differently.
3344
3345         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3346         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3347
3348         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3349         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3350
3351         return 0
3352 }
3353 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3354
3355 # createtest also checks that device nodes are created and
3356 # then visible correctly (#2091)
3357 test_28() { # bug 2091
3358         test_mkdir $DIR/d28
3359         $CREATETEST $DIR/d28/ct || error "createtest failed"
3360 }
3361 run_test 28 "create/mknod/mkdir with bad file types ============"
3362
3363 test_29() {
3364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3365
3366         sync; sleep 1; sync # flush out any dirty pages from previous tests
3367         cancel_lru_locks
3368         test_mkdir $DIR/d29
3369         touch $DIR/d29/foo
3370         log 'first d29'
3371         ls -l $DIR/d29
3372
3373         declare -i LOCKCOUNTORIG=0
3374         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3375                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3376         done
3377         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3378
3379         declare -i LOCKUNUSEDCOUNTORIG=0
3380         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3381                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3382         done
3383
3384         log 'second d29'
3385         ls -l $DIR/d29
3386         log 'done'
3387
3388         declare -i LOCKCOUNTCURRENT=0
3389         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3390                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3391         done
3392
3393         declare -i LOCKUNUSEDCOUNTCURRENT=0
3394         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3395                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3396         done
3397
3398         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3399                 $LCTL set_param -n ldlm.dump_namespaces ""
3400                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3401                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3402                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3403                 return 2
3404         fi
3405         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3406                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3407                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3408                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3409                 return 3
3410         fi
3411 }
3412 run_test 29 "IT_GETATTR regression  ============================"
3413
3414 test_30a() { # was test_30
3415         cp $(which ls) $DIR || cp /bin/ls $DIR
3416         $DIR/ls / || error "Can't execute binary from lustre"
3417         rm $DIR/ls
3418 }
3419 run_test 30a "execute binary from Lustre (execve) =============="
3420
3421 test_30b() {
3422         cp `which ls` $DIR || cp /bin/ls $DIR
3423         chmod go+rx $DIR/ls
3424         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3425         rm $DIR/ls
3426 }
3427 run_test 30b "execute binary from Lustre as non-root ==========="
3428
3429 test_30c() { # b=22376
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431
3432         cp $(which ls) $DIR || cp /bin/ls $DIR
3433         chmod a-rw $DIR/ls
3434         cancel_lru_locks mdc
3435         cancel_lru_locks osc
3436         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3437         rm -f $DIR/ls
3438 }
3439 run_test 30c "execute binary from Lustre without read perms ===="
3440
3441 test_30d() {
3442         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3443
3444         for i in {1..10}; do
3445                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3446                 local PID=$!
3447                 sleep 1
3448                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3449                 wait $PID || error "executing dd from Lustre failed"
3450                 rm -f $DIR/$tfile
3451         done
3452
3453         rm -f $DIR/dd
3454 }
3455 run_test 30d "execute binary from Lustre while clear locks"
3456
3457 test_31a() {
3458         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3459         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3460 }
3461 run_test 31a "open-unlink file =================================="
3462
3463 test_31b() {
3464         touch $DIR/f31 || error "touch $DIR/f31 failed"
3465         ln $DIR/f31 $DIR/f31b || error "ln failed"
3466         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3467         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3468 }
3469 run_test 31b "unlink file with multiple links while open ======="
3470
3471 test_31c() {
3472         touch $DIR/f31 || error "touch $DIR/f31 failed"
3473         ln $DIR/f31 $DIR/f31c || error "ln failed"
3474         multiop_bg_pause $DIR/f31 O_uc ||
3475                 error "multiop_bg_pause for $DIR/f31 failed"
3476         MULTIPID=$!
3477         $MULTIOP $DIR/f31c Ouc
3478         kill -USR1 $MULTIPID
3479         wait $MULTIPID
3480 }
3481 run_test 31c "open-unlink file with multiple links ============="
3482
3483 test_31d() {
3484         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3485         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3486 }
3487 run_test 31d "remove of open directory ========================="
3488
3489 test_31e() { # bug 2904
3490         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3491 }
3492 run_test 31e "remove of open non-empty directory ==============="
3493
3494 test_31f() { # bug 4554
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         set -vx
3498         test_mkdir $DIR/d31f
3499         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3500         cp /etc/hosts $DIR/d31f
3501         ls -l $DIR/d31f
3502         $LFS getstripe $DIR/d31f/hosts
3503         multiop_bg_pause $DIR/d31f D_c || return 1
3504         MULTIPID=$!
3505
3506         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3507         test_mkdir $DIR/d31f
3508         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3509         cp /etc/hosts $DIR/d31f
3510         ls -l $DIR/d31f
3511         $LFS getstripe $DIR/d31f/hosts
3512         multiop_bg_pause $DIR/d31f D_c || return 1
3513         MULTIPID2=$!
3514
3515         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3516         wait $MULTIPID || error "first opendir $MULTIPID failed"
3517
3518         sleep 6
3519
3520         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3521         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3522         set +vx
3523 }
3524 run_test 31f "remove of open directory with open-unlink file ==="
3525
3526 test_31g() {
3527         echo "-- cross directory link --"
3528         test_mkdir -c1 $DIR/${tdir}ga
3529         test_mkdir -c1 $DIR/${tdir}gb
3530         touch $DIR/${tdir}ga/f
3531         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3532         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3533         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3534         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3535         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3536 }
3537 run_test 31g "cross directory link==============="
3538
3539 test_31h() {
3540         echo "-- cross directory link --"
3541         test_mkdir -c1 $DIR/${tdir}
3542         test_mkdir -c1 $DIR/${tdir}/dir
3543         touch $DIR/${tdir}/f
3544         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3545         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3546         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3547         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3548         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3549 }
3550 run_test 31h "cross directory link under child==============="
3551
3552 test_31i() {
3553         echo "-- cross directory link --"
3554         test_mkdir -c1 $DIR/$tdir
3555         test_mkdir -c1 $DIR/$tdir/dir
3556         touch $DIR/$tdir/dir/f
3557         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3558         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3559         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3560         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3561         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3562 }
3563 run_test 31i "cross directory link under parent==============="
3564
3565 test_31j() {
3566         test_mkdir -c1 -p $DIR/$tdir
3567         test_mkdir -c1 -p $DIR/$tdir/dir1
3568         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3569         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3571         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3572         return 0
3573 }
3574 run_test 31j "link for directory==============="
3575
3576 test_31k() {
3577         test_mkdir -c1 -p $DIR/$tdir
3578         touch $DIR/$tdir/s
3579         touch $DIR/$tdir/exist
3580         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3581         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3582         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3583         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3584         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3586         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3587         return 0
3588 }
3589 run_test 31k "link to file: the same, non-existing, dir==============="
3590
3591 test_31m() {
3592         mkdir $DIR/d31m
3593         touch $DIR/d31m/s
3594         mkdir $DIR/d31m2
3595         touch $DIR/d31m2/exist
3596         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3597         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3598         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3599         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3601         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3602         return 0
3603 }
3604 run_test 31m "link to file: the same, non-existing, dir==============="
3605
3606 test_31n() {
3607         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3608         nlink=$(stat --format=%h $DIR/$tfile)
3609         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3610         local fd=$(free_fd)
3611         local cmd="exec $fd<$DIR/$tfile"
3612         eval $cmd
3613         cmd="exec $fd<&-"
3614         trap "eval $cmd" EXIT
3615         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3616         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3617         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3618         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3619         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3620         eval $cmd
3621 }
3622 run_test 31n "check link count of unlinked file"
3623
3624 link_one() {
3625         local tempfile=$(mktemp $1_XXXXXX)
3626         mlink $tempfile $1 2> /dev/null &&
3627                 echo "$BASHPID: link $tempfile to $1 succeeded"
3628         munlink $tempfile
3629 }
3630
3631 test_31o() { # LU-2901
3632         test_mkdir $DIR/$tdir
3633         for LOOP in $(seq 100); do
3634                 rm -f $DIR/$tdir/$tfile*
3635                 for THREAD in $(seq 8); do
3636                         link_one $DIR/$tdir/$tfile.$LOOP &
3637                 done
3638                 wait
3639                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3640                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3641                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3642                         break || true
3643         done
3644 }
3645 run_test 31o "duplicate hard links with same filename"
3646
3647 test_31p() {
3648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3649
3650         test_mkdir $DIR/$tdir
3651         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3652         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3653
3654         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3655                 error "open unlink test1 failed"
3656         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3657                 error "open unlink test2 failed"
3658
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3660                 error "test1 still exists"
3661         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3662                 error "test2 still exists"
3663 }
3664 run_test 31p "remove of open striped directory"
3665
3666 test_31q() {
3667         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3668
3669         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3670         index=$($LFS getdirstripe -i $DIR/$tdir)
3671         [ $index -eq 3 ] || error "first stripe index $index != 3"
3672         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3673         [ $index -eq 1 ] || error "second stripe index $index != 1"
3674
3675         # when "-c <stripe_count>" is set, the number of MDTs specified after
3676         # "-i" should equal to the stripe count
3677         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3678 }
3679 run_test 31q "create striped directory on specific MDTs"
3680
3681 cleanup_test32_mount() {
3682         local rc=0
3683         trap 0
3684         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3685         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3686         losetup -d $loopdev || true
3687         rm -rf $DIR/$tdir
3688         return $rc
3689 }
3690
3691 test_32a() {
3692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3693
3694         echo "== more mountpoints and symlinks ================="
3695         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3696         trap cleanup_test32_mount EXIT
3697         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3698         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3699                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3700         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3701                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3702         cleanup_test32_mount
3703 }
3704 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3705
3706 test_32b() {
3707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3708
3709         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3710         trap cleanup_test32_mount EXIT
3711         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3712         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3713                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3714         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3715                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3716         cleanup_test32_mount
3717 }
3718 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3719
3720 test_32c() {
3721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3722
3723         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3724         trap cleanup_test32_mount EXIT
3725         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3726         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3727                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3728         test_mkdir -p $DIR/$tdir/d2/test_dir
3729         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3730                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3731         cleanup_test32_mount
3732 }
3733 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3734
3735 test_32d() {
3736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3737
3738         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3739         trap cleanup_test32_mount EXIT
3740         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3741         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3742                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3743         test_mkdir -p $DIR/$tdir/d2/test_dir
3744         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3745                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3746         cleanup_test32_mount
3747 }
3748 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3749
3750 test_32e() {
3751         rm -fr $DIR/$tdir
3752         test_mkdir -p $DIR/$tdir/tmp
3753         local tmp_dir=$DIR/$tdir/tmp
3754         ln -s $DIR/$tdir $tmp_dir/symlink11
3755         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3756         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3757         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3758 }
3759 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3760
3761 test_32f() {
3762         rm -fr $DIR/$tdir
3763         test_mkdir -p $DIR/$tdir/tmp
3764         local tmp_dir=$DIR/$tdir/tmp
3765         ln -s $DIR/$tdir $tmp_dir/symlink11
3766         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3767         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3768         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3769 }
3770 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3771
3772 test_32g() {
3773         local tmp_dir=$DIR/$tdir/tmp
3774         test_mkdir -p $tmp_dir
3775         test_mkdir $DIR/${tdir}2
3776         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3777         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3778         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3779         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3780         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3781         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3782 }
3783 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3784
3785 test_32h() {
3786         rm -fr $DIR/$tdir $DIR/${tdir}2
3787         tmp_dir=$DIR/$tdir/tmp
3788         test_mkdir -p $tmp_dir
3789         test_mkdir $DIR/${tdir}2
3790         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3791         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3792         ls $tmp_dir/symlink12 || error "listing symlink12"
3793         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3794 }
3795 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3796
3797 test_32i() {
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3801         trap cleanup_test32_mount EXIT
3802         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3803         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3804                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3805         touch $DIR/$tdir/test_file
3806         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3807                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3808         cleanup_test32_mount
3809 }
3810 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3811
3812 test_32j() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3816         trap cleanup_test32_mount EXIT
3817         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3818         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3819                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3820         touch $DIR/$tdir/test_file
3821         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3822                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3823         cleanup_test32_mount
3824 }
3825 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3826
3827 test_32k() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         test_mkdir -p $DIR/$tdir/d2
3836         touch $DIR/$tdir/d2/test_file || error "touch failed"
3837         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3838                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3839         cleanup_test32_mount
3840 }
3841 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3842
3843 test_32l() {
3844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3845
3846         rm -fr $DIR/$tdir
3847         trap cleanup_test32_mount EXIT
3848         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3849         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3850                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3851         test_mkdir -p $DIR/$tdir/d2
3852         touch $DIR/$tdir/d2/test_file || error "touch failed"
3853         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3854                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3855         cleanup_test32_mount
3856 }
3857 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3858
3859 test_32m() {
3860         rm -fr $DIR/d32m
3861         test_mkdir -p $DIR/d32m/tmp
3862         TMP_DIR=$DIR/d32m/tmp
3863         ln -s $DIR $TMP_DIR/symlink11
3864         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3865         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3866                 error "symlink11 not a link"
3867         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3868                 error "symlink01 not a link"
3869 }
3870 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3871
3872 test_32n() {
3873         rm -fr $DIR/d32n
3874         test_mkdir -p $DIR/d32n/tmp
3875         TMP_DIR=$DIR/d32n/tmp
3876         ln -s $DIR $TMP_DIR/symlink11
3877         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3878         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3879         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3880 }
3881 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3882
3883 test_32o() {
3884         touch $DIR/$tfile
3885         test_mkdir -p $DIR/d32o/tmp
3886         TMP_DIR=$DIR/d32o/tmp
3887         ln -s $DIR/$tfile $TMP_DIR/symlink12
3888         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3889         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3890                 error "symlink12 not a link"
3891         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3892         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3893                 error "$DIR/d32o/tmp/symlink12 not file type"
3894         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3895                 error "$DIR/d32o/symlink02 not file type"
3896 }
3897 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3898
3899 test_32p() {
3900         log 32p_1
3901         rm -fr $DIR/d32p
3902         log 32p_2
3903         rm -f $DIR/$tfile
3904         log 32p_3
3905         touch $DIR/$tfile
3906         log 32p_4
3907         test_mkdir -p $DIR/d32p/tmp
3908         log 32p_5
3909         TMP_DIR=$DIR/d32p/tmp
3910         log 32p_6
3911         ln -s $DIR/$tfile $TMP_DIR/symlink12
3912         log 32p_7
3913         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3914         log 32p_8
3915         cat $DIR/d32p/tmp/symlink12 ||
3916                 error "Can't open $DIR/d32p/tmp/symlink12"
3917         log 32p_9
3918         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3919         log 32p_10
3920 }
3921 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3922
3923 test_32q() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3927         trap cleanup_test32_mount EXIT
3928         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3929         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3933         cleanup_test32_mount
3934 }
3935 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3936
3937 test_32r() {
3938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3939
3940         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3941         trap cleanup_test32_mount EXIT
3942         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3943         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3947         cleanup_test32_mount
3948 }
3949 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3950
3951 test_33aa() {
3952         rm -f $DIR/$tfile
3953         touch $DIR/$tfile
3954         chmod 444 $DIR/$tfile
3955         chown $RUNAS_ID $DIR/$tfile
3956         log 33_1
3957         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3958         log 33_2
3959 }
3960 run_test 33aa "write file with mode 444 (should return error)"
3961
3962 test_33a() {
3963         rm -fr $DIR/$tdir
3964         test_mkdir $DIR/$tdir
3965         chown $RUNAS_ID $DIR/$tdir
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3967                 error "$RUNAS create $tdir/$tfile failed"
3968         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3969                 error "open RDWR" || true
3970 }
3971 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3972
3973 test_33b() {
3974         rm -fr $DIR/$tdir
3975         test_mkdir $DIR/$tdir
3976         chown $RUNAS_ID $DIR/$tdir
3977         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3978 }
3979 run_test 33b "test open file with malformed flags (No panic)"
3980
3981 test_33c() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983         remote_ost_nodsh && skip "remote OST with nodsh"
3984
3985         local ostnum
3986         local ostname
3987         local write_bytes
3988         local all_zeros
3989
3990         all_zeros=true
3991         test_mkdir $DIR/$tdir
3992         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3993
3994         sync
3995         for ostnum in $(seq $OSTCOUNT); do
3996                 # test-framework's OST numbering is one-based, while Lustre's
3997                 # is zero-based
3998                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3999                 # check if at least some write_bytes stats are counted
4000                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4001                               obdfilter.$ostname.stats |
4002                               awk '/^write_bytes/ {print $7}' )
4003                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4004                 if (( ${write_bytes:-0} > 0 )); then
4005                         all_zeros=false
4006                         break
4007                 fi
4008         done
4009
4010         $all_zeros || return 0
4011
4012         # Write four bytes
4013         echo foo > $DIR/$tdir/bar
4014         # Really write them
4015         sync
4016
4017         # Total up write_bytes after writing.  We'd better find non-zeros.
4018         for ostnum in $(seq $OSTCOUNT); do
4019                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4020                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4021                               obdfilter/$ostname/stats |
4022                               awk '/^write_bytes/ {print $7}' )
4023                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4024                 if (( ${write_bytes:-0} > 0 )); then
4025                         all_zeros=false
4026                         break
4027                 fi
4028         done
4029
4030         if $all_zeros; then
4031                 for ostnum in $(seq $OSTCOUNT); do
4032                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4033                         echo "Check write_bytes is in obdfilter.*.stats:"
4034                         do_facet ost$ostnum lctl get_param -n \
4035                                 obdfilter.$ostname.stats
4036                 done
4037                 error "OST not keeping write_bytes stats (b=22312)"
4038         fi
4039 }
4040 run_test 33c "test write_bytes stats"
4041
4042 test_33d() {
4043         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4045
4046         local MDTIDX=1
4047         local remote_dir=$DIR/$tdir/remote_dir
4048
4049         test_mkdir $DIR/$tdir
4050         $LFS mkdir -i $MDTIDX $remote_dir ||
4051                 error "create remote directory failed"
4052
4053         touch $remote_dir/$tfile
4054         chmod 444 $remote_dir/$tfile
4055         chown $RUNAS_ID $remote_dir/$tfile
4056
4057         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4058
4059         chown $RUNAS_ID $remote_dir
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4061                                         error "create" || true
4062         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4063                                     error "open RDWR" || true
4064         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4065 }
4066 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4067
4068 test_33e() {
4069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4070
4071         mkdir $DIR/$tdir
4072
4073         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4074         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4075         mkdir $DIR/$tdir/local_dir
4076
4077         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4078         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4079         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4080
4081         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4082                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4083
4084         rmdir $DIR/$tdir/* || error "rmdir failed"
4085
4086         umask 777
4087         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4088         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4089         mkdir $DIR/$tdir/local_dir
4090
4091         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4092         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4093         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4094
4095         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4096                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4097
4098         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4099
4100         umask 000
4101         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4102         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4103         mkdir $DIR/$tdir/local_dir
4104
4105         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4106         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4107         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4108
4109         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4110                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4111 }
4112 run_test 33e "mkdir and striped directory should have same mode"
4113
4114 cleanup_33f() {
4115         trap 0
4116         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4117 }
4118
4119 test_33f() {
4120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4121         remote_mds_nodsh && skip "remote MDS with nodsh"
4122
4123         mkdir $DIR/$tdir
4124         chmod go+rwx $DIR/$tdir
4125         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4126         trap cleanup_33f EXIT
4127
4128         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4129                 error "cannot create striped directory"
4130
4131         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4132                 error "cannot create files in striped directory"
4133
4134         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4135                 error "cannot remove files in striped directory"
4136
4137         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4138                 error "cannot remove striped directory"
4139
4140         cleanup_33f
4141 }
4142 run_test 33f "nonroot user can create, access, and remove a striped directory"
4143
4144 test_33g() {
4145         mkdir -p $DIR/$tdir/dir2
4146
4147         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4148         echo $err
4149         [[ $err =~ "exists" ]] || error "Not exists error"
4150 }
4151 run_test 33g "nonroot user create already existing root created file"
4152
4153 test_33h() {
4154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4155         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4156                 skip "Need MDS version at least 2.13.50"
4157
4158         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4159                 error "mkdir $tdir failed"
4160         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4161
4162         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4163         local index2
4164
4165         for fname in $DIR/$tdir/$tfile.bak \
4166                      $DIR/$tdir/$tfile.SAV \
4167                      $DIR/$tdir/$tfile.orig \
4168                      $DIR/$tdir/$tfile~; do
4169                 touch $fname  || error "touch $fname failed"
4170                 index2=$($LFS getstripe -m $fname)
4171                 [ $index -eq $index2 ] ||
4172                         error "$fname MDT index mismatch $index != $index2"
4173         done
4174
4175         local failed=0
4176         for i in {1..250}; do
4177                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4178                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4179                         touch $fname  || error "touch $fname failed"
4180                         index2=$($LFS getstripe -m $fname)
4181                         if [[ $index != $index2 ]]; then
4182                                 failed=$((failed + 1))
4183                                 echo "$fname MDT index mismatch $index != $index2"
4184                         fi
4185                 done
4186         done
4187         echo "$failed MDT index mismatches"
4188         (( failed < 20 )) || error "MDT index mismatch $failed times"
4189
4190 }
4191 run_test 33h "temp file is located on the same MDT as target"
4192
4193 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4194 test_34a() {
4195         rm -f $DIR/f34
4196         $MCREATE $DIR/f34 || error "mcreate failed"
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4198                 error "getstripe failed"
4199         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4200         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4201                 error "getstripe failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204 }
4205 run_test 34a "truncate file that has not been opened ==========="
4206
4207 test_34b() {
4208         [ ! -f $DIR/f34 ] && test_34a
4209         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4210                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4211         $OPENFILE -f O_RDONLY $DIR/f34
4212         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4213                 error "getstripe failed"
4214         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4215                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4216 }
4217 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4218
4219 test_34c() {
4220         [ ! -f $DIR/f34 ] && test_34a
4221         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4222                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4223         $OPENFILE -f O_RDWR $DIR/f34
4224         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4225                 error "$LFS getstripe failed"
4226         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4227                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4228 }
4229 run_test 34c "O_RDWR opening file-with-size works =============="
4230
4231 test_34d() {
4232         [ ! -f $DIR/f34 ] && test_34a
4233         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4234                 error "dd failed"
4235         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4236                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4237         rm $DIR/f34
4238 }
4239 run_test 34d "write to sparse file ============================="
4240
4241 test_34e() {
4242         rm -f $DIR/f34e
4243         $MCREATE $DIR/f34e || error "mcreate failed"
4244         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4245         $CHECKSTAT -s 1000 $DIR/f34e ||
4246                 error "Size of $DIR/f34e not equal to 1000 bytes"
4247         $OPENFILE -f O_RDWR $DIR/f34e
4248         $CHECKSTAT -s 1000 $DIR/f34e ||
4249                 error "Size of $DIR/f34e not equal to 1000 bytes"
4250 }
4251 run_test 34e "create objects, some with size and some without =="
4252
4253 test_34f() { # bug 6242, 6243
4254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4255
4256         SIZE34F=48000
4257         rm -f $DIR/f34f
4258         $MCREATE $DIR/f34f || error "mcreate failed"
4259         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4260         dd if=$DIR/f34f of=$TMP/f34f
4261         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4262         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4263         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4264         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4265         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4266 }
4267 run_test 34f "read from a file with no objects until EOF ======="
4268
4269 test_34g() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4273                 error "dd failed"
4274         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4275         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4276                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4277         cancel_lru_locks osc
4278         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4279                 error "wrong size after lock cancel"
4280
4281         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4282         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4283                 error "expanding truncate failed"
4284         cancel_lru_locks osc
4285         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4286                 error "wrong expanded size after lock cancel"
4287 }
4288 run_test 34g "truncate long file ==============================="
4289
4290 test_34h() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         local gid=10
4294         local sz=1000
4295
4296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4297         sync # Flush the cache so that multiop below does not block on cache
4298              # flush when getting the group lock
4299         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4300         MULTIPID=$!
4301
4302         # Since just timed wait is not good enough, let's do a sync write
4303         # that way we are sure enough time for a roundtrip + processing
4304         # passed + 2 seconds of extra margin.
4305         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4306         rm $DIR/${tfile}-1
4307         sleep 2
4308
4309         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4310                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4311                 kill -9 $MULTIPID
4312         fi
4313         wait $MULTIPID
4314         local nsz=`stat -c %s $DIR/$tfile`
4315         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4316 }
4317 run_test 34h "ftruncate file under grouplock should not block"
4318
4319 test_35a() {
4320         cp /bin/sh $DIR/f35a
4321         chmod 444 $DIR/f35a
4322         chown $RUNAS_ID $DIR/f35a
4323         $RUNAS $DIR/f35a && error || true
4324         rm $DIR/f35a
4325 }
4326 run_test 35a "exec file with mode 444 (should return and not leak)"
4327
4328 test_36a() {
4329         rm -f $DIR/f36
4330         utime $DIR/f36 || error "utime failed for MDS"
4331 }
4332 run_test 36a "MDS utime check (mknod, utime)"
4333
4334 test_36b() {
4335         echo "" > $DIR/f36
4336         utime $DIR/f36 || error "utime failed for OST"
4337 }
4338 run_test 36b "OST utime check (open, utime)"
4339
4340 test_36c() {
4341         rm -f $DIR/d36/f36
4342         test_mkdir $DIR/d36
4343         chown $RUNAS_ID $DIR/d36
4344         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4345 }
4346 run_test 36c "non-root MDS utime check (mknod, utime)"
4347
4348 test_36d() {
4349         [ ! -d $DIR/d36 ] && test_36c
4350         echo "" > $DIR/d36/f36
4351         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4352 }
4353 run_test 36d "non-root OST utime check (open, utime)"
4354
4355 test_36e() {
4356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4357
4358         test_mkdir $DIR/$tdir
4359         touch $DIR/$tdir/$tfile
4360         $RUNAS utime $DIR/$tdir/$tfile &&
4361                 error "utime worked, expected failure" || true
4362 }
4363 run_test 36e "utime on non-owned file (should return error)"
4364
4365 subr_36fh() {
4366         local fl="$1"
4367         local LANG_SAVE=$LANG
4368         local LC_LANG_SAVE=$LC_LANG
4369         export LANG=C LC_LANG=C # for date language
4370
4371         DATESTR="Dec 20  2000"
4372         test_mkdir $DIR/$tdir
4373         lctl set_param fail_loc=$fl
4374         date; date +%s
4375         cp /etc/hosts $DIR/$tdir/$tfile
4376         sync & # write RPC generated with "current" inode timestamp, but delayed
4377         sleep 1
4378         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4379         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4380         cancel_lru_locks $OSC
4381         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4382         date; date +%s
4383         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4384                 echo "BEFORE: $LS_BEFORE" && \
4385                 echo "AFTER : $LS_AFTER" && \
4386                 echo "WANT  : $DATESTR" && \
4387                 error "$DIR/$tdir/$tfile timestamps changed" || true
4388
4389         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4390 }
4391
4392 test_36f() {
4393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4394
4395         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4396         subr_36fh "0x80000214"
4397 }
4398 run_test 36f "utime on file racing with OST BRW write =========="
4399
4400 test_36g() {
4401         remote_ost_nodsh && skip "remote OST with nodsh"
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4404                 skip "Need MDS version at least 2.12.51"
4405
4406         local fmd_max_age
4407         local fmd
4408         local facet="ost1"
4409         local tgt="obdfilter"
4410
4411         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4412
4413         test_mkdir $DIR/$tdir
4414         fmd_max_age=$(do_facet $facet \
4415                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4416                 head -n 1")
4417
4418         echo "FMD max age: ${fmd_max_age}s"
4419         touch $DIR/$tdir/$tfile
4420         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4421                 gawk '{cnt=cnt+$1}  END{print cnt}')
4422         echo "FMD before: $fmd"
4423         [[ $fmd == 0 ]] &&
4424                 error "FMD wasn't create by touch"
4425         sleep $((fmd_max_age + 12))
4426         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4427                 gawk '{cnt=cnt+$1}  END{print cnt}')
4428         echo "FMD after: $fmd"
4429         [[ $fmd == 0 ]] ||
4430                 error "FMD wasn't expired by ping"
4431 }
4432 run_test 36g "FMD cache expiry ====================="
4433
4434 test_36h() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4438         subr_36fh "0x80000227"
4439 }
4440 run_test 36h "utime on file racing with OST BRW write =========="
4441
4442 test_36i() {
4443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4444
4445         test_mkdir $DIR/$tdir
4446         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4447
4448         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4449         local new_mtime=$((mtime + 200))
4450
4451         #change Modify time of striped dir
4452         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4453                         error "change mtime failed"
4454
4455         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4456
4457         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4458 }
4459 run_test 36i "change mtime on striped directory"
4460
4461 # test_37 - duplicate with tests 32q 32r
4462
4463 test_38() {
4464         local file=$DIR/$tfile
4465         touch $file
4466         openfile -f O_DIRECTORY $file
4467         local RC=$?
4468         local ENOTDIR=20
4469         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4470         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4471 }
4472 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4473
4474 test_39a() { # was test_39
4475         touch $DIR/$tfile
4476         touch $DIR/${tfile}2
4477 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4479 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4480         sleep 2
4481         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4482         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4483                 echo "mtime"
4484                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "atime"
4486                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4487                 echo "ctime"
4488                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4489                 error "O_TRUNC didn't change timestamps"
4490         fi
4491 }
4492 run_test 39a "mtime changed on create"
4493
4494 test_39b() {
4495         test_mkdir -c1 $DIR/$tdir
4496         cp -p /etc/passwd $DIR/$tdir/fopen
4497         cp -p /etc/passwd $DIR/$tdir/flink
4498         cp -p /etc/passwd $DIR/$tdir/funlink
4499         cp -p /etc/passwd $DIR/$tdir/frename
4500         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4501
4502         sleep 1
4503         echo "aaaaaa" >> $DIR/$tdir/fopen
4504         echo "aaaaaa" >> $DIR/$tdir/flink
4505         echo "aaaaaa" >> $DIR/$tdir/funlink
4506         echo "aaaaaa" >> $DIR/$tdir/frename
4507
4508         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4509         local link_new=`stat -c %Y $DIR/$tdir/flink`
4510         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4511         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4512
4513         cat $DIR/$tdir/fopen > /dev/null
4514         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4515         rm -f $DIR/$tdir/funlink2
4516         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4517
4518         for (( i=0; i < 2; i++ )) ; do
4519                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4520                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4521                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4522                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4523
4524                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4525                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4526                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4527                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4528
4529                 cancel_lru_locks $OSC
4530                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4531         done
4532 }
4533 run_test 39b "mtime change on open, link, unlink, rename  ======"
4534
4535 # this should be set to past
4536 TEST_39_MTIME=`date -d "1 year ago" +%s`
4537
4538 # bug 11063
4539 test_39c() {
4540         touch $DIR1/$tfile
4541         sleep 2
4542         local mtime0=`stat -c %Y $DIR1/$tfile`
4543
4544         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4545         local mtime1=`stat -c %Y $DIR1/$tfile`
4546         [ "$mtime1" = $TEST_39_MTIME ] || \
4547                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4548
4549         local d1=`date +%s`
4550         echo hello >> $DIR1/$tfile
4551         local d2=`date +%s`
4552         local mtime2=`stat -c %Y $DIR1/$tfile`
4553         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4554                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4555
4556         mv $DIR1/$tfile $DIR1/$tfile-1
4557
4558         for (( i=0; i < 2; i++ )) ; do
4559                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4560                 [ "$mtime2" = "$mtime3" ] || \
4561                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4562
4563                 cancel_lru_locks $OSC
4564                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4565         done
4566 }
4567 run_test 39c "mtime change on rename ==========================="
4568
4569 # bug 21114
4570 test_39d() {
4571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4572
4573         touch $DIR1/$tfile
4574         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4575
4576         for (( i=0; i < 2; i++ )) ; do
4577                 local mtime=`stat -c %Y $DIR1/$tfile`
4578                 [ $mtime = $TEST_39_MTIME ] || \
4579                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4580
4581                 cancel_lru_locks $OSC
4582                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4583         done
4584 }
4585 run_test 39d "create, utime, stat =============================="
4586
4587 # bug 21114
4588 test_39e() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         touch $DIR1/$tfile
4592         local mtime1=`stat -c %Y $DIR1/$tfile`
4593
4594         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4595
4596         for (( i=0; i < 2; i++ )) ; do
4597                 local mtime2=`stat -c %Y $DIR1/$tfile`
4598                 [ $mtime2 = $TEST_39_MTIME ] || \
4599                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4600
4601                 cancel_lru_locks $OSC
4602                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4603         done
4604 }
4605 run_test 39e "create, stat, utime, stat ========================"
4606
4607 # bug 21114
4608 test_39f() {
4609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4610
4611         touch $DIR1/$tfile
4612         mtime1=`stat -c %Y $DIR1/$tfile`
4613
4614         sleep 2
4615         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4616
4617         for (( i=0; i < 2; i++ )) ; do
4618                 local mtime2=`stat -c %Y $DIR1/$tfile`
4619                 [ $mtime2 = $TEST_39_MTIME ] || \
4620                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4621
4622                 cancel_lru_locks $OSC
4623                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4624         done
4625 }
4626 run_test 39f "create, stat, sleep, utime, stat ================="
4627
4628 # bug 11063
4629 test_39g() {
4630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4631
4632         echo hello >> $DIR1/$tfile
4633         local mtime1=`stat -c %Y $DIR1/$tfile`
4634
4635         sleep 2
4636         chmod o+r $DIR1/$tfile
4637
4638         for (( i=0; i < 2; i++ )) ; do
4639                 local mtime2=`stat -c %Y $DIR1/$tfile`
4640                 [ "$mtime1" = "$mtime2" ] || \
4641                         error "lost mtime: $mtime2, should be $mtime1"
4642
4643                 cancel_lru_locks $OSC
4644                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645         done
4646 }
4647 run_test 39g "write, chmod, stat ==============================="
4648
4649 # bug 11063
4650 test_39h() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         local d1=`date`
4657         echo hello >> $DIR1/$tfile
4658         local mtime1=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local d2=`date`
4662         if [ "$d1" != "$d2" ]; then
4663                 echo "write and touch not within one second"
4664         else
4665                 for (( i=0; i < 2; i++ )) ; do
4666                         local mtime2=`stat -c %Y $DIR1/$tfile`
4667                         [ "$mtime2" = $TEST_39_MTIME ] || \
4668                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4669
4670                         cancel_lru_locks $OSC
4671                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4672                 done
4673         fi
4674 }
4675 run_test 39h "write, utime within one second, stat ============="
4676
4677 test_39i() {
4678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4679
4680         touch $DIR1/$tfile
4681         sleep 1
4682
4683         echo hello >> $DIR1/$tfile
4684         local mtime1=`stat -c %Y $DIR1/$tfile`
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4690
4691                 [ "$mtime1" = "$mtime2" ] || \
4692                         error "lost mtime: $mtime2, should be $mtime1"
4693
4694                 cancel_lru_locks $OSC
4695                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4696         done
4697 }
4698 run_test 39i "write, rename, stat =============================="
4699
4700 test_39j() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         start_full_debug_logging
4704         touch $DIR1/$tfile
4705         sleep 1
4706
4707         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4708         lctl set_param fail_loc=0x80000412
4709         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4710                 error "multiop failed"
4711         local multipid=$!
4712         local mtime1=`stat -c %Y $DIR1/$tfile`
4713
4714         mv $DIR1/$tfile $DIR1/$tfile-1
4715
4716         kill -USR1 $multipid
4717         wait $multipid || error "multiop close failed"
4718
4719         for (( i=0; i < 2; i++ )) ; do
4720                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4721                 [ "$mtime1" = "$mtime2" ] ||
4722                         error "mtime is lost on close: $mtime2, " \
4723                               "should be $mtime1"
4724
4725                 cancel_lru_locks
4726                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4727         done
4728         lctl set_param fail_loc=0
4729         stop_full_debug_logging
4730 }
4731 run_test 39j "write, rename, close, stat ======================="
4732
4733 test_39k() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         touch $DIR1/$tfile
4737         sleep 1
4738
4739         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4740         local multipid=$!
4741         local mtime1=`stat -c %Y $DIR1/$tfile`
4742
4743         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4744
4745         kill -USR1 $multipid
4746         wait $multipid || error "multiop close failed"
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local mtime2=`stat -c %Y $DIR1/$tfile`
4750
4751                 [ "$mtime2" = $TEST_39_MTIME ] || \
4752                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4753
4754                 cancel_lru_locks
4755                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4756         done
4757 }
4758 run_test 39k "write, utime, close, stat ========================"
4759
4760 # this should be set to future
4761 TEST_39_ATIME=`date -d "1 year" +%s`
4762
4763 test_39l() {
4764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4765         remote_mds_nodsh && skip "remote MDS with nodsh"
4766
4767         local atime_diff=$(do_facet $SINGLEMDS \
4768                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4769         rm -rf $DIR/$tdir
4770         mkdir_on_mdt0 $DIR/$tdir
4771
4772         # test setting directory atime to future
4773         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4774         local atime=$(stat -c %X $DIR/$tdir)
4775         [ "$atime" = $TEST_39_ATIME ] ||
4776                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4777
4778         # test setting directory atime from future to now
4779         local now=$(date +%s)
4780         touch -a -d @$now $DIR/$tdir
4781
4782         atime=$(stat -c %X $DIR/$tdir)
4783         [ "$atime" -eq "$now"  ] ||
4784                 error "atime is not updated from future: $atime, $now"
4785
4786         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4787         sleep 3
4788
4789         # test setting directory atime when now > dir atime + atime_diff
4790         local d1=$(date +%s)
4791         ls $DIR/$tdir
4792         local d2=$(date +%s)
4793         cancel_lru_locks mdc
4794         atime=$(stat -c %X $DIR/$tdir)
4795         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4796                 error "atime is not updated  : $atime, should be $d2"
4797
4798         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4799         sleep 3
4800
4801         # test not setting directory atime when now < dir atime + atime_diff
4802         ls $DIR/$tdir
4803         cancel_lru_locks mdc
4804         atime=$(stat -c %X $DIR/$tdir)
4805         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4806                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4807
4808         do_facet $SINGLEMDS \
4809                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4810 }
4811 run_test 39l "directory atime update ==========================="
4812
4813 test_39m() {
4814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4815
4816         touch $DIR1/$tfile
4817         sleep 2
4818         local far_past_mtime=$(date -d "May 29 1953" +%s)
4819         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4820
4821         touch -m -d @$far_past_mtime $DIR1/$tfile
4822         touch -a -d @$far_past_atime $DIR1/$tfile
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4826                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4827                         error "atime or mtime set incorrectly"
4828
4829                 cancel_lru_locks $OSC
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832 }
4833 run_test 39m "test atime and mtime before 1970"
4834
4835 test_39n() { # LU-3832
4836         remote_mds_nodsh && skip "remote MDS with nodsh"
4837
4838         local atime_diff=$(do_facet $SINGLEMDS \
4839                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4840         local atime0
4841         local atime1
4842         local atime2
4843
4844         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4845
4846         rm -rf $DIR/$tfile
4847         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4848         atime0=$(stat -c %X $DIR/$tfile)
4849
4850         sleep 5
4851         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4852         atime1=$(stat -c %X $DIR/$tfile)
4853
4854         sleep 5
4855         cancel_lru_locks mdc
4856         cancel_lru_locks osc
4857         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4858         atime2=$(stat -c %X $DIR/$tfile)
4859
4860         do_facet $SINGLEMDS \
4861                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4862
4863         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4864         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4865 }
4866 run_test 39n "check that O_NOATIME is honored"
4867
4868 test_39o() {
4869         TESTDIR=$DIR/$tdir/$tfile
4870         [ -e $TESTDIR ] && rm -rf $TESTDIR
4871         mkdir -p $TESTDIR
4872         cd $TESTDIR
4873         links1=2
4874         ls
4875         mkdir a b
4876         ls
4877         links2=$(stat -c %h .)
4878         [ $(($links1 + 2)) != $links2 ] &&
4879                 error "wrong links count $(($links1 + 2)) != $links2"
4880         rmdir b
4881         links3=$(stat -c %h .)
4882         [ $(($links1 + 1)) != $links3 ] &&
4883                 error "wrong links count $links1 != $links3"
4884         return 0
4885 }
4886 run_test 39o "directory cached attributes updated after create"
4887
4888 test_39p() {
4889         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4890
4891         local MDTIDX=1
4892         TESTDIR=$DIR/$tdir/$tdir
4893         [ -e $TESTDIR ] && rm -rf $TESTDIR
4894         test_mkdir -p $TESTDIR
4895         cd $TESTDIR
4896         links1=2
4897         ls
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4899         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4900         ls
4901         links2=$(stat -c %h .)
4902         [ $(($links1 + 2)) != $links2 ] &&
4903                 error "wrong links count $(($links1 + 2)) != $links2"
4904         rmdir remote_dir2
4905         links3=$(stat -c %h .)
4906         [ $(($links1 + 1)) != $links3 ] &&
4907                 error "wrong links count $links1 != $links3"
4908         return 0
4909 }
4910 run_test 39p "remote directory cached attributes updated after create ========"
4911
4912 test_39r() {
4913         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4914                 skip "no atime update on old OST"
4915         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4916                 skip_env "ldiskfs only test"
4917         fi
4918
4919         local saved_adiff
4920         saved_adiff=$(do_facet ost1 \
4921                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4922         stack_trap "do_facet ost1 \
4923                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4924
4925         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4926
4927         $LFS setstripe -i 0 $DIR/$tfile
4928         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4929                 error "can't write initial file"
4930         cancel_lru_locks osc
4931
4932         # exceed atime_diff and access file
4933         sleep 6
4934         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4935                 error "can't udpate atime"
4936
4937         local atime_cli=$(stat -c %X $DIR/$tfile)
4938         echo "client atime: $atime_cli"
4939         # allow atime update to be written to device
4940         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4941         sleep 5
4942
4943         local ostdev=$(ostdevname 1)
4944         local fid=($(lfs getstripe -y $DIR/$tfile |
4945                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4946         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4947         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4948
4949         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4950         local atime_ost=$(do_facet ost1 "$cmd" |&
4951                           awk -F'[: ]' '/atime:/ { print $4 }')
4952         (( atime_cli == atime_ost )) ||
4953                 error "atime on client $atime_cli != ost $atime_ost"
4954 }
4955 run_test 39r "lazy atime update on OST"
4956
4957 test_39q() { # LU-8041
4958         local testdir=$DIR/$tdir
4959         mkdir -p $testdir
4960         multiop_bg_pause $testdir D_c || error "multiop failed"
4961         local multipid=$!
4962         cancel_lru_locks mdc
4963         kill -USR1 $multipid
4964         local atime=$(stat -c %X $testdir)
4965         [ "$atime" -ne 0 ] || error "atime is zero"
4966 }
4967 run_test 39q "close won't zero out atime"
4968
4969 test_40() {
4970         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4971         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4972                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4973         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4974                 error "$tfile is not 4096 bytes in size"
4975 }
4976 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4977
4978 test_41() {
4979         # bug 1553
4980         small_write $DIR/f41 18
4981 }
4982 run_test 41 "test small file write + fstat ====================="
4983
4984 count_ost_writes() {
4985         lctl get_param -n ${OSC}.*.stats |
4986                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4987                         END { printf("%0.0f", writes) }'
4988 }
4989
4990 # decent default
4991 WRITEBACK_SAVE=500
4992 DIRTY_RATIO_SAVE=40
4993 MAX_DIRTY_RATIO=50
4994 BG_DIRTY_RATIO_SAVE=10
4995 MAX_BG_DIRTY_RATIO=25
4996
4997 start_writeback() {
4998         trap 0
4999         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5000         # dirty_ratio, dirty_background_ratio
5001         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5002                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5003                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5004                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5005         else
5006                 # if file not here, we are a 2.4 kernel
5007                 kill -CONT `pidof kupdated`
5008         fi
5009 }
5010
5011 stop_writeback() {
5012         # setup the trap first, so someone cannot exit the test at the
5013         # exact wrong time and mess up a machine
5014         trap start_writeback EXIT
5015         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5016         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5017                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 sysctl -w vm.dirty_writeback_centisecs=0
5020                 # save and increase /proc/sys/vm/dirty_ratio
5021                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5022                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5023                 # save and increase /proc/sys/vm/dirty_background_ratio
5024                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5025                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5026         else
5027                 # if file not here, we are a 2.4 kernel
5028                 kill -STOP `pidof kupdated`
5029         fi
5030 }
5031
5032 # ensure that all stripes have some grant before we test client-side cache
5033 setup_test42() {
5034         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5035                 dd if=/dev/zero of=$i bs=4k count=1
5036                 rm $i
5037         done
5038 }
5039
5040 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5041 # file truncation, and file removal.
5042 test_42a() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         setup_test42
5046         cancel_lru_locks $OSC
5047         stop_writeback
5048         sync; sleep 1; sync # just to be safe
5049         BEFOREWRITES=`count_ost_writes`
5050         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5051         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5052         AFTERWRITES=`count_ost_writes`
5053         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5054                 error "$BEFOREWRITES < $AFTERWRITES"
5055         start_writeback
5056 }
5057 run_test 42a "ensure that we don't flush on close"
5058
5059 test_42b() {
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         setup_test42
5063         cancel_lru_locks $OSC
5064         stop_writeback
5065         sync
5066         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5067         BEFOREWRITES=$(count_ost_writes)
5068         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5069         AFTERWRITES=$(count_ost_writes)
5070         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5071                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5072         fi
5073         BEFOREWRITES=$(count_ost_writes)
5074         sync || error "sync: $?"
5075         AFTERWRITES=$(count_ost_writes)
5076         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5077                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5078         fi
5079         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5080         start_writeback
5081         return 0
5082 }
5083 run_test 42b "test destroy of file with cached dirty data ======"
5084
5085 # if these tests just want to test the effect of truncation,
5086 # they have to be very careful.  consider:
5087 # - the first open gets a {0,EOF}PR lock
5088 # - the first write conflicts and gets a {0, count-1}PW
5089 # - the rest of the writes are under {count,EOF}PW
5090 # - the open for truncate tries to match a {0,EOF}PR
5091 #   for the filesize and cancels the PWs.
5092 # any number of fixes (don't get {0,EOF} on open, match
5093 # composite locks, do smarter file size management) fix
5094 # this, but for now we want these tests to verify that
5095 # the cancellation with truncate intent works, so we
5096 # start the file with a full-file pw lock to match against
5097 # until the truncate.
5098 trunc_test() {
5099         test=$1
5100         file=$DIR/$test
5101         offset=$2
5102         cancel_lru_locks $OSC
5103         stop_writeback
5104         # prime the file with 0,EOF PW to match
5105         touch $file
5106         $TRUNCATE $file 0
5107         sync; sync
5108         # now the real test..
5109         dd if=/dev/zero of=$file bs=1024 count=100
5110         BEFOREWRITES=`count_ost_writes`
5111         $TRUNCATE $file $offset
5112         cancel_lru_locks $OSC
5113         AFTERWRITES=`count_ost_writes`
5114         start_writeback
5115 }
5116
5117 test_42c() {
5118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5119
5120         trunc_test 42c 1024
5121         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5122                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5123         rm $file
5124 }
5125 run_test 42c "test partial truncate of file with cached dirty data"
5126
5127 test_42d() {
5128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5129
5130         trunc_test 42d 0
5131         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5132                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5133         rm $file
5134 }
5135 run_test 42d "test complete truncate of file with cached dirty data"
5136
5137 test_42e() { # bug22074
5138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5139
5140         local TDIR=$DIR/${tdir}e
5141         local pages=16 # hardcoded 16 pages, don't change it.
5142         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5143         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5144         local max_dirty_mb
5145         local warmup_files
5146
5147         test_mkdir $DIR/${tdir}e
5148         $LFS setstripe -c 1 $TDIR
5149         createmany -o $TDIR/f $files
5150
5151         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5152
5153         # we assume that with $OSTCOUNT files, at least one of them will
5154         # be allocated on OST0.
5155         warmup_files=$((OSTCOUNT * max_dirty_mb))
5156         createmany -o $TDIR/w $warmup_files
5157
5158         # write a large amount of data into one file and sync, to get good
5159         # avail_grant number from OST.
5160         for ((i=0; i<$warmup_files; i++)); do
5161                 idx=$($LFS getstripe -i $TDIR/w$i)
5162                 [ $idx -ne 0 ] && continue
5163                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5164                 break
5165         done
5166         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5167         sync
5168         $LCTL get_param $proc_osc0/cur_dirty_bytes
5169         $LCTL get_param $proc_osc0/cur_grant_bytes
5170
5171         # create as much dirty pages as we can while not to trigger the actual
5172         # RPCs directly. but depends on the env, VFS may trigger flush during this
5173         # period, hopefully we are good.
5174         for ((i=0; i<$warmup_files; i++)); do
5175                 idx=$($LFS getstripe -i $TDIR/w$i)
5176                 [ $idx -ne 0 ] && continue
5177                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5178         done
5179         $LCTL get_param $proc_osc0/cur_dirty_bytes
5180         $LCTL get_param $proc_osc0/cur_grant_bytes
5181
5182         # perform the real test
5183         $LCTL set_param $proc_osc0/rpc_stats 0
5184         for ((;i<$files; i++)); do
5185                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5186                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5187         done
5188         sync
5189         $LCTL get_param $proc_osc0/rpc_stats
5190
5191         local percent=0
5192         local have_ppr=false
5193         $LCTL get_param $proc_osc0/rpc_stats |
5194                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5195                         # skip lines until we are at the RPC histogram data
5196                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5197                         $have_ppr || continue
5198
5199                         # we only want the percent stat for < 16 pages
5200                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5201
5202                         percent=$((percent + WPCT))
5203                         if [[ $percent -gt 15 ]]; then
5204                                 error "less than 16-pages write RPCs" \
5205                                       "$percent% > 15%"
5206                                 break
5207                         fi
5208                 done
5209         rm -rf $TDIR
5210 }
5211 run_test 42e "verify sub-RPC writes are not done synchronously"
5212
5213 test_43A() { # was test_43
5214         test_mkdir $DIR/$tdir
5215         cp -p /bin/ls $DIR/$tdir/$tfile
5216         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5217         pid=$!
5218         # give multiop a chance to open
5219         sleep 1
5220
5221         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5222         kill -USR1 $pid
5223         # Wait for multiop to exit
5224         wait $pid
5225 }
5226 run_test 43A "execution of file opened for write should return -ETXTBSY"
5227
5228 test_43a() {
5229         test_mkdir $DIR/$tdir
5230         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5231         $DIR/$tdir/sleep 60 &
5232         SLEEP_PID=$!
5233         # Make sure exec of $tdir/sleep wins race with truncate
5234         sleep 1
5235         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5236         kill $SLEEP_PID
5237 }
5238 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5239
5240 test_43b() {
5241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5242
5243         test_mkdir $DIR/$tdir
5244         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5245         $DIR/$tdir/sleep 60 &
5246         SLEEP_PID=$!
5247         # Make sure exec of $tdir/sleep wins race with truncate
5248         sleep 1
5249         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5250         kill $SLEEP_PID
5251 }
5252 run_test 43b "truncate of file being executed should return -ETXTBSY"
5253
5254 test_43c() {
5255         local testdir="$DIR/$tdir"
5256         test_mkdir $testdir
5257         cp $SHELL $testdir/
5258         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5259                 ( cd $testdir && md5sum -c )
5260 }
5261 run_test 43c "md5sum of copy into lustre"
5262
5263 test_44A() { # was test_44
5264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5265
5266         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5267         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5268 }
5269 run_test 44A "zero length read from a sparse stripe"
5270
5271 test_44a() {
5272         local nstripe=$($LFS getstripe -c -d $DIR)
5273         [ -z "$nstripe" ] && skip "can't get stripe info"
5274         [[ $nstripe -gt $OSTCOUNT ]] &&
5275                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5276
5277         local stride=$($LFS getstripe -S -d $DIR)
5278         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5279                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5280         fi
5281
5282         OFFSETS="0 $((stride/2)) $((stride-1))"
5283         for offset in $OFFSETS; do
5284                 for i in $(seq 0 $((nstripe-1))); do
5285                         local GLOBALOFFSETS=""
5286                         # size in Bytes
5287                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5288                         local myfn=$DIR/d44a-$size
5289                         echo "--------writing $myfn at $size"
5290                         ll_sparseness_write $myfn $size ||
5291                                 error "ll_sparseness_write"
5292                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5293                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5294                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5295
5296                         for j in $(seq 0 $((nstripe-1))); do
5297                                 # size in Bytes
5298                                 size=$((((j + $nstripe )*$stride + $offset)))
5299                                 ll_sparseness_write $myfn $size ||
5300                                         error "ll_sparseness_write"
5301                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5302                         done
5303                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5304                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5305                         rm -f $myfn
5306                 done
5307         done
5308 }
5309 run_test 44a "test sparse pwrite ==============================="
5310
5311 dirty_osc_total() {
5312         tot=0
5313         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5314                 tot=$(($tot + $d))
5315         done
5316         echo $tot
5317 }
5318 do_dirty_record() {
5319         before=`dirty_osc_total`
5320         echo executing "\"$*\""
5321         eval $*
5322         after=`dirty_osc_total`
5323         echo before $before, after $after
5324 }
5325 test_45() {
5326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5327
5328         f="$DIR/f45"
5329         # Obtain grants from OST if it supports it
5330         echo blah > ${f}_grant
5331         stop_writeback
5332         sync
5333         do_dirty_record "echo blah > $f"
5334         [[ $before -eq $after ]] && error "write wasn't cached"
5335         do_dirty_record "> $f"
5336         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5337         do_dirty_record "echo blah > $f"
5338         [[ $before -eq $after ]] && error "write wasn't cached"
5339         do_dirty_record "sync"
5340         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5341         do_dirty_record "echo blah > $f"
5342         [[ $before -eq $after ]] && error "write wasn't cached"
5343         do_dirty_record "cancel_lru_locks osc"
5344         [[ $before -gt $after ]] ||
5345                 error "lock cancellation didn't lower dirty count"
5346         start_writeback
5347 }
5348 run_test 45 "osc io page accounting ============================"
5349
5350 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5351 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5352 # objects offset and an assert hit when an rpc was built with 1023's mapped
5353 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5354 test_46() {
5355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5356
5357         f="$DIR/f46"
5358         stop_writeback
5359         sync
5360         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5361         sync
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5363         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5364         sync
5365         start_writeback
5366 }
5367 run_test 46 "dirtying a previously written page ================"
5368
5369 # test_47 is removed "Device nodes check" is moved to test_28
5370
5371 test_48a() { # bug 2399
5372         [ "$mds1_FSTYPE" = "zfs" ] &&
5373         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5374                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5375
5376         test_mkdir $DIR/$tdir
5377         cd $DIR/$tdir
5378         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5379         test_mkdir $DIR/$tdir
5380         touch foo || error "'touch foo' failed after recreating cwd"
5381         test_mkdir bar
5382         touch .foo || error "'touch .foo' failed after recreating cwd"
5383         test_mkdir .bar
5384         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5385         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5386         cd . || error "'cd .' failed after recreating cwd"
5387         mkdir . && error "'mkdir .' worked after recreating cwd"
5388         rmdir . && error "'rmdir .' worked after recreating cwd"
5389         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5390         cd .. || error "'cd ..' failed after recreating cwd"
5391 }
5392 run_test 48a "Access renamed working dir (should return errors)="
5393
5394 test_48b() { # bug 2399
5395         rm -rf $DIR/$tdir
5396         test_mkdir $DIR/$tdir
5397         cd $DIR/$tdir
5398         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5399         touch foo && error "'touch foo' worked after removing cwd"
5400         mkdir foo && error "'mkdir foo' worked after removing cwd"
5401         touch .foo && error "'touch .foo' worked after removing cwd"
5402         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5403         ls . > /dev/null && error "'ls .' worked after removing cwd"
5404         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5405         mkdir . && error "'mkdir .' worked after removing cwd"
5406         rmdir . && error "'rmdir .' worked after removing cwd"
5407         ln -s . foo && error "'ln -s .' worked after removing cwd"
5408         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5409 }
5410 run_test 48b "Access removed working dir (should return errors)="
5411
5412 test_48c() { # bug 2350
5413         #lctl set_param debug=-1
5414         #set -vx
5415         rm -rf $DIR/$tdir
5416         test_mkdir -p $DIR/$tdir/dir
5417         cd $DIR/$tdir/dir
5418         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5419         $TRACE touch foo && error "touch foo worked after removing cwd"
5420         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5421         touch .foo && error "touch .foo worked after removing cwd"
5422         mkdir .foo && error "mkdir .foo worked after removing cwd"
5423         $TRACE ls . && error "'ls .' worked after removing cwd"
5424         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5425         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5426         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5427         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5428         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5429 }
5430 run_test 48c "Access removed working subdir (should return errors)"
5431
5432 test_48d() { # bug 2350
5433         #lctl set_param debug=-1
5434         #set -vx
5435         rm -rf $DIR/$tdir
5436         test_mkdir -p $DIR/$tdir/dir
5437         cd $DIR/$tdir/dir
5438         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5439         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5440         $TRACE touch foo && error "'touch foo' worked after removing parent"
5441         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5442         touch .foo && error "'touch .foo' worked after removing parent"
5443         mkdir .foo && error "mkdir .foo worked after removing parent"
5444         $TRACE ls . && error "'ls .' worked after removing parent"
5445         $TRACE ls .. && error "'ls ..' worked after removing parent"
5446         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5447         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5448         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5449         true
5450 }
5451 run_test 48d "Access removed parent subdir (should return errors)"
5452
5453 test_48e() { # bug 4134
5454         #lctl set_param debug=-1
5455         #set -vx
5456         rm -rf $DIR/$tdir
5457         test_mkdir -p $DIR/$tdir/dir
5458         cd $DIR/$tdir/dir
5459         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5460         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5461         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5462         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5463         # On a buggy kernel addition of "touch foo" after cd .. will
5464         # produce kernel oops in lookup_hash_it
5465         touch ../foo && error "'cd ..' worked after recreate parent"
5466         cd $DIR
5467         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5468 }
5469 run_test 48e "Access to recreated parent subdir (should return errors)"
5470
5471 test_48f() {
5472         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5473                 skip "need MDS >= 2.13.55"
5474         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5475         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5476                 skip "needs different host for mdt1 mdt2"
5477         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5478
5479         $LFS mkdir -i0 $DIR/$tdir
5480         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5481
5482         for d in sub1 sub2 sub3; do
5483                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5484                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5485                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5486         done
5487
5488         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5489 }
5490 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5491
5492 test_49() { # LU-1030
5493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5494         remote_ost_nodsh && skip "remote OST with nodsh"
5495
5496         # get ost1 size - $FSNAME-OST0000
5497         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5498                 awk '{ print $4 }')
5499         # write 800M at maximum
5500         [[ $ost1_size -lt 2 ]] && ost1_size=2
5501         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5502
5503         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5504         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5505         local dd_pid=$!
5506
5507         # change max_pages_per_rpc while writing the file
5508         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5509         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5510         # loop until dd process exits
5511         while ps ax -opid | grep -wq $dd_pid; do
5512                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5513                 sleep $((RANDOM % 5 + 1))
5514         done
5515         # restore original max_pages_per_rpc
5516         $LCTL set_param $osc1_mppc=$orig_mppc
5517         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5518 }
5519 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5520
5521 test_50() {
5522         # bug 1485
5523         test_mkdir $DIR/$tdir
5524         cd $DIR/$tdir
5525         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5526 }
5527 run_test 50 "special situations: /proc symlinks  ==============="
5528
5529 test_51a() {    # was test_51
5530         # bug 1516 - create an empty entry right after ".." then split dir
5531         test_mkdir -c1 $DIR/$tdir
5532         touch $DIR/$tdir/foo
5533         $MCREATE $DIR/$tdir/bar
5534         rm $DIR/$tdir/foo
5535         createmany -m $DIR/$tdir/longfile 201
5536         FNUM=202
5537         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5538                 $MCREATE $DIR/$tdir/longfile$FNUM
5539                 FNUM=$(($FNUM + 1))
5540                 echo -n "+"
5541         done
5542         echo
5543         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5544 }
5545 run_test 51a "special situations: split htree with empty entry =="
5546
5547 cleanup_print_lfs_df () {
5548         trap 0
5549         $LFS df
5550         $LFS df -i
5551 }
5552
5553 test_51b() {
5554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5555
5556         local dir=$DIR/$tdir
5557         local nrdirs=$((65536 + 100))
5558
5559         # cleanup the directory
5560         rm -fr $dir
5561
5562         test_mkdir -c1 $dir
5563
5564         $LFS df
5565         $LFS df -i
5566         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5567         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5568         [[ $numfree -lt $nrdirs ]] &&
5569                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5570
5571         # need to check free space for the directories as well
5572         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5573         numfree=$(( blkfree / $(fs_inode_ksize) ))
5574         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5575
5576         trap cleanup_print_lfs_df EXIT
5577
5578         # create files
5579         createmany -d $dir/d $nrdirs || {
5580                 unlinkmany $dir/d $nrdirs
5581                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5582         }
5583
5584         # really created :
5585         nrdirs=$(ls -U $dir | wc -l)
5586
5587         # unlink all but 100 subdirectories, then check it still works
5588         local left=100
5589         local delete=$((nrdirs - left))
5590
5591         $LFS df
5592         $LFS df -i
5593
5594         # for ldiskfs the nlink count should be 1, but this is OSD specific
5595         # and so this is listed for informational purposes only
5596         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5597         unlinkmany -d $dir/d $delete ||
5598                 error "unlink of first $delete subdirs failed"
5599
5600         echo "nlink between: $(stat -c %h $dir)"
5601         local found=$(ls -U $dir | wc -l)
5602         [ $found -ne $left ] &&
5603                 error "can't find subdirs: found only $found, expected $left"
5604
5605         unlinkmany -d $dir/d $delete $left ||
5606                 error "unlink of second $left subdirs failed"
5607         # regardless of whether the backing filesystem tracks nlink accurately
5608         # or not, the nlink count shouldn't be more than "." and ".." here
5609         local after=$(stat -c %h $dir)
5610         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5611                 echo "nlink after: $after"
5612
5613         cleanup_print_lfs_df
5614 }
5615 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5616
5617 test_51d() {
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5620
5621         test_mkdir $DIR/$tdir
5622         createmany -o $DIR/$tdir/t- 1000
5623         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5624         for N in $(seq 0 $((OSTCOUNT - 1))); do
5625                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5626                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5627                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5628                         '($1 == '$N') { objs += 1 } \
5629                         END { printf("%0.0f", objs) }')
5630                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5631         done
5632         unlinkmany $DIR/$tdir/t- 1000
5633
5634         NLAST=0
5635         for N in $(seq 1 $((OSTCOUNT - 1))); do
5636                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5637                         error "OST $N has less objects vs OST $NLAST" \
5638                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5639                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5640                         error "OST $N has less objects vs OST $NLAST" \
5641                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5642
5643                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5644                         error "OST $N has less #0 objects vs OST $NLAST" \
5645                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5646                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5647                         error "OST $N has less #0 objects vs OST $NLAST" \
5648                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5649                 NLAST=$N
5650         done
5651         rm -f $TMP/$tfile
5652 }
5653 run_test 51d "check object distribution"
5654
5655 test_51e() {
5656         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5657                 skip_env "ldiskfs only test"
5658         fi
5659
5660         test_mkdir -c1 $DIR/$tdir
5661         test_mkdir -c1 $DIR/$tdir/d0
5662
5663         touch $DIR/$tdir/d0/foo
5664         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5665                 error "file exceed 65000 nlink limit!"
5666         unlinkmany $DIR/$tdir/d0/f- 65001
5667         return 0
5668 }
5669 run_test 51e "check file nlink limit"
5670
5671 test_51f() {
5672         test_mkdir $DIR/$tdir
5673
5674         local max=100000
5675         local ulimit_old=$(ulimit -n)
5676         local spare=20 # number of spare fd's for scripts/libraries, etc.
5677         local mdt=$($LFS getstripe -m $DIR/$tdir)
5678         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5679
5680         echo "MDT$mdt numfree=$numfree, max=$max"
5681         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5682         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5683                 while ! ulimit -n $((numfree + spare)); do
5684                         numfree=$((numfree * 3 / 4))
5685                 done
5686                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5687         else
5688                 echo "left ulimit at $ulimit_old"
5689         fi
5690
5691         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5692                 unlinkmany $DIR/$tdir/f $numfree
5693                 error "create+open $numfree files in $DIR/$tdir failed"
5694         }
5695         ulimit -n $ulimit_old
5696
5697         # if createmany exits at 120s there will be fewer than $numfree files
5698         unlinkmany $DIR/$tdir/f $numfree || true
5699 }
5700 run_test 51f "check many open files limit"
5701
5702 test_52a() {
5703         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5704         test_mkdir $DIR/$tdir
5705         touch $DIR/$tdir/foo
5706         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5707         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5708         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5709         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5710         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5711                                         error "link worked"
5712         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5713         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5714         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5715                                                      error "lsattr"
5716         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5717         cp -r $DIR/$tdir $TMP/
5718         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5719 }
5720 run_test 52a "append-only flag test (should return errors)"
5721
5722 test_52b() {
5723         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5724         test_mkdir $DIR/$tdir
5725         touch $DIR/$tdir/foo
5726         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5727         cat test > $DIR/$tdir/foo && error "cat test worked"
5728         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5729         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5730         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5731                                         error "link worked"
5732         echo foo >> $DIR/$tdir/foo && error "echo worked"
5733         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5734         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5735         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5736         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5737                                                         error "lsattr"
5738         chattr -i $DIR/$tdir/foo || error "chattr failed"
5739
5740         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5741 }
5742 run_test 52b "immutable flag test (should return errors) ======="
5743
5744 test_53() {
5745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5746         remote_mds_nodsh && skip "remote MDS with nodsh"
5747         remote_ost_nodsh && skip "remote OST with nodsh"
5748
5749         local param
5750         local param_seq
5751         local ostname
5752         local mds_last
5753         local mds_last_seq
5754         local ost_last
5755         local ost_last_seq
5756         local ost_last_id
5757         local ostnum
5758         local node
5759         local found=false
5760         local support_last_seq=true
5761
5762         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5763                 support_last_seq=false
5764
5765         # only test MDT0000
5766         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5767         local value
5768         for value in $(do_facet $SINGLEMDS \
5769                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5770                 param=$(echo ${value[0]} | cut -d "=" -f1)
5771                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5772
5773                 if $support_last_seq; then
5774                         param_seq=$(echo $param |
5775                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5776                         mds_last_seq=$(do_facet $SINGLEMDS \
5777                                        $LCTL get_param -n $param_seq)
5778                 fi
5779                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5780
5781                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5782                 node=$(facet_active_host ost$((ostnum+1)))
5783                 param="obdfilter.$ostname.last_id"
5784                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5785                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5786                         ost_last_id=$ost_last
5787
5788                         if $support_last_seq; then
5789                                 ost_last_id=$(echo $ost_last |
5790                                               awk -F':' '{print $2}' |
5791                                               sed -e "s/^0x//g")
5792                                 ost_last_seq=$(echo $ost_last |
5793                                                awk -F':' '{print $1}')
5794                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5795                         fi
5796
5797                         if [[ $ost_last_id != $mds_last ]]; then
5798                                 error "$ost_last_id != $mds_last"
5799                         else
5800                                 found=true
5801                                 break
5802                         fi
5803                 done
5804         done
5805         $found || error "can not match last_seq/last_id for $mdtosc"
5806         return 0
5807 }
5808 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5809
5810 test_54a() {
5811         perl -MSocket -e ';' || skip "no Socket perl module installed"
5812
5813         $SOCKETSERVER $DIR/socket ||
5814                 error "$SOCKETSERVER $DIR/socket failed: $?"
5815         $SOCKETCLIENT $DIR/socket ||
5816                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5817         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5818 }
5819 run_test 54a "unix domain socket test =========================="
5820
5821 test_54b() {
5822         f="$DIR/f54b"
5823         mknod $f c 1 3
5824         chmod 0666 $f
5825         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5826 }
5827 run_test 54b "char device works in lustre ======================"
5828
5829 find_loop_dev() {
5830         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5831         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5832         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5833
5834         for i in $(seq 3 7); do
5835                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5836                 LOOPDEV=$LOOPBASE$i
5837                 LOOPNUM=$i
5838                 break
5839         done
5840 }
5841
5842 cleanup_54c() {
5843         local rc=0
5844         loopdev="$DIR/loop54c"
5845
5846         trap 0
5847         $UMOUNT $DIR/$tdir || rc=$?
5848         losetup -d $loopdev || true
5849         losetup -d $LOOPDEV || true
5850         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5851         return $rc
5852 }
5853
5854 test_54c() {
5855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5856
5857         loopdev="$DIR/loop54c"
5858
5859         find_loop_dev
5860         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5861         trap cleanup_54c EXIT
5862         mknod $loopdev b 7 $LOOPNUM
5863         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5864         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5865         losetup $loopdev $DIR/$tfile ||
5866                 error "can't set up $loopdev for $DIR/$tfile"
5867         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5868         test_mkdir $DIR/$tdir
5869         mount -t ext2 $loopdev $DIR/$tdir ||
5870                 error "error mounting $loopdev on $DIR/$tdir"
5871         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5872                 error "dd write"
5873         df $DIR/$tdir
5874         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5875                 error "dd read"
5876         cleanup_54c
5877 }
5878 run_test 54c "block device works in lustre ====================="
5879
5880 test_54d() {
5881         f="$DIR/f54d"
5882         string="aaaaaa"
5883         mknod $f p
5884         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5885 }
5886 run_test 54d "fifo device works in lustre ======================"
5887
5888 test_54e() {
5889         f="$DIR/f54e"
5890         string="aaaaaa"
5891         cp -aL /dev/console $f
5892         echo $string > $f || error "echo $string to $f failed"
5893 }
5894 run_test 54e "console/tty device works in lustre ======================"
5895
5896 test_56a() {
5897         local numfiles=3
5898         local numdirs=2
5899         local dir=$DIR/$tdir
5900
5901         rm -rf $dir
5902         test_mkdir -p $dir/dir
5903         for i in $(seq $numfiles); do
5904                 touch $dir/file$i
5905                 touch $dir/dir/file$i
5906         done
5907
5908         local numcomp=$($LFS getstripe --component-count $dir)
5909
5910         [[ $numcomp == 0 ]] && numcomp=1
5911
5912         # test lfs getstripe with --recursive
5913         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5914
5915         [[ $filenum -eq $((numfiles * 2)) ]] ||
5916                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5917         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5918         [[ $filenum -eq $numfiles ]] ||
5919                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5920         echo "$LFS getstripe showed obdidx or l_ost_idx"
5921
5922         # test lfs getstripe with file instead of dir
5923         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5924         [[ $filenum -eq 1 ]] ||
5925                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5926         echo "$LFS getstripe file1 passed"
5927
5928         #test lfs getstripe with --verbose
5929         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5930         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5931                 error "$LFS getstripe --verbose $dir: "\
5932                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5933         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5934                 error "$LFS getstripe $dir: showed lmm_magic"
5935
5936         #test lfs getstripe with -v prints lmm_fid
5937         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5938         local countfids=$((numdirs + numfiles * numcomp))
5939         [[ $filenum -eq $countfids ]] ||
5940                 error "$LFS getstripe -v $dir: "\
5941                       "got $filenum want $countfids lmm_fid"
5942         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5943                 error "$LFS getstripe $dir: showed lmm_fid by default"
5944         echo "$LFS getstripe --verbose passed"
5945
5946         #check for FID information
5947         local fid1=$($LFS getstripe --fid $dir/file1)
5948         local fid2=$($LFS getstripe --verbose $dir/file1 |
5949                      awk '/lmm_fid: / { print $2; exit; }')
5950         local fid3=$($LFS path2fid $dir/file1)
5951
5952         [ "$fid1" != "$fid2" ] &&
5953                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5954         [ "$fid1" != "$fid3" ] &&
5955                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5956         echo "$LFS getstripe --fid passed"
5957
5958         #test lfs getstripe with --obd
5959         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5960                 error "$LFS getstripe --obd wrong_uuid: should return error"
5961
5962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5963
5964         local ostidx=1
5965         local obduuid=$(ostuuid_from_index $ostidx)
5966         local found=$($LFS getstripe -r --obd $obduuid $dir |
5967                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5968
5969         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5970         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5971                 ((filenum--))
5972         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5973                 ((filenum--))
5974
5975         [[ $found -eq $filenum ]] ||
5976                 error "$LFS getstripe --obd: found $found expect $filenum"
5977         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5978                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5979                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5980                 error "$LFS getstripe --obd: should not show file on other obd"
5981         echo "$LFS getstripe --obd passed"
5982 }
5983 run_test 56a "check $LFS getstripe"
5984
5985 test_56b() {
5986         local dir=$DIR/$tdir
5987         local numdirs=3
5988
5989         test_mkdir $dir
5990         for i in $(seq $numdirs); do
5991                 test_mkdir $dir/dir$i
5992         done
5993
5994         # test lfs getdirstripe default mode is non-recursion, which is
5995         # different from lfs getstripe
5996         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5997
5998         [[ $dircnt -eq 1 ]] ||
5999                 error "$LFS getdirstripe: found $dircnt, not 1"
6000         dircnt=$($LFS getdirstripe --recursive $dir |
6001                 grep -c lmv_stripe_count)
6002         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6003                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6004 }
6005 run_test 56b "check $LFS getdirstripe"
6006
6007 test_56c() {
6008         remote_ost_nodsh && skip "remote OST with nodsh"
6009
6010         local ost_idx=0
6011         local ost_name=$(ostname_from_index $ost_idx)
6012         local old_status=$(ost_dev_status $ost_idx)
6013         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6014
6015         [[ -z "$old_status" ]] ||
6016                 skip_env "OST $ost_name is in $old_status status"
6017
6018         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6019         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6020                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6021         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6022                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6023                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6024         fi
6025
6026         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6027                 error "$LFS df -v showing inactive devices"
6028         sleep_maxage
6029
6030         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6031
6032         [[ "$new_status" =~ "D" ]] ||
6033                 error "$ost_name status is '$new_status', missing 'D'"
6034         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6035                 [[ "$new_status" =~ "N" ]] ||
6036                         error "$ost_name status is '$new_status', missing 'N'"
6037         fi
6038         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6039                 [[ "$new_status" =~ "f" ]] ||
6040                         error "$ost_name status is '$new_status', missing 'f'"
6041         fi
6042
6043         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6044         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6045                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6046         [[ -z "$p" ]] && restore_lustre_params < $p || true
6047         sleep_maxage
6048
6049         new_status=$(ost_dev_status $ost_idx)
6050         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6051                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6052         # can't check 'f' as devices may actually be on flash
6053 }
6054 run_test 56c "check 'lfs df' showing device status"
6055
6056 test_56d() {
6057         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6058         local osts=$($LFS df -v $MOUNT | grep -c OST)
6059
6060         $LFS df $MOUNT
6061
6062         (( mdts == MDSCOUNT )) ||
6063                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6064         (( osts == OSTCOUNT )) ||
6065                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6066 }
6067 run_test 56d "'lfs df -v' prints only configured devices"
6068
6069 NUMFILES=3
6070 NUMDIRS=3
6071 setup_56() {
6072         local local_tdir="$1"
6073         local local_numfiles="$2"
6074         local local_numdirs="$3"
6075         local dir_params="$4"
6076         local dir_stripe_params="$5"
6077
6078         if [ ! -d "$local_tdir" ] ; then
6079                 test_mkdir -p $dir_stripe_params $local_tdir
6080                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6081                 for i in $(seq $local_numfiles) ; do
6082                         touch $local_tdir/file$i
6083                 done
6084                 for i in $(seq $local_numdirs) ; do
6085                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6086                         for j in $(seq $local_numfiles) ; do
6087                                 touch $local_tdir/dir$i/file$j
6088                         done
6089                 done
6090         fi
6091 }
6092
6093 setup_56_special() {
6094         local local_tdir=$1
6095         local local_numfiles=$2
6096         local local_numdirs=$3
6097
6098         setup_56 $local_tdir $local_numfiles $local_numdirs
6099
6100         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6101                 for i in $(seq $local_numfiles) ; do
6102                         mknod $local_tdir/loop${i}b b 7 $i
6103                         mknod $local_tdir/null${i}c c 1 3
6104                         ln -s $local_tdir/file1 $local_tdir/link${i}
6105                 done
6106                 for i in $(seq $local_numdirs) ; do
6107                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6108                         mknod $local_tdir/dir$i/null${i}c c 1 3
6109                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6110                 done
6111         fi
6112 }
6113
6114 test_56g() {
6115         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6116         local expected=$(($NUMDIRS + 2))
6117
6118         setup_56 $dir $NUMFILES $NUMDIRS
6119
6120         # test lfs find with -name
6121         for i in $(seq $NUMFILES) ; do
6122                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6123
6124                 [ $nums -eq $expected ] ||
6125                         error "lfs find -name '*$i' $dir wrong: "\
6126                               "found $nums, expected $expected"
6127         done
6128 }
6129 run_test 56g "check lfs find -name"
6130
6131 test_56h() {
6132         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6133         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6134
6135         setup_56 $dir $NUMFILES $NUMDIRS
6136
6137         # test lfs find with ! -name
6138         for i in $(seq $NUMFILES) ; do
6139                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6140
6141                 [ $nums -eq $expected ] ||
6142                         error "lfs find ! -name '*$i' $dir wrong: "\
6143                               "found $nums, expected $expected"
6144         done
6145 }
6146 run_test 56h "check lfs find ! -name"
6147
6148 test_56i() {
6149         local dir=$DIR/$tdir
6150
6151         test_mkdir $dir
6152
6153         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6154         local out=$($cmd)
6155
6156         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6157 }
6158 run_test 56i "check 'lfs find -ost UUID' skips directories"
6159
6160 test_56j() {
6161         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6162
6163         setup_56_special $dir $NUMFILES $NUMDIRS
6164
6165         local expected=$((NUMDIRS + 1))
6166         local cmd="$LFS find -type d $dir"
6167         local nums=$($cmd | wc -l)
6168
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171 }
6172 run_test 56j "check lfs find -type d"
6173
6174 test_56k() {
6175         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6176
6177         setup_56_special $dir $NUMFILES $NUMDIRS
6178
6179         local expected=$(((NUMDIRS + 1) * NUMFILES))
6180         local cmd="$LFS find -type f $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185 }
6186 run_test 56k "check lfs find -type f"
6187
6188 test_56l() {
6189         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6190
6191         setup_56_special $dir $NUMFILES $NUMDIRS
6192
6193         local expected=$((NUMDIRS + NUMFILES))
6194         local cmd="$LFS find -type b $dir"
6195         local nums=$($cmd | wc -l)
6196
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199 }
6200 run_test 56l "check lfs find -type b"
6201
6202 test_56m() {
6203         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6204
6205         setup_56_special $dir $NUMFILES $NUMDIRS
6206
6207         local expected=$((NUMDIRS + NUMFILES))
6208         local cmd="$LFS find -type c $dir"
6209         local nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212 }
6213 run_test 56m "check lfs find -type c"
6214
6215 test_56n() {
6216         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6217         setup_56_special $dir $NUMFILES $NUMDIRS
6218
6219         local expected=$((NUMDIRS + NUMFILES))
6220         local cmd="$LFS find -type l $dir"
6221         local nums=$($cmd | wc -l)
6222
6223         [ $nums -eq $expected ] ||
6224                 error "'$cmd' wrong: found $nums, expected $expected"
6225 }
6226 run_test 56n "check lfs find -type l"
6227
6228 test_56o() {
6229         local dir=$DIR/$tdir
6230
6231         setup_56 $dir $NUMFILES $NUMDIRS
6232         utime $dir/file1 > /dev/null || error "utime (1)"
6233         utime $dir/file2 > /dev/null || error "utime (2)"
6234         utime $dir/dir1 > /dev/null || error "utime (3)"
6235         utime $dir/dir2 > /dev/null || error "utime (4)"
6236         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6237         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6238
6239         local expected=4
6240         local nums=$($LFS find -mtime +0 $dir | wc -l)
6241
6242         [ $nums -eq $expected ] ||
6243                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6244
6245         expected=12
6246         cmd="$LFS find -mtime 0 $dir"
6247         nums=$($cmd | wc -l)
6248         [ $nums -eq $expected ] ||
6249                 error "'$cmd' wrong: found $nums, expected $expected"
6250 }
6251 run_test 56o "check lfs find -mtime for old files"
6252
6253 test_56ob() {
6254         local dir=$DIR/$tdir
6255         local expected=1
6256         local count=0
6257
6258         # just to make sure there is something that won't be found
6259         test_mkdir $dir
6260         touch $dir/$tfile.now
6261
6262         for age in year week day hour min; do
6263                 count=$((count + 1))
6264
6265                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6266                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6267                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6268
6269                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6270                 local nums=$($cmd | wc -l)
6271                 [ $nums -eq $expected ] ||
6272                         error "'$cmd' wrong: found $nums, expected $expected"
6273
6274                 cmd="$LFS find $dir -atime $count${age:0:1}"
6275                 nums=$($cmd | wc -l)
6276                 [ $nums -eq $expected ] ||
6277                         error "'$cmd' wrong: found $nums, expected $expected"
6278         done
6279
6280         sleep 2
6281         cmd="$LFS find $dir -ctime +1s -type f"
6282         nums=$($cmd | wc -l)
6283         (( $nums == $count * 2 + 1)) ||
6284                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6285 }
6286 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6287
6288 test_newerXY_base() {
6289         local x=$1
6290         local y=$2
6291         local dir=$DIR/$tdir
6292         local ref
6293         local negref
6294
6295         if [ $y == "t" ]; then
6296                 if [ $x == "b" ]; then
6297                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6298                 else
6299                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6300                 fi
6301         else
6302                 ref=$DIR/$tfile.newer.$x$y
6303                 touch $ref || error "touch $ref failed"
6304         fi
6305
6306         echo "before = $ref"
6307         sleep 2
6308         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6309         sleep 2
6310         if [ $y == "t" ]; then
6311                 if [ $x == "b" ]; then
6312                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6313                 else
6314                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6315                 fi
6316         else
6317                 negref=$DIR/$tfile.negnewer.$x$y
6318                 touch $negref || error "touch $negref failed"
6319         fi
6320
6321         echo "after = $negref"
6322         local cmd="$LFS find $dir -newer$x$y $ref"
6323         local nums=$(eval $cmd | wc -l)
6324         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6325
6326         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6327                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6328
6329         cmd="$LFS find $dir ! -newer$x$y $negref"
6330         nums=$(eval $cmd | wc -l)
6331         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6332                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6333
6334         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6335         nums=$(eval $cmd | wc -l)
6336         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6337                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6338
6339         rm -rf $DIR/*
6340 }
6341
6342 test_56oc() {
6343         test_newerXY_base "a" "a"
6344         test_newerXY_base "a" "m"
6345         test_newerXY_base "a" "c"
6346         test_newerXY_base "m" "a"
6347         test_newerXY_base "m" "m"
6348         test_newerXY_base "m" "c"
6349         test_newerXY_base "c" "a"
6350         test_newerXY_base "c" "m"
6351         test_newerXY_base "c" "c"
6352
6353         [[ -n "$sles_version" ]] &&
6354                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6355
6356         test_newerXY_base "a" "t"
6357         test_newerXY_base "m" "t"
6358         test_newerXY_base "c" "t"
6359
6360         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6361            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6362                 ! btime_supported && echo "btime unsupported" && return 0
6363
6364         test_newerXY_base "b" "b"
6365         test_newerXY_base "b" "t"
6366 }
6367 run_test 56oc "check lfs find -newerXY work"
6368
6369 btime_supported() {
6370         local dir=$DIR/$tdir
6371         local rc
6372
6373         mkdir -p $dir
6374         touch $dir/$tfile
6375         $LFS find $dir -btime -1d -type f
6376         rc=$?
6377         rm -rf $dir
6378         return $rc
6379 }
6380
6381 test_56od() {
6382         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6383                 ! btime_supported && skip "btime unsupported on MDS"
6384
6385         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6386                 ! btime_supported && skip "btime unsupported on clients"
6387
6388         local dir=$DIR/$tdir
6389         local ref=$DIR/$tfile.ref
6390         local negref=$DIR/$tfile.negref
6391
6392         mkdir $dir || error "mkdir $dir failed"
6393         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6394         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6395         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6396         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6397         touch $ref || error "touch $ref failed"
6398         # sleep 3 seconds at least
6399         sleep 3
6400
6401         local before=$(do_facet mds1 date +%s)
6402         local skew=$(($(date +%s) - before + 1))
6403
6404         if (( skew < 0 && skew > -5 )); then
6405                 sleep $((0 - skew + 1))
6406                 skew=0
6407         fi
6408
6409         # Set the dir stripe params to limit files all on MDT0,
6410         # otherwise we need to calc the max clock skew between
6411         # the client and MDTs.
6412         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6413         sleep 2
6414         touch $negref || error "touch $negref failed"
6415
6416         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6417         local nums=$($cmd | wc -l)
6418         local expected=$(((NUMFILES + 1) * NUMDIRS))
6419
6420         [ $nums -eq $expected ] ||
6421                 error "'$cmd' wrong: found $nums, expected $expected"
6422
6423         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6424         nums=$($cmd | wc -l)
6425         expected=$((NUMFILES + 1))
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         [ $skew -lt 0 ] && return
6430
6431         local after=$(do_facet mds1 date +%s)
6432         local age=$((after - before + 1 + skew))
6433
6434         cmd="$LFS find $dir -btime -${age}s -type f"
6435         nums=$($cmd | wc -l)
6436         expected=$(((NUMFILES + 1) * NUMDIRS))
6437
6438         echo "Clock skew between client and server: $skew, age:$age"
6439         [ $nums -eq $expected ] ||
6440                 error "'$cmd' wrong: found $nums, expected $expected"
6441
6442         expected=$(($NUMDIRS + 1))
6443         cmd="$LFS find $dir -btime -${age}s -type d"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447         rm -f $ref $negref || error "Failed to remove $ref $negref"
6448 }
6449 run_test 56od "check lfs find -btime with units"
6450
6451 test_56p() {
6452         [ $RUNAS_ID -eq $UID ] &&
6453                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6454
6455         local dir=$DIR/$tdir
6456
6457         setup_56 $dir $NUMFILES $NUMDIRS
6458         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6459
6460         local expected=$NUMFILES
6461         local cmd="$LFS find -uid $RUNAS_ID $dir"
6462         local nums=$($cmd | wc -l)
6463
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6468         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6469         nums=$($cmd | wc -l)
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472 }
6473 run_test 56p "check lfs find -uid and ! -uid"
6474
6475 test_56q() {
6476         [ $RUNAS_ID -eq $UID ] &&
6477                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6478
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6483
6484         local expected=$NUMFILES
6485         local cmd="$LFS find -gid $RUNAS_GID $dir"
6486         local nums=$($cmd | wc -l)
6487
6488         [ $nums -eq $expected ] ||
6489                 error "'$cmd' wrong: found $nums, expected $expected"
6490
6491         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6492         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6493         nums=$($cmd | wc -l)
6494         [ $nums -eq $expected ] ||
6495                 error "'$cmd' wrong: found $nums, expected $expected"
6496 }
6497 run_test 56q "check lfs find -gid and ! -gid"
6498
6499 test_56r() {
6500         local dir=$DIR/$tdir
6501
6502         setup_56 $dir $NUMFILES $NUMDIRS
6503
6504         local expected=12
6505         local cmd="$LFS find -size 0 -type f -lazy $dir"
6506         local nums=$($cmd | wc -l)
6507
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510         cmd="$LFS find -size 0 -type f $dir"
6511         nums=$($cmd | wc -l)
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         expected=0
6516         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520         cmd="$LFS find ! -size 0 -type f $dir"
6521         nums=$($cmd | wc -l)
6522         [ $nums -eq $expected ] ||
6523                 error "'$cmd' wrong: found $nums, expected $expected"
6524
6525         echo "test" > $dir/$tfile
6526         echo "test2" > $dir/$tfile.2 && sync
6527         expected=1
6528         cmd="$LFS find -size 5 -type f -lazy $dir"
6529         nums=$($cmd | wc -l)
6530         [ $nums -eq $expected ] ||
6531                 error "'$cmd' wrong: found $nums, expected $expected"
6532         cmd="$LFS find -size 5 -type f $dir"
6533         nums=$($cmd | wc -l)
6534         [ $nums -eq $expected ] ||
6535                 error "'$cmd' wrong: found $nums, expected $expected"
6536
6537         expected=1
6538         cmd="$LFS find -size +5 -type f -lazy $dir"
6539         nums=$($cmd | wc -l)
6540         [ $nums -eq $expected ] ||
6541                 error "'$cmd' wrong: found $nums, expected $expected"
6542         cmd="$LFS find -size +5 -type f $dir"
6543         nums=$($cmd | wc -l)
6544         [ $nums -eq $expected ] ||
6545                 error "'$cmd' wrong: found $nums, expected $expected"
6546
6547         expected=2
6548         cmd="$LFS find -size +0 -type f -lazy $dir"
6549         nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552         cmd="$LFS find -size +0 -type f $dir"
6553         nums=$($cmd | wc -l)
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         expected=2
6558         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6559         nums=$($cmd | wc -l)
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562         cmd="$LFS find ! -size -5 -type f $dir"
6563         nums=$($cmd | wc -l)
6564         [ $nums -eq $expected ] ||
6565                 error "'$cmd' wrong: found $nums, expected $expected"
6566
6567         expected=12
6568         cmd="$LFS find -size -5 -type f -lazy $dir"
6569         nums=$($cmd | wc -l)
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572         cmd="$LFS find -size -5 -type f $dir"
6573         nums=$($cmd | wc -l)
6574         [ $nums -eq $expected ] ||
6575                 error "'$cmd' wrong: found $nums, expected $expected"
6576 }
6577 run_test 56r "check lfs find -size works"
6578
6579 test_56ra_sub() {
6580         local expected=$1
6581         local glimpses=$2
6582         local cmd="$3"
6583
6584         cancel_lru_locks $OSC
6585
6586         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6587         local nums=$($cmd | wc -l)
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591
6592         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6593
6594         if (( rpcs_before + glimpses != rpcs_after )); then
6595                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6596                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6597
6598                 if [[ $glimpses == 0 ]]; then
6599                         error "'$cmd' should not send glimpse RPCs to OST"
6600                 else
6601                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6602                 fi
6603         fi
6604 }
6605
6606 test_56ra() {
6607         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6608                 skip "MDS < 2.12.58 doesn't return LSOM data"
6609         local dir=$DIR/$tdir
6610         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6611
6612         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6613
6614         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6615         $LCTL set_param -n llite.*.statahead_agl=0
6616         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6617
6618         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6619         # open and close all files to ensure LSOM is updated
6620         cancel_lru_locks $OSC
6621         find $dir -type f | xargs cat > /dev/null
6622
6623         #   expect_found  glimpse_rpcs  command_to_run
6624         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6625         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6626         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6627         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6628
6629         echo "test" > $dir/$tfile
6630         echo "test2" > $dir/$tfile.2 && sync
6631         cancel_lru_locks $OSC
6632         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6633
6634         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6635         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6636         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6637         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6638
6639         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6640         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6641         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6642         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6643         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6644         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6645 }
6646 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6647
6648 test_56rb() {
6649         local dir=$DIR/$tdir
6650         local tmp=$TMP/$tfile.log
6651         local mdt_idx;
6652
6653         test_mkdir -p $dir || error "failed to mkdir $dir"
6654         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6655                 error "failed to setstripe $dir/$tfile"
6656         mdt_idx=$($LFS getdirstripe -i $dir)
6657         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6658
6659         stack_trap "rm -f $tmp" EXIT
6660         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6661         ! grep -q obd_uuid $tmp ||
6662                 error "failed to find --size +100K --ost 0 $dir"
6663         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6664         ! grep -q obd_uuid $tmp ||
6665                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6666 }
6667 run_test 56rb "check lfs find --size --ost/--mdt works"
6668
6669 test_56rc() {
6670         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6671         local dir=$DIR/$tdir
6672         local found
6673
6674         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6675         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6676         (( $MDSCOUNT > 2 )) &&
6677                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6678         mkdir $dir/$tdir-{1..10}
6679         touch $dir/$tfile-{1..10}
6680
6681         found=$($LFS find $dir --mdt-count 2 | wc -l)
6682         expect=11
6683         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6684
6685         found=$($LFS find $dir -T +1 | wc -l)
6686         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6687         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6688
6689         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6690         expect=11
6691         (( $found == $expect )) || error "found $found all_char, expect $expect"
6692
6693         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6694         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6695         (( $found == $expect )) || error "found $found all_char, expect $expect"
6696 }
6697 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6698
6699 test_56s() { # LU-611 #LU-9369
6700         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6701
6702         local dir=$DIR/$tdir
6703         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6706         for i in $(seq $NUMDIRS); do
6707                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6708         done
6709
6710         local expected=$NUMDIRS
6711         local cmd="$LFS find -c $OSTCOUNT $dir"
6712         local nums=$($cmd | wc -l)
6713
6714         [ $nums -eq $expected ] || {
6715                 $LFS getstripe -R $dir
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717         }
6718
6719         expected=$((NUMDIRS + onestripe))
6720         cmd="$LFS find -stripe-count +0 -type f $dir"
6721         nums=$($cmd | wc -l)
6722         [ $nums -eq $expected ] || {
6723                 $LFS getstripe -R $dir
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725         }
6726
6727         expected=$onestripe
6728         cmd="$LFS find -stripe-count 1 -type f $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] || {
6731                 $LFS getstripe -R $dir
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         }
6734
6735         cmd="$LFS find -stripe-count -2 -type f $dir"
6736         nums=$($cmd | wc -l)
6737         [ $nums -eq $expected ] || {
6738                 $LFS getstripe -R $dir
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740         }
6741
6742         expected=0
6743         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] || {
6746                 $LFS getstripe -R $dir
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748         }
6749 }
6750 run_test 56s "check lfs find -stripe-count works"
6751
6752 test_56t() { # LU-611 #LU-9369
6753         local dir=$DIR/$tdir
6754
6755         setup_56 $dir 0 $NUMDIRS
6756         for i in $(seq $NUMDIRS); do
6757                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6758         done
6759
6760         local expected=$NUMDIRS
6761         local cmd="$LFS find -S 8M $dir"
6762         local nums=$($cmd | wc -l)
6763
6764         [ $nums -eq $expected ] || {
6765                 $LFS getstripe -R $dir
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767         }
6768         rm -rf $dir
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6771
6772         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6773
6774         expected=$(((NUMDIRS + 1) * NUMFILES))
6775         cmd="$LFS find -stripe-size 512k -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         cmd="$LFS find -stripe-size +320k -type f $dir"
6781         nums=$($cmd | wc -l)
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784
6785         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6786         cmd="$LFS find -stripe-size +200k -type f $dir"
6787         nums=$($cmd | wc -l)
6788         [ $nums -eq $expected ] ||
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790
6791         cmd="$LFS find -stripe-size -640k -type f $dir"
6792         nums=$($cmd | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795
6796         expected=4
6797         cmd="$LFS find -stripe-size 256k -type f $dir"
6798         nums=$($cmd | wc -l)
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         cmd="$LFS find -stripe-size -320k -type f $dir"
6803         nums=$($cmd | wc -l)
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806
6807         expected=0
6808         cmd="$LFS find -stripe-size 1024k -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812 }
6813 run_test 56t "check lfs find -stripe-size works"
6814
6815 test_56u() { # LU-611
6816         local dir=$DIR/$tdir
6817
6818         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6819
6820         if [[ $OSTCOUNT -gt 1 ]]; then
6821                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6822                 onestripe=4
6823         else
6824                 onestripe=0
6825         fi
6826
6827         local expected=$(((NUMDIRS + 1) * NUMFILES))
6828         local cmd="$LFS find -stripe-index 0 -type f $dir"
6829         local nums=$($cmd | wc -l)
6830
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         expected=$onestripe
6835         cmd="$LFS find -stripe-index 1 -type f $dir"
6836         nums=$($cmd | wc -l)
6837         [ $nums -eq $expected ] ||
6838                 error "'$cmd' wrong: found $nums, expected $expected"
6839
6840         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         expected=0
6846         # This should produce an error and not return any files
6847         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6848         nums=$($cmd 2>/dev/null | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851
6852         if [[ $OSTCOUNT -gt 1 ]]; then
6853                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6854                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6855                 nums=$($cmd | wc -l)
6856                 [ $nums -eq $expected ] ||
6857                         error "'$cmd' wrong: found $nums, expected $expected"
6858         fi
6859 }
6860 run_test 56u "check lfs find -stripe-index works"
6861
6862 test_56v() {
6863         local mdt_idx=0
6864         local dir=$DIR/$tdir
6865
6866         setup_56 $dir $NUMFILES $NUMDIRS
6867
6868         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6869         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6870
6871         for file in $($LFS find -m $UUID $dir); do
6872                 file_midx=$($LFS getstripe -m $file)
6873                 [ $file_midx -eq $mdt_idx ] ||
6874                         error "lfs find -m $UUID != getstripe -m $file_midx"
6875         done
6876 }
6877 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6878
6879 test_56w() {
6880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6882
6883         local dir=$DIR/$tdir
6884
6885         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6886
6887         local stripe_size=$($LFS getstripe -S -d $dir) ||
6888                 error "$LFS getstripe -S -d $dir failed"
6889         stripe_size=${stripe_size%% *}
6890
6891         local file_size=$((stripe_size * OSTCOUNT))
6892         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6893         local required_space=$((file_num * file_size))
6894         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6895                            head -n1)
6896         [[ $free_space -le $((required_space / 1024)) ]] &&
6897                 skip_env "need $required_space, have $free_space kbytes"
6898
6899         local dd_bs=65536
6900         local dd_count=$((file_size / dd_bs))
6901
6902         # write data into the files
6903         local i
6904         local j
6905         local file
6906
6907         for i in $(seq $NUMFILES); do
6908                 file=$dir/file$i
6909                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6910                         error "write data into $file failed"
6911         done
6912         for i in $(seq $NUMDIRS); do
6913                 for j in $(seq $NUMFILES); do
6914                         file=$dir/dir$i/file$j
6915                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6916                                 error "write data into $file failed"
6917                 done
6918         done
6919
6920         # $LFS_MIGRATE will fail if hard link migration is unsupported
6921         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6922                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6923                         error "creating links to $dir/dir1/file1 failed"
6924         fi
6925
6926         local expected=-1
6927
6928         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6929
6930         # lfs_migrate file
6931         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6932
6933         echo "$cmd"
6934         eval $cmd || error "$cmd failed"
6935
6936         check_stripe_count $dir/file1 $expected
6937
6938         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6939         then
6940                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6941                 # OST 1 if it is on OST 0. This file is small enough to
6942                 # be on only one stripe.
6943                 file=$dir/migr_1_ost
6944                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6945                         error "write data into $file failed"
6946                 local obdidx=$($LFS getstripe -i $file)
6947                 local oldmd5=$(md5sum $file)
6948                 local newobdidx=0
6949
6950                 [[ $obdidx -eq 0 ]] && newobdidx=1
6951                 cmd="$LFS migrate -i $newobdidx $file"
6952                 echo $cmd
6953                 eval $cmd || error "$cmd failed"
6954
6955                 local realobdix=$($LFS getstripe -i $file)
6956                 local newmd5=$(md5sum $file)
6957
6958                 [[ $newobdidx -ne $realobdix ]] &&
6959                         error "new OST is different (was=$obdidx, "\
6960                               "wanted=$newobdidx, got=$realobdix)"
6961                 [[ "$oldmd5" != "$newmd5" ]] &&
6962                         error "md5sum differ: $oldmd5, $newmd5"
6963         fi
6964
6965         # lfs_migrate dir
6966         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6967         echo "$cmd"
6968         eval $cmd || error "$cmd failed"
6969
6970         for j in $(seq $NUMFILES); do
6971                 check_stripe_count $dir/dir1/file$j $expected
6972         done
6973
6974         # lfs_migrate works with lfs find
6975         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6976              $LFS_MIGRATE -y -c $expected"
6977         echo "$cmd"
6978         eval $cmd || error "$cmd failed"
6979
6980         for i in $(seq 2 $NUMFILES); do
6981                 check_stripe_count $dir/file$i $expected
6982         done
6983         for i in $(seq 2 $NUMDIRS); do
6984                 for j in $(seq $NUMFILES); do
6985                 check_stripe_count $dir/dir$i/file$j $expected
6986                 done
6987         done
6988 }
6989 run_test 56w "check lfs_migrate -c stripe_count works"
6990
6991 test_56wb() {
6992         local file1=$DIR/$tdir/file1
6993         local create_pool=false
6994         local initial_pool=$($LFS getstripe -p $DIR)
6995         local pool_list=()
6996         local pool=""
6997
6998         echo -n "Creating test dir..."
6999         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7000         echo "done."
7001
7002         echo -n "Creating test file..."
7003         touch $file1 || error "cannot create file"
7004         echo "done."
7005
7006         echo -n "Detecting existing pools..."
7007         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7008
7009         if [ ${#pool_list[@]} -gt 0 ]; then
7010                 echo "${pool_list[@]}"
7011                 for thispool in "${pool_list[@]}"; do
7012                         if [[ -z "$initial_pool" ||
7013                               "$initial_pool" != "$thispool" ]]; then
7014                                 pool="$thispool"
7015                                 echo "Using existing pool '$pool'"
7016                                 break
7017                         fi
7018                 done
7019         else
7020                 echo "none detected."
7021         fi
7022         if [ -z "$pool" ]; then
7023                 pool=${POOL:-testpool}
7024                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7025                 echo -n "Creating pool '$pool'..."
7026                 create_pool=true
7027                 pool_add $pool &> /dev/null ||
7028                         error "pool_add failed"
7029                 echo "done."
7030
7031                 echo -n "Adding target to pool..."
7032                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7033                         error "pool_add_targets failed"
7034                 echo "done."
7035         fi
7036
7037         echo -n "Setting pool using -p option..."
7038         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7039                 error "migrate failed rc = $?"
7040         echo "done."
7041
7042         echo -n "Verifying test file is in pool after migrating..."
7043         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7044                 error "file was not migrated to pool $pool"
7045         echo "done."
7046
7047         echo -n "Removing test file from pool '$pool'..."
7048         # "lfs migrate $file" won't remove the file from the pool
7049         # until some striping information is changed.
7050         $LFS migrate -c 1 $file1 &> /dev/null ||
7051                 error "cannot remove from pool"
7052         [ "$($LFS getstripe -p $file1)" ] &&
7053                 error "pool still set"
7054         echo "done."
7055
7056         echo -n "Setting pool using --pool option..."
7057         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7058                 error "migrate failed rc = $?"
7059         echo "done."
7060
7061         # Clean up
7062         rm -f $file1
7063         if $create_pool; then
7064                 destroy_test_pools 2> /dev/null ||
7065                         error "destroy test pools failed"
7066         fi
7067 }
7068 run_test 56wb "check lfs_migrate pool support"
7069
7070 test_56wc() {
7071         local file1="$DIR/$tdir/file1"
7072         local parent_ssize
7073         local parent_scount
7074         local cur_ssize
7075         local cur_scount
7076         local orig_ssize
7077
7078         echo -n "Creating test dir..."
7079         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7080         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7081                 error "cannot set stripe by '-S 1M -c 1'"
7082         echo "done"
7083
7084         echo -n "Setting initial stripe for test file..."
7085         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7086                 error "cannot set stripe"
7087         cur_ssize=$($LFS getstripe -S "$file1")
7088         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7089         echo "done."
7090
7091         # File currently set to -S 512K -c 1
7092
7093         # Ensure -c and -S options are rejected when -R is set
7094         echo -n "Verifying incompatible options are detected..."
7095         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7096                 error "incompatible -c and -R options not detected"
7097         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7098                 error "incompatible -S and -R options not detected"
7099         echo "done."
7100
7101         # Ensure unrecognized options are passed through to 'lfs migrate'
7102         echo -n "Verifying -S option is passed through to lfs migrate..."
7103         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7104                 error "migration failed"
7105         cur_ssize=$($LFS getstripe -S "$file1")
7106         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7107         echo "done."
7108
7109         # File currently set to -S 1M -c 1
7110
7111         # Ensure long options are supported
7112         echo -n "Verifying long options supported..."
7113         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7114                 error "long option without argument not supported"
7115         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7116                 error "long option with argument not supported"
7117         cur_ssize=$($LFS getstripe -S "$file1")
7118         [ $cur_ssize -eq 524288 ] ||
7119                 error "migrate --stripe-size $cur_ssize != 524288"
7120         echo "done."
7121
7122         # File currently set to -S 512K -c 1
7123
7124         if [ "$OSTCOUNT" -gt 1 ]; then
7125                 echo -n "Verifying explicit stripe count can be set..."
7126                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7127                         error "migrate failed"
7128                 cur_scount=$($LFS getstripe -c "$file1")
7129                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7130                 echo "done."
7131         fi
7132
7133         # File currently set to -S 512K -c 1 or -S 512K -c 2
7134
7135         # Ensure parent striping is used if -R is set, and no stripe
7136         # count or size is specified
7137         echo -n "Setting stripe for parent directory..."
7138         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7139                 error "cannot set stripe '-S 2M -c 1'"
7140         echo "done."
7141
7142         echo -n "Verifying restripe option uses parent stripe settings..."
7143         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7144         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7145         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7146                 error "migrate failed"
7147         cur_ssize=$($LFS getstripe -S "$file1")
7148         [ $cur_ssize -eq $parent_ssize ] ||
7149                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7150         cur_scount=$($LFS getstripe -c "$file1")
7151         [ $cur_scount -eq $parent_scount ] ||
7152                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7153         echo "done."
7154
7155         # File currently set to -S 1M -c 1
7156
7157         # Ensure striping is preserved if -R is not set, and no stripe
7158         # count or size is specified
7159         echo -n "Verifying striping size preserved when not specified..."
7160         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7161         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7162                 error "cannot set stripe on parent directory"
7163         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7164                 error "migrate failed"
7165         cur_ssize=$($LFS getstripe -S "$file1")
7166         [ $cur_ssize -eq $orig_ssize ] ||
7167                 error "migrate by default $cur_ssize != $orig_ssize"
7168         echo "done."
7169
7170         # Ensure file name properly detected when final option has no argument
7171         echo -n "Verifying file name properly detected..."
7172         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7173                 error "file name interpreted as option argument"
7174         echo "done."
7175
7176         # Clean up
7177         rm -f "$file1"
7178 }
7179 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7180
7181 test_56wd() {
7182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7183
7184         local file1=$DIR/$tdir/file1
7185
7186         echo -n "Creating test dir..."
7187         test_mkdir $DIR/$tdir || error "cannot create dir"
7188         echo "done."
7189
7190         echo -n "Creating test file..."
7191         touch $file1
7192         echo "done."
7193
7194         # Ensure 'lfs migrate' will fail by using a non-existent option,
7195         # and make sure rsync is not called to recover
7196         echo -n "Make sure --no-rsync option works..."
7197         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7198                 grep -q 'refusing to fall back to rsync' ||
7199                 error "rsync was called with --no-rsync set"
7200         echo "done."
7201
7202         # Ensure rsync is called without trying 'lfs migrate' first
7203         echo -n "Make sure --rsync option works..."
7204         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7205                 grep -q 'falling back to rsync' &&
7206                 error "lfs migrate was called with --rsync set"
7207         echo "done."
7208
7209         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7210         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7211                 grep -q 'at the same time' ||
7212                 error "--rsync and --no-rsync accepted concurrently"
7213         echo "done."
7214
7215         # Clean up
7216         rm -f $file1
7217 }
7218 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7219
7220 test_56we() {
7221         local td=$DIR/$tdir
7222         local tf=$td/$tfile
7223
7224         test_mkdir $td || error "cannot create $td"
7225         touch $tf || error "cannot touch $tf"
7226
7227         echo -n "Make sure --non-direct|-D works..."
7228         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7229                 grep -q "lfs migrate --non-direct" ||
7230                 error "--non-direct option cannot work correctly"
7231         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7232                 grep -q "lfs migrate -D" ||
7233                 error "-D option cannot work correctly"
7234         echo "done."
7235 }
7236 run_test 56we "check lfs_migrate --non-direct|-D support"
7237
7238 test_56x() {
7239         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7240         check_swap_layouts_support
7241
7242         local dir=$DIR/$tdir
7243         local ref1=/etc/passwd
7244         local file1=$dir/file1
7245
7246         test_mkdir $dir || error "creating dir $dir"
7247         $LFS setstripe -c 2 $file1
7248         cp $ref1 $file1
7249         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7250         stripe=$($LFS getstripe -c $file1)
7251         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7252         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7253
7254         # clean up
7255         rm -f $file1
7256 }
7257 run_test 56x "lfs migration support"
7258
7259 test_56xa() {
7260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7261         check_swap_layouts_support
7262
7263         local dir=$DIR/$tdir/$testnum
7264
7265         test_mkdir -p $dir
7266
7267         local ref1=/etc/passwd
7268         local file1=$dir/file1
7269
7270         $LFS setstripe -c 2 $file1
7271         cp $ref1 $file1
7272         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7273
7274         local stripe=$($LFS getstripe -c $file1)
7275
7276         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7277         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7278
7279         # clean up
7280         rm -f $file1
7281 }
7282 run_test 56xa "lfs migration --block support"
7283
7284 check_migrate_links() {
7285         local dir="$1"
7286         local file1="$dir/file1"
7287         local begin="$2"
7288         local count="$3"
7289         local runas="$4"
7290         local total_count=$(($begin + $count - 1))
7291         local symlink_count=10
7292         local uniq_count=10
7293
7294         if [ ! -f "$file1" ]; then
7295                 echo -n "creating initial file..."
7296                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7297                         error "cannot setstripe initial file"
7298                 echo "done"
7299
7300                 echo -n "creating symlinks..."
7301                 for s in $(seq 1 $symlink_count); do
7302                         ln -s "$file1" "$dir/slink$s" ||
7303                                 error "cannot create symlinks"
7304                 done
7305                 echo "done"
7306
7307                 echo -n "creating nonlinked files..."
7308                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7309                         error "cannot create nonlinked files"
7310                 echo "done"
7311         fi
7312
7313         # create hard links
7314         if [ ! -f "$dir/file$total_count" ]; then
7315                 echo -n "creating hard links $begin:$total_count..."
7316                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7317                         /dev/null || error "cannot create hard links"
7318                 echo "done"
7319         fi
7320
7321         echo -n "checking number of hard links listed in xattrs..."
7322         local fid=$($LFS getstripe -F "$file1")
7323         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7324
7325         echo "${#paths[*]}"
7326         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7327                         skip "hard link list has unexpected size, skipping test"
7328         fi
7329         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7330                         error "link names should exceed xattrs size"
7331         fi
7332
7333         echo -n "migrating files..."
7334         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7335         local rc=$?
7336         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7337         echo "done"
7338
7339         # make sure all links have been properly migrated
7340         echo -n "verifying files..."
7341         fid=$($LFS getstripe -F "$file1") ||
7342                 error "cannot get fid for file $file1"
7343         for i in $(seq 2 $total_count); do
7344                 local fid2=$($LFS getstripe -F $dir/file$i)
7345
7346                 [ "$fid2" == "$fid" ] ||
7347                         error "migrated hard link has mismatched FID"
7348         done
7349
7350         # make sure hard links were properly detected, and migration was
7351         # performed only once for the entire link set; nonlinked files should
7352         # also be migrated
7353         local actual=$(grep -c 'done' <<< "$migrate_out")
7354         local expected=$(($uniq_count + 1))
7355
7356         [ "$actual" -eq  "$expected" ] ||
7357                 error "hard links individually migrated ($actual != $expected)"
7358
7359         # make sure the correct number of hard links are present
7360         local hardlinks=$(stat -c '%h' "$file1")
7361
7362         [ $hardlinks -eq $total_count ] ||
7363                 error "num hard links $hardlinks != $total_count"
7364         echo "done"
7365
7366         return 0
7367 }
7368
7369 test_56xb() {
7370         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7371                 skip "Need MDS version at least 2.10.55"
7372
7373         local dir="$DIR/$tdir"
7374
7375         test_mkdir "$dir" || error "cannot create dir $dir"
7376
7377         echo "testing lfs migrate mode when all links fit within xattrs"
7378         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7379
7380         echo "testing rsync mode when all links fit within xattrs"
7381         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7382
7383         echo "testing lfs migrate mode when all links do not fit within xattrs"
7384         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7385
7386         echo "testing rsync mode when all links do not fit within xattrs"
7387         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7388
7389         chown -R $RUNAS_ID $dir
7390         echo "testing non-root lfs migrate mode when not all links are in xattr"
7391         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7392
7393         # clean up
7394         rm -rf $dir
7395 }
7396 run_test 56xb "lfs migration hard link support"
7397
7398 test_56xc() {
7399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7400
7401         local dir="$DIR/$tdir"
7402
7403         test_mkdir "$dir" || error "cannot create dir $dir"
7404
7405         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7406         echo -n "Setting initial stripe for 20MB test file..."
7407         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7408                 error "cannot setstripe 20MB file"
7409         echo "done"
7410         echo -n "Sizing 20MB test file..."
7411         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7412         echo "done"
7413         echo -n "Verifying small file autostripe count is 1..."
7414         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7415                 error "cannot migrate 20MB file"
7416         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7417                 error "cannot get stripe for $dir/20mb"
7418         [ $stripe_count -eq 1 ] ||
7419                 error "unexpected stripe count $stripe_count for 20MB file"
7420         rm -f "$dir/20mb"
7421         echo "done"
7422
7423         # Test 2: File is small enough to fit within the available space on
7424         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7425         # have at least an additional 1KB for each desired stripe for test 3
7426         echo -n "Setting stripe for 1GB test file..."
7427         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7428         echo "done"
7429         echo -n "Sizing 1GB test file..."
7430         # File size is 1GB + 3KB
7431         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7432         echo "done"
7433
7434         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7435         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7436         if (( avail > 524288 * OSTCOUNT )); then
7437                 echo -n "Migrating 1GB file..."
7438                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7439                         error "cannot migrate 1GB file"
7440                 echo "done"
7441                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7442                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7443                         error "cannot getstripe for 1GB file"
7444                 [ $stripe_count -eq 2 ] ||
7445                         error "unexpected stripe count $stripe_count != 2"
7446                 echo "done"
7447         fi
7448
7449         # Test 3: File is too large to fit within the available space on
7450         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7451         if [ $OSTCOUNT -ge 3 ]; then
7452                 # The required available space is calculated as
7453                 # file size (1GB + 3KB) / OST count (3).
7454                 local kb_per_ost=349526
7455
7456                 echo -n "Migrating 1GB file with limit..."
7457                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7458                         error "cannot migrate 1GB file with limit"
7459                 echo "done"
7460
7461                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7462                 echo -n "Verifying 1GB autostripe count with limited space..."
7463                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7464                         error "unexpected stripe count $stripe_count (min 3)"
7465                 echo "done"
7466         fi
7467
7468         # clean up
7469         rm -rf $dir
7470 }
7471 run_test 56xc "lfs migration autostripe"
7472
7473 test_56xd() {
7474         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7475
7476         local dir=$DIR/$tdir
7477         local f_mgrt=$dir/$tfile.mgrt
7478         local f_yaml=$dir/$tfile.yaml
7479         local f_copy=$dir/$tfile.copy
7480         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7481         local layout_copy="-c 2 -S 2M -i 1"
7482         local yamlfile=$dir/yamlfile
7483         local layout_before;
7484         local layout_after;
7485
7486         test_mkdir "$dir" || error "cannot create dir $dir"
7487         $LFS setstripe $layout_yaml $f_yaml ||
7488                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7489         $LFS getstripe --yaml $f_yaml > $yamlfile
7490         $LFS setstripe $layout_copy $f_copy ||
7491                 error "cannot setstripe $f_copy with layout $layout_copy"
7492         touch $f_mgrt
7493         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7494
7495         # 1. test option --yaml
7496         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7497                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7498         layout_before=$(get_layout_param $f_yaml)
7499         layout_after=$(get_layout_param $f_mgrt)
7500         [ "$layout_after" == "$layout_before" ] ||
7501                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7502
7503         # 2. test option --copy
7504         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7505                 error "cannot migrate $f_mgrt with --copy $f_copy"
7506         layout_before=$(get_layout_param $f_copy)
7507         layout_after=$(get_layout_param $f_mgrt)
7508         [ "$layout_after" == "$layout_before" ] ||
7509                 error "lfs_migrate --copy: $layout_after != $layout_before"
7510 }
7511 run_test 56xd "check lfs_migrate --yaml and --copy support"
7512
7513 test_56xe() {
7514         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7515
7516         local dir=$DIR/$tdir
7517         local f_comp=$dir/$tfile
7518         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7519         local layout_before=""
7520         local layout_after=""
7521
7522         test_mkdir "$dir" || error "cannot create dir $dir"
7523         $LFS setstripe $layout $f_comp ||
7524                 error "cannot setstripe $f_comp with layout $layout"
7525         layout_before=$(get_layout_param $f_comp)
7526         dd if=/dev/zero of=$f_comp bs=1M count=4
7527
7528         # 1. migrate a comp layout file by lfs_migrate
7529         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7530         layout_after=$(get_layout_param $f_comp)
7531         [ "$layout_before" == "$layout_after" ] ||
7532                 error "lfs_migrate: $layout_before != $layout_after"
7533
7534         # 2. migrate a comp layout file by lfs migrate
7535         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7536         layout_after=$(get_layout_param $f_comp)
7537         [ "$layout_before" == "$layout_after" ] ||
7538                 error "lfs migrate: $layout_before != $layout_after"
7539 }
7540 run_test 56xe "migrate a composite layout file"
7541
7542 test_56xf() {
7543         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7544
7545         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7546                 skip "Need server version at least 2.13.53"
7547
7548         local dir=$DIR/$tdir
7549         local f_comp=$dir/$tfile
7550         local layout="-E 1M -c1 -E -1 -c2"
7551         local fid_before=""
7552         local fid_after=""
7553
7554         test_mkdir "$dir" || error "cannot create dir $dir"
7555         $LFS setstripe $layout $f_comp ||
7556                 error "cannot setstripe $f_comp with layout $layout"
7557         fid_before=$($LFS getstripe --fid $f_comp)
7558         dd if=/dev/zero of=$f_comp bs=1M count=4
7559
7560         # 1. migrate a comp layout file to a comp layout
7561         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7562         fid_after=$($LFS getstripe --fid $f_comp)
7563         [ "$fid_before" == "$fid_after" ] ||
7564                 error "comp-to-comp migrate: $fid_before != $fid_after"
7565
7566         # 2. migrate a comp layout file to a plain layout
7567         $LFS migrate -c2 $f_comp ||
7568                 error "cannot migrate $f_comp by lfs migrate"
7569         fid_after=$($LFS getstripe --fid $f_comp)
7570         [ "$fid_before" == "$fid_after" ] ||
7571                 error "comp-to-plain migrate: $fid_before != $fid_after"
7572
7573         # 3. migrate a plain layout file to a comp layout
7574         $LFS migrate $layout $f_comp ||
7575                 error "cannot migrate $f_comp by lfs migrate"
7576         fid_after=$($LFS getstripe --fid $f_comp)
7577         [ "$fid_before" == "$fid_after" ] ||
7578                 error "plain-to-comp migrate: $fid_before != $fid_after"
7579 }
7580 run_test 56xf "FID is not lost during migration of a composite layout file"
7581
7582 test_56y() {
7583         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7584                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7585
7586         local res=""
7587         local dir=$DIR/$tdir
7588         local f1=$dir/file1
7589         local f2=$dir/file2
7590
7591         test_mkdir -p $dir || error "creating dir $dir"
7592         touch $f1 || error "creating std file $f1"
7593         $MULTIOP $f2 H2c || error "creating released file $f2"
7594
7595         # a directory can be raid0, so ask only for files
7596         res=$($LFS find $dir -L raid0 -type f | wc -l)
7597         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7598
7599         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7600         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7601
7602         # only files can be released, so no need to force file search
7603         res=$($LFS find $dir -L released)
7604         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7605
7606         res=$($LFS find $dir -type f \! -L released)
7607         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7608 }
7609 run_test 56y "lfs find -L raid0|released"
7610
7611 test_56z() { # LU-4824
7612         # This checks to make sure 'lfs find' continues after errors
7613         # There are two classes of errors that should be caught:
7614         # - If multiple paths are provided, all should be searched even if one
7615         #   errors out
7616         # - If errors are encountered during the search, it should not terminate
7617         #   early
7618         local dir=$DIR/$tdir
7619         local i
7620
7621         test_mkdir $dir
7622         for i in d{0..9}; do
7623                 test_mkdir $dir/$i
7624                 touch $dir/$i/$tfile
7625         done
7626         $LFS find $DIR/non_existent_dir $dir &&
7627                 error "$LFS find did not return an error"
7628         # Make a directory unsearchable. This should NOT be the last entry in
7629         # directory order.  Arbitrarily pick the 6th entry
7630         chmod 700 $($LFS find $dir -type d | sed '6!d')
7631
7632         $RUNAS $LFS find $DIR/non_existent $dir
7633         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7634
7635         # The user should be able to see 10 directories and 9 files
7636         (( count == 19 )) ||
7637                 error "$LFS find found $count != 19 entries after error"
7638 }
7639 run_test 56z "lfs find should continue after an error"
7640
7641 test_56aa() { # LU-5937
7642         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7643
7644         local dir=$DIR/$tdir
7645
7646         mkdir $dir
7647         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7648
7649         createmany -o $dir/striped_dir/${tfile}- 1024
7650         local dirs=$($LFS find --size +8k $dir/)
7651
7652         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7653 }
7654 run_test 56aa "lfs find --size under striped dir"
7655
7656 test_56ab() { # LU-10705
7657         test_mkdir $DIR/$tdir
7658         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7659         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7660         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7661         # Flush writes to ensure valid blocks.  Need to be more thorough for
7662         # ZFS, since blocks are not allocated/returned to client immediately.
7663         sync_all_data
7664         wait_zfs_commit ost1 2
7665         cancel_lru_locks osc
7666         ls -ls $DIR/$tdir
7667
7668         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7669
7670         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7671
7672         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7673         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7674
7675         rm -f $DIR/$tdir/$tfile.[123]
7676 }
7677 run_test 56ab "lfs find --blocks"
7678
7679 # LU-11188
7680 test_56aca() {
7681         local dir="$DIR/$tdir"
7682         local perms=(001 002 003 004 005 006 007
7683                      010 020 030 040 050 060 070
7684                      100 200 300 400 500 600 700
7685                      111 222 333 444 555 666 777)
7686         local perm_minus=(8 8 4 8 4 4 2
7687                           8 8 4 8 4 4 2
7688                           8 8 4 8 4 4 2
7689                           4 4 2 4 2 2 1)
7690         local perm_slash=(8  8 12  8 12 12 14
7691                           8  8 12  8 12 12 14
7692                           8  8 12  8 12 12 14
7693                          16 16 24 16 24 24 28)
7694
7695         test_mkdir "$dir"
7696         for perm in ${perms[*]}; do
7697                 touch "$dir/$tfile.$perm"
7698                 chmod $perm "$dir/$tfile.$perm"
7699         done
7700
7701         for ((i = 0; i < ${#perms[*]}; i++)); do
7702                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7703                 (( $num == 1 )) ||
7704                         error "lfs find -perm ${perms[i]}:"\
7705                               "$num != 1"
7706
7707                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7708                 (( $num == ${perm_minus[i]} )) ||
7709                         error "lfs find -perm -${perms[i]}:"\
7710                               "$num != ${perm_minus[i]}"
7711
7712                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7713                 (( $num == ${perm_slash[i]} )) ||
7714                         error "lfs find -perm /${perms[i]}:"\
7715                               "$num != ${perm_slash[i]}"
7716         done
7717 }
7718 run_test 56aca "check lfs find -perm with octal representation"
7719
7720 test_56acb() {
7721         local dir=$DIR/$tdir
7722         # p is the permission of write and execute for user, group and other
7723         # without the umask. It is used to test +wx.
7724         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7725         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7726         local symbolic=(+t  a+t u+t g+t o+t
7727                         g+s u+s o+s +s o+sr
7728                         o=r,ug+o,u+w
7729                         u+ g+ o+ a+ ugo+
7730                         u- g- o- a- ugo-
7731                         u= g= o= a= ugo=
7732                         o=r,ug+o,u+w u=r,a+u,u+w
7733                         g=r,ugo=g,u+w u+x,+X +X
7734                         u+x,u+X u+X u+x,g+X o+r,+X
7735                         u+x,go+X +wx +rwx)
7736
7737         test_mkdir $dir
7738         for perm in ${perms[*]}; do
7739                 touch "$dir/$tfile.$perm"
7740                 chmod $perm "$dir/$tfile.$perm"
7741         done
7742
7743         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7744                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7745
7746                 (( $num == 1 )) ||
7747                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7748         done
7749 }
7750 run_test 56acb "check lfs find -perm with symbolic representation"
7751
7752 test_56acc() {
7753         local dir=$DIR/$tdir
7754         local tests="17777 787 789 abcd
7755                 ug=uu ug=a ug=gu uo=ou urw
7756                 u+xg+x a=r,u+x,"
7757
7758         test_mkdir $dir
7759         for err in $tests; do
7760                 if $LFS find $dir -perm $err 2>/dev/null; then
7761                         error "lfs find -perm $err: parsing should have failed"
7762                 fi
7763         done
7764 }
7765 run_test 56acc "check parsing error for lfs find -perm"
7766
7767 test_56ba() {
7768         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7769                 skip "Need MDS version at least 2.10.50"
7770
7771         # Create composite files with one component
7772         local dir=$DIR/$tdir
7773
7774         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7775         # Create composite files with three components
7776         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7777         # Create non-composite files
7778         createmany -o $dir/${tfile}- 10
7779
7780         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7781
7782         [[ $nfiles == 10 ]] ||
7783                 error "lfs find -E 1M found $nfiles != 10 files"
7784
7785         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7786         [[ $nfiles == 25 ]] ||
7787                 error "lfs find ! -E 1M found $nfiles != 25 files"
7788
7789         # All files have a component that starts at 0
7790         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7791         [[ $nfiles == 35 ]] ||
7792                 error "lfs find --component-start 0 - $nfiles != 35 files"
7793
7794         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7795         [[ $nfiles == 15 ]] ||
7796                 error "lfs find --component-start 2M - $nfiles != 15 files"
7797
7798         # All files created here have a componenet that does not starts at 2M
7799         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7800         [[ $nfiles == 35 ]] ||
7801                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7802
7803         # Find files with a specified number of components
7804         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7805         [[ $nfiles == 15 ]] ||
7806                 error "lfs find --component-count 3 - $nfiles != 15 files"
7807
7808         # Remember non-composite files have a component count of zero
7809         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7810         [[ $nfiles == 10 ]] ||
7811                 error "lfs find --component-count 0 - $nfiles != 10 files"
7812
7813         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7814         [[ $nfiles == 20 ]] ||
7815                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7816
7817         # All files have a flag called "init"
7818         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7819         [[ $nfiles == 35 ]] ||
7820                 error "lfs find --component-flags init - $nfiles != 35 files"
7821
7822         # Multi-component files will have a component not initialized
7823         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7824         [[ $nfiles == 15 ]] ||
7825                 error "lfs find !--component-flags init - $nfiles != 15 files"
7826
7827         rm -rf $dir
7828
7829 }
7830 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7831
7832 test_56ca() {
7833         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7834                 skip "Need MDS version at least 2.10.57"
7835
7836         local td=$DIR/$tdir
7837         local tf=$td/$tfile
7838         local dir
7839         local nfiles
7840         local cmd
7841         local i
7842         local j
7843
7844         # create mirrored directories and mirrored files
7845         mkdir $td || error "mkdir $td failed"
7846         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7847         createmany -o $tf- 10 || error "create $tf- failed"
7848
7849         for i in $(seq 2); do
7850                 dir=$td/dir$i
7851                 mkdir $dir || error "mkdir $dir failed"
7852                 $LFS mirror create -N$((3 + i)) $dir ||
7853                         error "create mirrored dir $dir failed"
7854                 createmany -o $dir/$tfile- 10 ||
7855                         error "create $dir/$tfile- failed"
7856         done
7857
7858         # change the states of some mirrored files
7859         echo foo > $tf-6
7860         for i in $(seq 2); do
7861                 dir=$td/dir$i
7862                 for j in $(seq 4 9); do
7863                         echo foo > $dir/$tfile-$j
7864                 done
7865         done
7866
7867         # find mirrored files with specific mirror count
7868         cmd="$LFS find --mirror-count 3 --type f $td"
7869         nfiles=$($cmd | wc -l)
7870         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7871
7872         cmd="$LFS find ! --mirror-count 3 --type f $td"
7873         nfiles=$($cmd | wc -l)
7874         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7875
7876         cmd="$LFS find --mirror-count +2 --type f $td"
7877         nfiles=$($cmd | wc -l)
7878         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7879
7880         cmd="$LFS find --mirror-count -6 --type f $td"
7881         nfiles=$($cmd | wc -l)
7882         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7883
7884         # find mirrored files with specific file state
7885         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7886         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7887
7888         cmd="$LFS find --mirror-state=ro --type f $td"
7889         nfiles=$($cmd | wc -l)
7890         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7891
7892         cmd="$LFS find ! --mirror-state=ro --type f $td"
7893         nfiles=$($cmd | wc -l)
7894         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7895
7896         cmd="$LFS find --mirror-state=wp --type f $td"
7897         nfiles=$($cmd | wc -l)
7898         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7899
7900         cmd="$LFS find ! --mirror-state=sp --type f $td"
7901         nfiles=$($cmd | wc -l)
7902         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7903 }
7904 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7905
7906 test_56da() { # LU-14179
7907         local path=$DIR/$tdir
7908
7909         test_mkdir $path
7910         cd $path
7911
7912         local longdir=$(str_repeat 'a' 255)
7913
7914         for i in {1..15}; do
7915                 path=$path/$longdir
7916                 test_mkdir $longdir
7917                 cd $longdir
7918         done
7919
7920         local len=${#path}
7921         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7922
7923         test_mkdir $lastdir
7924         cd $lastdir
7925         # PATH_MAX-1
7926         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7927
7928         # NAME_MAX
7929         touch $(str_repeat 'f' 255)
7930
7931         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7932                 error "lfs find reported an error"
7933
7934         rm -rf $DIR/$tdir
7935 }
7936 run_test 56da "test lfs find with long paths"
7937
7938 test_57a() {
7939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7940         # note test will not do anything if MDS is not local
7941         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7942                 skip_env "ldiskfs only test"
7943         fi
7944         remote_mds_nodsh && skip "remote MDS with nodsh"
7945
7946         local MNTDEV="osd*.*MDT*.mntdev"
7947         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7948         [ -z "$DEV" ] && error "can't access $MNTDEV"
7949         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7950                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7951                         error "can't access $DEV"
7952                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7953                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7954                 rm $TMP/t57a.dump
7955         done
7956 }
7957 run_test 57a "verify MDS filesystem created with large inodes =="
7958
7959 test_57b() {
7960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7961         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7962                 skip_env "ldiskfs only test"
7963         fi
7964         remote_mds_nodsh && skip "remote MDS with nodsh"
7965
7966         local dir=$DIR/$tdir
7967         local filecount=100
7968         local file1=$dir/f1
7969         local fileN=$dir/f$filecount
7970
7971         rm -rf $dir || error "removing $dir"
7972         test_mkdir -c1 $dir
7973         local mdtidx=$($LFS getstripe -m $dir)
7974         local mdtname=MDT$(printf %04x $mdtidx)
7975         local facet=mds$((mdtidx + 1))
7976
7977         echo "mcreating $filecount files"
7978         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7979
7980         # verify that files do not have EAs yet
7981         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7982                 error "$file1 has an EA"
7983         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7984                 error "$fileN has an EA"
7985
7986         sync
7987         sleep 1
7988         df $dir  #make sure we get new statfs data
7989         local mdsfree=$(do_facet $facet \
7990                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7991         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7992         local file
7993
7994         echo "opening files to create objects/EAs"
7995         for file in $(seq -f $dir/f%g 1 $filecount); do
7996                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7997                         error "opening $file"
7998         done
7999
8000         # verify that files have EAs now
8001         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8002         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8003
8004         sleep 1  #make sure we get new statfs data
8005         df $dir
8006         local mdsfree2=$(do_facet $facet \
8007                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8008         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8009
8010         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8011                 if [ "$mdsfree" != "$mdsfree2" ]; then
8012                         error "MDC before $mdcfree != after $mdcfree2"
8013                 else
8014                         echo "MDC before $mdcfree != after $mdcfree2"
8015                         echo "unable to confirm if MDS has large inodes"
8016                 fi
8017         fi
8018         rm -rf $dir
8019 }
8020 run_test 57b "default LOV EAs are stored inside large inodes ==="
8021
8022 test_58() {
8023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8024         [ -z "$(which wiretest 2>/dev/null)" ] &&
8025                         skip_env "could not find wiretest"
8026
8027         wiretest
8028 }
8029 run_test 58 "verify cross-platform wire constants =============="
8030
8031 test_59() {
8032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8033
8034         echo "touch 130 files"
8035         createmany -o $DIR/f59- 130
8036         echo "rm 130 files"
8037         unlinkmany $DIR/f59- 130
8038         sync
8039         # wait for commitment of removal
8040         wait_delete_completed
8041 }
8042 run_test 59 "verify cancellation of llog records async ========="
8043
8044 TEST60_HEAD="test_60 run $RANDOM"
8045 test_60a() {
8046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8047         remote_mgs_nodsh && skip "remote MGS with nodsh"
8048         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8049                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8050                         skip_env "missing subtest run-llog.sh"
8051
8052         log "$TEST60_HEAD - from kernel mode"
8053         do_facet mgs "$LCTL dk > /dev/null"
8054         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8055         do_facet mgs $LCTL dk > $TMP/$tfile
8056
8057         # LU-6388: test llog_reader
8058         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8059         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8060         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8061                         skip_env "missing llog_reader"
8062         local fstype=$(facet_fstype mgs)
8063         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8064                 skip_env "Only for ldiskfs or zfs type mgs"
8065
8066         local mntpt=$(facet_mntpt mgs)
8067         local mgsdev=$(mgsdevname 1)
8068         local fid_list
8069         local fid
8070         local rec_list
8071         local rec
8072         local rec_type
8073         local obj_file
8074         local path
8075         local seq
8076         local oid
8077         local pass=true
8078
8079         #get fid and record list
8080         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8081                 tail -n 4))
8082         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8083                 tail -n 4))
8084         #remount mgs as ldiskfs or zfs type
8085         stop mgs || error "stop mgs failed"
8086         mount_fstype mgs || error "remount mgs failed"
8087         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8088                 fid=${fid_list[i]}
8089                 rec=${rec_list[i]}
8090                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8091                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8092                 oid=$((16#$oid))
8093
8094                 case $fstype in
8095                         ldiskfs )
8096                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8097                         zfs )
8098                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8099                 esac
8100                 echo "obj_file is $obj_file"
8101                 do_facet mgs $llog_reader $obj_file
8102
8103                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8104                         awk '{ print $3 }' | sed -e "s/^type=//g")
8105                 if [ $rec_type != $rec ]; then
8106                         echo "FAILED test_60a wrong record type $rec_type," \
8107                               "should be $rec"
8108                         pass=false
8109                         break
8110                 fi
8111
8112                 #check obj path if record type is LLOG_LOGID_MAGIC
8113                 if [ "$rec" == "1064553b" ]; then
8114                         path=$(do_facet mgs $llog_reader $obj_file |
8115                                 grep "path=" | awk '{ print $NF }' |
8116                                 sed -e "s/^path=//g")
8117                         if [ $obj_file != $mntpt/$path ]; then
8118                                 echo "FAILED test_60a wrong obj path" \
8119                                       "$montpt/$path, should be $obj_file"
8120                                 pass=false
8121                                 break
8122                         fi
8123                 fi
8124         done
8125         rm -f $TMP/$tfile
8126         #restart mgs before "error", otherwise it will block the next test
8127         stop mgs || error "stop mgs failed"
8128         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8129         $pass || error "test failed, see FAILED test_60a messages for specifics"
8130 }
8131 run_test 60a "llog_test run from kernel module and test llog_reader"
8132
8133 test_60b() { # bug 6411
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         dmesg > $DIR/$tfile
8137         LLOG_COUNT=$(do_facet mgs dmesg |
8138                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8139                           /llog_[a-z]*.c:[0-9]/ {
8140                                 if (marker)
8141                                         from_marker++
8142                                 from_begin++
8143                           }
8144                           END {
8145                                 if (marker)
8146                                         print from_marker
8147                                 else
8148                                         print from_begin
8149                           }")
8150
8151         [[ $LLOG_COUNT -gt 120 ]] &&
8152                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8153 }
8154 run_test 60b "limit repeated messages from CERROR/CWARN"
8155
8156 test_60c() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158
8159         echo "create 5000 files"
8160         createmany -o $DIR/f60c- 5000
8161 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8162         lctl set_param fail_loc=0x80000137
8163         unlinkmany $DIR/f60c- 5000
8164         lctl set_param fail_loc=0
8165 }
8166 run_test 60c "unlink file when mds full"
8167
8168 test_60d() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         SAVEPRINTK=$(lctl get_param -n printk)
8172         # verify "lctl mark" is even working"
8173         MESSAGE="test message ID $RANDOM $$"
8174         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8175         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8176
8177         lctl set_param printk=0 || error "set lnet.printk failed"
8178         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8179         MESSAGE="new test message ID $RANDOM $$"
8180         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8181         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8182         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8183
8184         lctl set_param -n printk="$SAVEPRINTK"
8185 }
8186 run_test 60d "test printk console message masking"
8187
8188 test_60e() {
8189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8190         remote_mds_nodsh && skip "remote MDS with nodsh"
8191
8192         touch $DIR/$tfile
8193 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8194         do_facet mds1 lctl set_param fail_loc=0x15b
8195         rm $DIR/$tfile
8196 }
8197 run_test 60e "no space while new llog is being created"
8198
8199 test_60f() {
8200         local old_path=$($LCTL get_param -n debug_path)
8201
8202         stack_trap "$LCTL set_param debug_path=$old_path"
8203         stack_trap "rm -f $TMP/$tfile*"
8204         rm -f $TMP/$tfile* 2> /dev/null
8205         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8206         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8207         test_mkdir $DIR/$tdir
8208         # retry in case the open is cached and not released
8209         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8210                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8211                 sleep 0.1
8212         done
8213         ls $TMP/$tfile*
8214         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8215 }
8216 run_test 60f "change debug_path works"
8217
8218 test_60g() {
8219         local pid
8220         local i
8221
8222         test_mkdir -c $MDSCOUNT $DIR/$tdir
8223
8224         (
8225                 local index=0
8226                 while true; do
8227                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8228                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8229                                 2>/dev/null
8230                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8231                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8232                         index=$((index + 1))
8233                 done
8234         ) &
8235
8236         pid=$!
8237
8238         for i in {0..100}; do
8239                 # define OBD_FAIL_OSD_TXN_START    0x19a
8240                 local index=$((i % MDSCOUNT + 1))
8241
8242                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8243                         > /dev/null
8244                 sleep 0.01
8245         done
8246
8247         kill -9 $pid
8248
8249         for i in $(seq $MDSCOUNT); do
8250                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8251         done
8252
8253         mkdir $DIR/$tdir/new || error "mkdir failed"
8254         rmdir $DIR/$tdir/new || error "rmdir failed"
8255
8256         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8257                 -t namespace
8258         for i in $(seq $MDSCOUNT); do
8259                 wait_update_facet mds$i "$LCTL get_param -n \
8260                         mdd.$(facet_svc mds$i).lfsck_namespace |
8261                         awk '/^status/ { print \\\$2 }'" "completed"
8262         done
8263
8264         ls -R $DIR/$tdir || error "ls failed"
8265         rm -rf $DIR/$tdir || error "rmdir failed"
8266 }
8267 run_test 60g "transaction abort won't cause MDT hung"
8268
8269 test_60h() {
8270         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8271                 skip "Need MDS version at least 2.12.52"
8272         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8273
8274         local f
8275
8276         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8277         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8278         for fail_loc in 0x80000188 0x80000189; do
8279                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8280                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8281                         error "mkdir $dir-$fail_loc failed"
8282                 for i in {0..10}; do
8283                         # create may fail on missing stripe
8284                         echo $i > $DIR/$tdir-$fail_loc/$i
8285                 done
8286                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8287                         error "getdirstripe $tdir-$fail_loc failed"
8288                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8289                         error "migrate $tdir-$fail_loc failed"
8290                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8291                         error "getdirstripe $tdir-$fail_loc failed"
8292                 pushd $DIR/$tdir-$fail_loc
8293                 for f in *; do
8294                         echo $f | cmp $f - || error "$f data mismatch"
8295                 done
8296                 popd
8297                 rm -rf $DIR/$tdir-$fail_loc
8298         done
8299 }
8300 run_test 60h "striped directory with missing stripes can be accessed"
8301
8302 function t60i_load() {
8303         mkdir $DIR/$tdir
8304         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8305         $LCTL set_param fail_loc=0x131c fail_val=1
8306         for ((i=0; i<5000; i++)); do
8307                 touch $DIR/$tdir/f$i
8308         done
8309 }
8310
8311 test_60i() {
8312         changelog_register || error "changelog_register failed"
8313         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8314         changelog_users $SINGLEMDS | grep -q $cl_user ||
8315                 error "User $cl_user not found in changelog_users"
8316         changelog_chmask "ALL"
8317         t60i_load &
8318         local PID=$!
8319         for((i=0; i<100; i++)); do
8320                 changelog_dump >/dev/null ||
8321                         error "can't read changelog"
8322         done
8323         kill $PID
8324         wait $PID
8325         changelog_deregister || error "changelog_deregister failed"
8326         $LCTL set_param fail_loc=0
8327 }
8328 run_test 60i "llog: new record vs reader race"
8329
8330 test_61a() {
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332
8333         f="$DIR/f61"
8334         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8335         cancel_lru_locks osc
8336         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8337         sync
8338 }
8339 run_test 61a "mmap() writes don't make sync hang ================"
8340
8341 test_61b() {
8342         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8343 }
8344 run_test 61b "mmap() of unstriped file is successful"
8345
8346 # bug 2330 - insufficient obd_match error checking causes LBUG
8347 test_62() {
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         f="$DIR/f62"
8351         echo foo > $f
8352         cancel_lru_locks osc
8353         lctl set_param fail_loc=0x405
8354         cat $f && error "cat succeeded, expect -EIO"
8355         lctl set_param fail_loc=0
8356 }
8357 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8358 # match every page all of the time.
8359 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8360
8361 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8362 # Though this test is irrelevant anymore, it helped to reveal some
8363 # other grant bugs (LU-4482), let's keep it.
8364 test_63a() {   # was test_63
8365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8366
8367         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8368
8369         for i in `seq 10` ; do
8370                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8371                 sleep 5
8372                 kill $!
8373                 sleep 1
8374         done
8375
8376         rm -f $DIR/f63 || true
8377 }
8378 run_test 63a "Verify oig_wait interruption does not crash ======="
8379
8380 # bug 2248 - async write errors didn't return to application on sync
8381 # bug 3677 - async write errors left page locked
8382 test_63b() {
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384
8385         debugsave
8386         lctl set_param debug=-1
8387
8388         # ensure we have a grant to do async writes
8389         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8390         rm $DIR/$tfile
8391
8392         sync    # sync lest earlier test intercept the fail_loc
8393
8394         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8395         lctl set_param fail_loc=0x80000406
8396         $MULTIOP $DIR/$tfile Owy && \
8397                 error "sync didn't return ENOMEM"
8398         sync; sleep 2; sync     # do a real sync this time to flush page
8399         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8400                 error "locked page left in cache after async error" || true
8401         debugrestore
8402 }
8403 run_test 63b "async write errors should be returned to fsync ==="
8404
8405 test_64a () {
8406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8407
8408         lfs df $DIR
8409         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8410 }
8411 run_test 64a "verify filter grant calculations (in kernel) ====="
8412
8413 test_64b () {
8414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8415
8416         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8417 }
8418 run_test 64b "check out-of-space detection on client"
8419
8420 test_64c() {
8421         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8422 }
8423 run_test 64c "verify grant shrink"
8424
8425 import_param() {
8426         local tgt=$1
8427         local param=$2
8428
8429         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8430 }
8431
8432 # this does exactly what osc_request.c:osc_announce_cached() does in
8433 # order to calculate max amount of grants to ask from server
8434 want_grant() {
8435         local tgt=$1
8436
8437         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8438         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8439
8440         ((rpc_in_flight++));
8441         nrpages=$((nrpages * rpc_in_flight))
8442
8443         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8444
8445         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8446
8447         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8448         local undirty=$((nrpages * PAGE_SIZE))
8449
8450         local max_extent_pages
8451         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8452         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8453         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8454         local grant_extent_tax
8455         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8456
8457         undirty=$((undirty + nrextents * grant_extent_tax))
8458
8459         echo $undirty
8460 }
8461
8462 # this is size of unit for grant allocation. It should be equal to
8463 # what tgt_grant.c:tgt_grant_chunk() calculates
8464 grant_chunk() {
8465         local tgt=$1
8466         local max_brw_size
8467         local grant_extent_tax
8468
8469         max_brw_size=$(import_param $tgt max_brw_size)
8470
8471         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8472
8473         echo $(((max_brw_size + grant_extent_tax) * 2))
8474 }
8475
8476 test_64d() {
8477         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8478                 skip "OST < 2.10.55 doesn't limit grants enough"
8479
8480         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8481
8482         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8483                 skip "no grant_param connect flag"
8484
8485         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8486
8487         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8488         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8489
8490
8491         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8492         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8493
8494         $LFS setstripe $DIR/$tfile -i 0 -c 1
8495         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8496         ddpid=$!
8497
8498         while kill -0 $ddpid; do
8499                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8500
8501                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8502                         kill $ddpid
8503                         error "cur_grant $cur_grant > $max_cur_granted"
8504                 fi
8505
8506                 sleep 1
8507         done
8508 }
8509 run_test 64d "check grant limit exceed"
8510
8511 check_grants() {
8512         local tgt=$1
8513         local expected=$2
8514         local msg=$3
8515         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8516
8517         ((cur_grants == expected)) ||
8518                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8519 }
8520
8521 round_up_p2() {
8522         echo $((($1 + $2 - 1) & ~($2 - 1)))
8523 }
8524
8525 test_64e() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8528                 skip "Need OSS version at least 2.11.56"
8529
8530         # Remount client to reset grant
8531         remount_client $MOUNT || error "failed to remount client"
8532         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8533
8534         local init_grants=$(import_param $osc_tgt initial_grant)
8535
8536         check_grants $osc_tgt $init_grants "init grants"
8537
8538         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8539         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8540         local gbs=$(import_param $osc_tgt grant_block_size)
8541
8542         # write random number of bytes from max_brw_size / 4 to max_brw_size
8543         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8544         # align for direct io
8545         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8546         # round to grant consumption unit
8547         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8548
8549         local grants=$((wb_round_up + extent_tax))
8550
8551         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8552
8553         # define OBD_FAIL_TGT_NO_GRANT 0x725
8554         # make the server not grant more back
8555         do_facet ost1 $LCTL set_param fail_loc=0x725
8556         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8557
8558         do_facet ost1 $LCTL set_param fail_loc=0
8559
8560         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8561
8562         rm -f $DIR/$tfile || error "rm failed"
8563
8564         # Remount client to reset grant
8565         remount_client $MOUNT || error "failed to remount client"
8566         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8567
8568         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8569
8570         # define OBD_FAIL_TGT_NO_GRANT 0x725
8571         # make the server not grant more back
8572         do_facet ost1 $LCTL set_param fail_loc=0x725
8573         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8574         do_facet ost1 $LCTL set_param fail_loc=0
8575
8576         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8577 }
8578 run_test 64e "check grant consumption (no grant allocation)"
8579
8580 test_64f() {
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         # Remount client to reset grant
8584         remount_client $MOUNT || error "failed to remount client"
8585         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8586
8587         local init_grants=$(import_param $osc_tgt initial_grant)
8588         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8589         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8590         local gbs=$(import_param $osc_tgt grant_block_size)
8591         local chunk=$(grant_chunk $osc_tgt)
8592
8593         # write random number of bytes from max_brw_size / 4 to max_brw_size
8594         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8595         # align for direct io
8596         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8597         # round to grant consumption unit
8598         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8599
8600         local grants=$((wb_round_up + extent_tax))
8601
8602         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8603         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8604                 error "error writing to $DIR/$tfile"
8605
8606         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8607                 "direct io with grant allocation"
8608
8609         rm -f $DIR/$tfile || error "rm failed"
8610
8611         # Remount client to reset grant
8612         remount_client $MOUNT || error "failed to remount client"
8613         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8614
8615         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8616
8617         local cmd="oO_WRONLY:w${write_bytes}_yc"
8618
8619         $MULTIOP $DIR/$tfile $cmd &
8620         MULTIPID=$!
8621         sleep 1
8622
8623         check_grants $osc_tgt $((init_grants - grants)) \
8624                 "buffered io, not write rpc"
8625
8626         kill -USR1 $MULTIPID
8627         wait
8628
8629         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8630                 "buffered io, one RPC"
8631 }
8632 run_test 64f "check grant consumption (with grant allocation)"
8633
8634 # bug 1414 - set/get directories' stripe info
8635 test_65a() {
8636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8637
8638         test_mkdir $DIR/$tdir
8639         touch $DIR/$tdir/f1
8640         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8641 }
8642 run_test 65a "directory with no stripe info"
8643
8644 test_65b() {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646
8647         test_mkdir $DIR/$tdir
8648         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8649
8650         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8651                                                 error "setstripe"
8652         touch $DIR/$tdir/f2
8653         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8654 }
8655 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8656
8657 test_65c() {
8658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8659         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8660
8661         test_mkdir $DIR/$tdir
8662         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8663
8664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8666         touch $DIR/$tdir/f3
8667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8668 }
8669 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8670
8671 test_65d() {
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         test_mkdir $DIR/$tdir
8675         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8676         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8677
8678         if [[ $STRIPECOUNT -le 0 ]]; then
8679                 sc=1
8680         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8681                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8682                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8683         else
8684                 sc=$(($STRIPECOUNT - 1))
8685         fi
8686         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8687         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8688         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8689                 error "lverify failed"
8690 }
8691 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8692
8693 test_65e() {
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695
8696         test_mkdir $DIR/$tdir
8697
8698         $LFS setstripe $DIR/$tdir || error "setstripe"
8699         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8700                                         error "no stripe info failed"
8701         touch $DIR/$tdir/f6
8702         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8703 }
8704 run_test 65e "directory setstripe defaults"
8705
8706 test_65f() {
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         test_mkdir $DIR/${tdir}f
8710         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8711                 error "setstripe succeeded" || true
8712 }
8713 run_test 65f "dir setstripe permission (should return error) ==="
8714
8715 test_65g() {
8716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8717
8718         test_mkdir $DIR/$tdir
8719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8720
8721         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8722                 error "setstripe -S failed"
8723         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8724         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8725                 error "delete default stripe failed"
8726 }
8727 run_test 65g "directory setstripe -d"
8728
8729 test_65h() {
8730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8731
8732         test_mkdir $DIR/$tdir
8733         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8734
8735         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8736                 error "setstripe -S failed"
8737         test_mkdir $DIR/$tdir/dd1
8738         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8739                 error "stripe info inherit failed"
8740 }
8741 run_test 65h "directory stripe info inherit ===================="
8742
8743 test_65i() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745
8746         save_layout_restore_at_exit $MOUNT
8747
8748         # bug6367: set non-default striping on root directory
8749         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8750
8751         # bug12836: getstripe on -1 default directory striping
8752         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8753
8754         # bug12836: getstripe -v on -1 default directory striping
8755         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8756
8757         # bug12836: new find on -1 default directory striping
8758         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8759 }
8760 run_test 65i "various tests to set root directory striping"
8761
8762 test_65j() { # bug6367
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764
8765         sync; sleep 1
8766
8767         # if we aren't already remounting for each test, do so for this test
8768         if [ "$I_MOUNTED" = "yes" ]; then
8769                 cleanup || error "failed to unmount"
8770                 setup
8771         fi
8772
8773         save_layout_restore_at_exit $MOUNT
8774
8775         $LFS setstripe -d $MOUNT || error "setstripe failed"
8776 }
8777 run_test 65j "set default striping on root directory (bug 6367)="
8778
8779 cleanup_65k() {
8780         rm -rf $DIR/$tdir
8781         wait_delete_completed
8782         do_facet $SINGLEMDS "lctl set_param -n \
8783                 osp.$ost*MDT0000.max_create_count=$max_count"
8784         do_facet $SINGLEMDS "lctl set_param -n \
8785                 osp.$ost*MDT0000.create_count=$count"
8786         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8787         echo $INACTIVE_OSC "is Activate"
8788
8789         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8790 }
8791
8792 test_65k() { # bug11679
8793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8795         remote_mds_nodsh && skip "remote MDS with nodsh"
8796
8797         local disable_precreate=true
8798         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8799                 disable_precreate=false
8800
8801         echo "Check OST status: "
8802         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8803                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8804
8805         for OSC in $MDS_OSCS; do
8806                 echo $OSC "is active"
8807                 do_facet $SINGLEMDS lctl --device %$OSC activate
8808         done
8809
8810         for INACTIVE_OSC in $MDS_OSCS; do
8811                 local ost=$(osc_to_ost $INACTIVE_OSC)
8812                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8813                                lov.*md*.target_obd |
8814                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8815
8816                 mkdir -p $DIR/$tdir
8817                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8818                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8819
8820                 echo "Deactivate: " $INACTIVE_OSC
8821                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8822
8823                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8824                               osp.$ost*MDT0000.create_count")
8825                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8826                                   osp.$ost*MDT0000.max_create_count")
8827                 $disable_precreate &&
8828                         do_facet $SINGLEMDS "lctl set_param -n \
8829                                 osp.$ost*MDT0000.max_create_count=0"
8830
8831                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8832                         [ -f $DIR/$tdir/$idx ] && continue
8833                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8834                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8835                                 { cleanup_65k;
8836                                   error "setstripe $idx should succeed"; }
8837                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8838                 done
8839                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8840                 rmdir $DIR/$tdir
8841
8842                 do_facet $SINGLEMDS "lctl set_param -n \
8843                         osp.$ost*MDT0000.max_create_count=$max_count"
8844                 do_facet $SINGLEMDS "lctl set_param -n \
8845                         osp.$ost*MDT0000.create_count=$count"
8846                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8847                 echo $INACTIVE_OSC "is Activate"
8848
8849                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8850         done
8851 }
8852 run_test 65k "validate manual striping works properly with deactivated OSCs"
8853
8854 test_65l() { # bug 12836
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856
8857         test_mkdir -p $DIR/$tdir/test_dir
8858         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8859         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8860 }
8861 run_test 65l "lfs find on -1 stripe dir ========================"
8862
8863 test_65m() {
8864         local layout=$(save_layout $MOUNT)
8865         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8866                 restore_layout $MOUNT $layout
8867                 error "setstripe should fail by non-root users"
8868         }
8869         true
8870 }
8871 run_test 65m "normal user can't set filesystem default stripe"
8872
8873 test_65n() {
8874         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8875         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8876                 skip "Need MDS version at least 2.12.50"
8877         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8878
8879         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8880         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8881         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8882
8883         save_layout_restore_at_exit $MOUNT
8884
8885         # new subdirectory under root directory should not inherit
8886         # the default layout from root
8887         local dir1=$MOUNT/$tdir-1
8888         mkdir $dir1 || error "mkdir $dir1 failed"
8889         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8890                 error "$dir1 shouldn't have LOV EA"
8891
8892         # delete the default layout on root directory
8893         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8894
8895         local dir2=$MOUNT/$tdir-2
8896         mkdir $dir2 || error "mkdir $dir2 failed"
8897         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8898                 error "$dir2 shouldn't have LOV EA"
8899
8900         # set a new striping pattern on root directory
8901         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8902         local new_def_stripe_size=$((def_stripe_size * 2))
8903         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8904                 error "set stripe size on $MOUNT failed"
8905
8906         # new file created in $dir2 should inherit the new stripe size from
8907         # the filesystem default
8908         local file2=$dir2/$tfile-2
8909         touch $file2 || error "touch $file2 failed"
8910
8911         local file2_stripe_size=$($LFS getstripe -S $file2)
8912         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8913         {
8914                 echo "file2_stripe_size: '$file2_stripe_size'"
8915                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8916                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8917         }
8918
8919         local dir3=$MOUNT/$tdir-3
8920         mkdir $dir3 || error "mkdir $dir3 failed"
8921         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8922         # the root layout, which is the actual default layout that will be used
8923         # when new files are created in $dir3.
8924         local dir3_layout=$(get_layout_param $dir3)
8925         local root_dir_layout=$(get_layout_param $MOUNT)
8926         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8927         {
8928                 echo "dir3_layout: '$dir3_layout'"
8929                 echo "root_dir_layout: '$root_dir_layout'"
8930                 error "$dir3 should show the default layout from $MOUNT"
8931         }
8932
8933         # set OST pool on root directory
8934         local pool=$TESTNAME
8935         pool_add $pool || error "add $pool failed"
8936         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8937                 error "add targets to $pool failed"
8938
8939         $LFS setstripe -p $pool $MOUNT ||
8940                 error "set OST pool on $MOUNT failed"
8941
8942         # new file created in $dir3 should inherit the pool from
8943         # the filesystem default
8944         local file3=$dir3/$tfile-3
8945         touch $file3 || error "touch $file3 failed"
8946
8947         local file3_pool=$($LFS getstripe -p $file3)
8948         [[ "$file3_pool" = "$pool" ]] ||
8949                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8950
8951         local dir4=$MOUNT/$tdir-4
8952         mkdir $dir4 || error "mkdir $dir4 failed"
8953         local dir4_layout=$(get_layout_param $dir4)
8954         root_dir_layout=$(get_layout_param $MOUNT)
8955         echo "$LFS getstripe -d $dir4"
8956         $LFS getstripe -d $dir4
8957         echo "$LFS getstripe -d $MOUNT"
8958         $LFS getstripe -d $MOUNT
8959         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8960         {
8961                 echo "dir4_layout: '$dir4_layout'"
8962                 echo "root_dir_layout: '$root_dir_layout'"
8963                 error "$dir4 should show the default layout from $MOUNT"
8964         }
8965
8966         # new file created in $dir4 should inherit the pool from
8967         # the filesystem default
8968         local file4=$dir4/$tfile-4
8969         touch $file4 || error "touch $file4 failed"
8970
8971         local file4_pool=$($LFS getstripe -p $file4)
8972         [[ "$file4_pool" = "$pool" ]] ||
8973                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8974
8975         # new subdirectory under non-root directory should inherit
8976         # the default layout from its parent directory
8977         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8978                 error "set directory layout on $dir4 failed"
8979
8980         local dir5=$dir4/$tdir-5
8981         mkdir $dir5 || error "mkdir $dir5 failed"
8982
8983         dir4_layout=$(get_layout_param $dir4)
8984         local dir5_layout=$(get_layout_param $dir5)
8985         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8986         {
8987                 echo "dir4_layout: '$dir4_layout'"
8988                 echo "dir5_layout: '$dir5_layout'"
8989                 error "$dir5 should inherit the default layout from $dir4"
8990         }
8991
8992         # though subdir under ROOT doesn't inherit default layout, but
8993         # its sub dir/file should be created with default layout.
8994         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8995         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8996                 skip "Need MDS version at least 2.12.59"
8997
8998         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8999         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9000         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9001
9002         if [ $default_lmv_hash == "none" ]; then
9003                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9004         else
9005                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9006                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9007         fi
9008
9009         $LFS setdirstripe -D -c 2 $MOUNT ||
9010                 error "setdirstripe -D -c 2 failed"
9011         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9012         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9013         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9014 }
9015 run_test 65n "don't inherit default layout from root for new subdirectories"
9016
9017 # bug 2543 - update blocks count on client
9018 test_66() {
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020
9021         COUNT=${COUNT:-8}
9022         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9023         sync; sync_all_data; sync; sync_all_data
9024         cancel_lru_locks osc
9025         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9026         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9027 }
9028 run_test 66 "update inode blocks count on client ==============="
9029
9030 meminfo() {
9031         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9032 }
9033
9034 swap_used() {
9035         swapon -s | awk '($1 == "'$1'") { print $4 }'
9036 }
9037
9038 # bug5265, obdfilter oa2dentry return -ENOENT
9039 # #define OBD_FAIL_SRV_ENOENT 0x217
9040 test_69() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         remote_ost_nodsh && skip "remote OST with nodsh"
9043
9044         f="$DIR/$tfile"
9045         $LFS setstripe -c 1 -i 0 $f
9046
9047         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9048
9049         do_facet ost1 lctl set_param fail_loc=0x217
9050         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9051         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9052
9053         do_facet ost1 lctl set_param fail_loc=0
9054         $DIRECTIO write $f 0 2 || error "write error"
9055
9056         cancel_lru_locks osc
9057         $DIRECTIO read $f 0 1 || error "read error"
9058
9059         do_facet ost1 lctl set_param fail_loc=0x217
9060         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9061
9062         do_facet ost1 lctl set_param fail_loc=0
9063         rm -f $f
9064 }
9065 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9066
9067 test_71() {
9068         test_mkdir $DIR/$tdir
9069         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9070         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9071 }
9072 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9073
9074 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9076         [ "$RUNAS_ID" = "$UID" ] &&
9077                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9078         # Check that testing environment is properly set up. Skip if not
9079         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9080                 skip_env "User $RUNAS_ID does not exist - skipping"
9081
9082         touch $DIR/$tfile
9083         chmod 777 $DIR/$tfile
9084         chmod ug+s $DIR/$tfile
9085         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9086                 error "$RUNAS dd $DIR/$tfile failed"
9087         # See if we are still setuid/sgid
9088         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9089                 error "S/gid is not dropped on write"
9090         # Now test that MDS is updated too
9091         cancel_lru_locks mdc
9092         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9093                 error "S/gid is not dropped on MDS"
9094         rm -f $DIR/$tfile
9095 }
9096 run_test 72a "Test that remove suid works properly (bug5695) ===="
9097
9098 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9099         local perm
9100
9101         [ "$RUNAS_ID" = "$UID" ] &&
9102                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9103         [ "$RUNAS_ID" -eq 0 ] &&
9104                 skip_env "RUNAS_ID = 0 -- skipping"
9105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9106         # Check that testing environment is properly set up. Skip if not
9107         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9108                 skip_env "User $RUNAS_ID does not exist - skipping"
9109
9110         touch $DIR/${tfile}-f{g,u}
9111         test_mkdir $DIR/${tfile}-dg
9112         test_mkdir $DIR/${tfile}-du
9113         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9114         chmod g+s $DIR/${tfile}-{f,d}g
9115         chmod u+s $DIR/${tfile}-{f,d}u
9116         for perm in 777 2777 4777; do
9117                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9118                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9119                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9120                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9121         done
9122         true
9123 }
9124 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9125
9126 # bug 3462 - multiple simultaneous MDC requests
9127 test_73() {
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129
9130         test_mkdir $DIR/d73-1
9131         test_mkdir $DIR/d73-2
9132         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9133         pid1=$!
9134
9135         lctl set_param fail_loc=0x80000129
9136         $MULTIOP $DIR/d73-1/f73-2 Oc &
9137         sleep 1
9138         lctl set_param fail_loc=0
9139
9140         $MULTIOP $DIR/d73-2/f73-3 Oc &
9141         pid3=$!
9142
9143         kill -USR1 $pid1
9144         wait $pid1 || return 1
9145
9146         sleep 25
9147
9148         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9149         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9150         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9151
9152         rm -rf $DIR/d73-*
9153 }
9154 run_test 73 "multiple MDC requests (should not deadlock)"
9155
9156 test_74a() { # bug 6149, 6184
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158
9159         touch $DIR/f74a
9160         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9161         #
9162         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9163         # will spin in a tight reconnection loop
9164         $LCTL set_param fail_loc=0x8000030e
9165         # get any lock that won't be difficult - lookup works.
9166         ls $DIR/f74a
9167         $LCTL set_param fail_loc=0
9168         rm -f $DIR/f74a
9169         true
9170 }
9171 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9172
9173 test_74b() { # bug 13310
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175
9176         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9177         #
9178         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9179         # will spin in a tight reconnection loop
9180         $LCTL set_param fail_loc=0x8000030e
9181         # get a "difficult" lock
9182         touch $DIR/f74b
9183         $LCTL set_param fail_loc=0
9184         rm -f $DIR/f74b
9185         true
9186 }
9187 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9188
9189 test_74c() {
9190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9191
9192         #define OBD_FAIL_LDLM_NEW_LOCK
9193         $LCTL set_param fail_loc=0x319
9194         touch $DIR/$tfile && error "touch successful"
9195         $LCTL set_param fail_loc=0
9196         true
9197 }
9198 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9199
9200 slab_lic=/sys/kernel/slab/lustre_inode_cache
9201 num_objects() {
9202         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9203         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9204                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9205 }
9206
9207 test_76a() { # Now for b=20433, added originally in b=1443
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         cancel_lru_locks osc
9211         # there may be some slab objects cached per core
9212         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9213         local before=$(num_objects)
9214         local count=$((512 * cpus))
9215         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9216         local margin=$((count / 10))
9217         if [[ -f $slab_lic/aliases ]]; then
9218                 local aliases=$(cat $slab_lic/aliases)
9219                 (( aliases > 0 )) && margin=$((margin * aliases))
9220         fi
9221
9222         echo "before slab objects: $before"
9223         for i in $(seq $count); do
9224                 touch $DIR/$tfile
9225                 rm -f $DIR/$tfile
9226         done
9227         cancel_lru_locks osc
9228         local after=$(num_objects)
9229         echo "created: $count, after slab objects: $after"
9230         # shared slab counts are not very accurate, allow significant margin
9231         # the main goal is that the cache growth is not permanently > $count
9232         while (( after > before + margin )); do
9233                 sleep 1
9234                 after=$(num_objects)
9235                 wait=$((wait + 1))
9236                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9237                 if (( wait > 60 )); then
9238                         error "inode slab grew from $before+$margin to $after"
9239                 fi
9240         done
9241 }
9242 run_test 76a "confirm clients recycle inodes properly ===="
9243
9244 test_76b() {
9245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9246         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9247
9248         local count=512
9249         local before=$(num_objects)
9250
9251         for i in $(seq $count); do
9252                 mkdir $DIR/$tdir
9253                 rmdir $DIR/$tdir
9254         done
9255
9256         local after=$(num_objects)
9257         local wait=0
9258
9259         while (( after > before )); do
9260                 sleep 1
9261                 after=$(num_objects)
9262                 wait=$((wait + 1))
9263                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9264                 if (( wait > 60 )); then
9265                         error "inode slab grew from $before to $after"
9266                 fi
9267         done
9268
9269         echo "slab objects before: $before, after: $after"
9270 }
9271 run_test 76b "confirm clients recycle directory inodes properly ===="
9272
9273 export ORIG_CSUM=""
9274 set_checksums()
9275 {
9276         # Note: in sptlrpc modes which enable its own bulk checksum, the
9277         # original crc32_le bulk checksum will be automatically disabled,
9278         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9279         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9280         # In this case set_checksums() will not be no-op, because sptlrpc
9281         # bulk checksum will be enabled all through the test.
9282
9283         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9284         lctl set_param -n osc.*.checksums $1
9285         return 0
9286 }
9287
9288 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9289                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9290 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9291                              tr -d [] | head -n1)}
9292 set_checksum_type()
9293 {
9294         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9295         rc=$?
9296         log "set checksum type to $1, rc = $rc"
9297         return $rc
9298 }
9299
9300 get_osc_checksum_type()
9301 {
9302         # arugment 1: OST name, like OST0000
9303         ost=$1
9304         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9305                         sed 's/.*\[\(.*\)\].*/\1/g')
9306         rc=$?
9307         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9308         echo $checksum_type
9309 }
9310
9311 F77_TMP=$TMP/f77-temp
9312 F77SZ=8
9313 setup_f77() {
9314         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9315                 error "error writing to $F77_TMP"
9316 }
9317
9318 test_77a() { # bug 10889
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320         $GSS && skip_env "could not run with gss"
9321
9322         [ ! -f $F77_TMP ] && setup_f77
9323         set_checksums 1
9324         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9325         set_checksums 0
9326         rm -f $DIR/$tfile
9327 }
9328 run_test 77a "normal checksum read/write operation"
9329
9330 test_77b() { # bug 10889
9331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9332         $GSS && skip_env "could not run with gss"
9333
9334         [ ! -f $F77_TMP ] && setup_f77
9335         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9336         $LCTL set_param fail_loc=0x80000409
9337         set_checksums 1
9338
9339         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9340                 error "dd error: $?"
9341         $LCTL set_param fail_loc=0
9342
9343         for algo in $CKSUM_TYPES; do
9344                 cancel_lru_locks osc
9345                 set_checksum_type $algo
9346                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9347                 $LCTL set_param fail_loc=0x80000408
9348                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9349                 $LCTL set_param fail_loc=0
9350         done
9351         set_checksums 0
9352         set_checksum_type $ORIG_CSUM_TYPE
9353         rm -f $DIR/$tfile
9354 }
9355 run_test 77b "checksum error on client write, read"
9356
9357 cleanup_77c() {
9358         trap 0
9359         set_checksums 0
9360         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9361         $check_ost &&
9362                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9363         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9364         $check_ost && [ -n "$ost_file_prefix" ] &&
9365                 do_facet ost1 rm -f ${ost_file_prefix}\*
9366 }
9367
9368 test_77c() {
9369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9370         $GSS && skip_env "could not run with gss"
9371         remote_ost_nodsh && skip "remote OST with nodsh"
9372
9373         local bad1
9374         local osc_file_prefix
9375         local osc_file
9376         local check_ost=false
9377         local ost_file_prefix
9378         local ost_file
9379         local orig_cksum
9380         local dump_cksum
9381         local fid
9382
9383         # ensure corruption will occur on first OSS/OST
9384         $LFS setstripe -i 0 $DIR/$tfile
9385
9386         [ ! -f $F77_TMP ] && setup_f77
9387         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9388                 error "dd write error: $?"
9389         fid=$($LFS path2fid $DIR/$tfile)
9390
9391         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9392         then
9393                 check_ost=true
9394                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9395                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9396         else
9397                 echo "OSS do not support bulk pages dump upon error"
9398         fi
9399
9400         osc_file_prefix=$($LCTL get_param -n debug_path)
9401         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9402
9403         trap cleanup_77c EXIT
9404
9405         set_checksums 1
9406         # enable bulk pages dump upon error on Client
9407         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9408         # enable bulk pages dump upon error on OSS
9409         $check_ost &&
9410                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9411
9412         # flush Client cache to allow next read to reach OSS
9413         cancel_lru_locks osc
9414
9415         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9416         $LCTL set_param fail_loc=0x80000408
9417         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9418         $LCTL set_param fail_loc=0
9419
9420         rm -f $DIR/$tfile
9421
9422         # check cksum dump on Client
9423         osc_file=$(ls ${osc_file_prefix}*)
9424         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9425         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9426         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9427         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9428         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9429                      cksum)
9430         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9431         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9432                 error "dump content does not match on Client"
9433
9434         $check_ost || skip "No need to check cksum dump on OSS"
9435
9436         # check cksum dump on OSS
9437         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9438         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9439         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9440         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9441         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9442                 error "dump content does not match on OSS"
9443
9444         cleanup_77c
9445 }
9446 run_test 77c "checksum error on client read with debug"
9447
9448 test_77d() { # bug 10889
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450         $GSS && skip_env "could not run with gss"
9451
9452         stack_trap "rm -f $DIR/$tfile"
9453         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9454         $LCTL set_param fail_loc=0x80000409
9455         set_checksums 1
9456         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9457                 error "direct write: rc=$?"
9458         $LCTL set_param fail_loc=0
9459         set_checksums 0
9460
9461         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9462         $LCTL set_param fail_loc=0x80000408
9463         set_checksums 1
9464         cancel_lru_locks osc
9465         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9466                 error "direct read: rc=$?"
9467         $LCTL set_param fail_loc=0
9468         set_checksums 0
9469 }
9470 run_test 77d "checksum error on OST direct write, read"
9471
9472 test_77f() { # bug 10889
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         $GSS && skip_env "could not run with gss"
9475
9476         set_checksums 1
9477         stack_trap "rm -f $DIR/$tfile"
9478         for algo in $CKSUM_TYPES; do
9479                 cancel_lru_locks osc
9480                 set_checksum_type $algo
9481                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9482                 $LCTL set_param fail_loc=0x409
9483                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9484                         error "direct write succeeded"
9485                 $LCTL set_param fail_loc=0
9486         done
9487         set_checksum_type $ORIG_CSUM_TYPE
9488         set_checksums 0
9489 }
9490 run_test 77f "repeat checksum error on write (expect error)"
9491
9492 test_77g() { # bug 10889
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494         $GSS && skip_env "could not run with gss"
9495         remote_ost_nodsh && skip "remote OST with nodsh"
9496
9497         [ ! -f $F77_TMP ] && setup_f77
9498
9499         local file=$DIR/$tfile
9500         stack_trap "rm -f $file" EXIT
9501
9502         $LFS setstripe -c 1 -i 0 $file
9503         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9504         do_facet ost1 lctl set_param fail_loc=0x8000021a
9505         set_checksums 1
9506         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9507                 error "write error: rc=$?"
9508         do_facet ost1 lctl set_param fail_loc=0
9509         set_checksums 0
9510
9511         cancel_lru_locks osc
9512         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9513         do_facet ost1 lctl set_param fail_loc=0x8000021b
9514         set_checksums 1
9515         cmp $F77_TMP $file || error "file compare failed"
9516         do_facet ost1 lctl set_param fail_loc=0
9517         set_checksums 0
9518 }
9519 run_test 77g "checksum error on OST write, read"
9520
9521 test_77k() { # LU-10906
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523         $GSS && skip_env "could not run with gss"
9524
9525         local cksum_param="osc.$FSNAME*.checksums"
9526         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9527         local checksum
9528         local i
9529
9530         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9531         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9532         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9533
9534         for i in 0 1; do
9535                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9536                         error "failed to set checksum=$i on MGS"
9537                 wait_update $HOSTNAME "$get_checksum" $i
9538                 #remount
9539                 echo "remount client, checksum should be $i"
9540                 remount_client $MOUNT || error "failed to remount client"
9541                 checksum=$(eval $get_checksum)
9542                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9543         done
9544         # remove persistent param to avoid races with checksum mountopt below
9545         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9546                 error "failed to delete checksum on MGS"
9547
9548         for opt in "checksum" "nochecksum"; do
9549                 #remount with mount option
9550                 echo "remount client with option $opt, checksum should be $i"
9551                 umount_client $MOUNT || error "failed to umount client"
9552                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9553                         error "failed to mount client with option '$opt'"
9554                 checksum=$(eval $get_checksum)
9555                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9556                 i=$((i - 1))
9557         done
9558
9559         remount_client $MOUNT || error "failed to remount client"
9560 }
9561 run_test 77k "enable/disable checksum correctly"
9562
9563 test_77l() {
9564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9565         $GSS && skip_env "could not run with gss"
9566
9567         set_checksums 1
9568         stack_trap "set_checksums $ORIG_CSUM" EXIT
9569         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9570
9571         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9572
9573         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9574         for algo in $CKSUM_TYPES; do
9575                 set_checksum_type $algo || error "fail to set checksum type $algo"
9576                 osc_algo=$(get_osc_checksum_type OST0000)
9577                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9578
9579                 # no locks, no reqs to let the connection idle
9580                 cancel_lru_locks osc
9581                 lru_resize_disable osc
9582                 wait_osc_import_state client ost1 IDLE
9583
9584                 # ensure ost1 is connected
9585                 stat $DIR/$tfile >/dev/null || error "can't stat"
9586                 wait_osc_import_state client ost1 FULL
9587
9588                 osc_algo=$(get_osc_checksum_type OST0000)
9589                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9590         done
9591         return 0
9592 }
9593 run_test 77l "preferred checksum type is remembered after reconnected"
9594
9595 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9596 rm -f $F77_TMP
9597 unset F77_TMP
9598
9599 test_77m() {
9600         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9601                 skip "Need at least version 2.14.52"
9602         local param=checksum_speed
9603
9604         $LCTL get_param $param || error "reading $param failed"
9605
9606         csum_speeds=$($LCTL get_param -n $param)
9607
9608         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9609                 error "known checksum types are missing"
9610 }
9611 run_test 77m "Verify checksum_speed is correctly read"
9612
9613 cleanup_test_78() {
9614         trap 0
9615         rm -f $DIR/$tfile
9616 }
9617
9618 test_78() { # bug 10901
9619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9620         remote_ost || skip_env "local OST"
9621
9622         NSEQ=5
9623         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9624         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9625         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9626         echo "MemTotal: $MEMTOTAL"
9627
9628         # reserve 256MB of memory for the kernel and other running processes,
9629         # and then take 1/2 of the remaining memory for the read/write buffers.
9630         if [ $MEMTOTAL -gt 512 ] ;then
9631                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9632         else
9633                 # for those poor memory-starved high-end clusters...
9634                 MEMTOTAL=$((MEMTOTAL / 2))
9635         fi
9636         echo "Mem to use for directio: $MEMTOTAL"
9637
9638         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9639         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9640         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9641         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9642                 head -n1)
9643         echo "Smallest OST: $SMALLESTOST"
9644         [[ $SMALLESTOST -lt 10240 ]] &&
9645                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9646
9647         trap cleanup_test_78 EXIT
9648
9649         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9650                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9651
9652         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9653         echo "File size: $F78SIZE"
9654         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9655         for i in $(seq 1 $NSEQ); do
9656                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9657                 echo directIO rdwr round $i of $NSEQ
9658                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9659         done
9660
9661         cleanup_test_78
9662 }
9663 run_test 78 "handle large O_DIRECT writes correctly ============"
9664
9665 test_79() { # bug 12743
9666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9667
9668         wait_delete_completed
9669
9670         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9671         BKFREE=$(calc_osc_kbytes kbytesfree)
9672         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9673
9674         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9675         DFTOTAL=`echo $STRING | cut -d, -f1`
9676         DFUSED=`echo $STRING  | cut -d, -f2`
9677         DFAVAIL=`echo $STRING | cut -d, -f3`
9678         DFFREE=$(($DFTOTAL - $DFUSED))
9679
9680         ALLOWANCE=$((64 * $OSTCOUNT))
9681
9682         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9683            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9684                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9685         fi
9686         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9687            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9688                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9689         fi
9690         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9691            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9692                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9693         fi
9694 }
9695 run_test 79 "df report consistency check ======================="
9696
9697 test_80() { # bug 10718
9698         remote_ost_nodsh && skip "remote OST with nodsh"
9699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9700
9701         # relax strong synchronous semantics for slow backends like ZFS
9702         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9703                 local soc="obdfilter.*.sync_lock_cancel"
9704                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9705
9706                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9707                 if [ -z "$save" ]; then
9708                         soc="obdfilter.*.sync_on_lock_cancel"
9709                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9710                 fi
9711
9712                 if [ "$save" != "never" ]; then
9713                         local hosts=$(comma_list $(osts_nodes))
9714
9715                         do_nodes $hosts $LCTL set_param $soc=never
9716                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9717                 fi
9718         fi
9719
9720         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9721         sync; sleep 1; sync
9722         local before=$(date +%s)
9723         cancel_lru_locks osc
9724         local after=$(date +%s)
9725         local diff=$((after - before))
9726         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9727
9728         rm -f $DIR/$tfile
9729 }
9730 run_test 80 "Page eviction is equally fast at high offsets too"
9731
9732 test_81a() { # LU-456
9733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9734         remote_ost_nodsh && skip "remote OST with nodsh"
9735
9736         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9737         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9738         do_facet ost1 lctl set_param fail_loc=0x80000228
9739
9740         # write should trigger a retry and success
9741         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9742         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9743         RC=$?
9744         if [ $RC -ne 0 ] ; then
9745                 error "write should success, but failed for $RC"
9746         fi
9747 }
9748 run_test 81a "OST should retry write when get -ENOSPC ==============="
9749
9750 test_81b() { # LU-456
9751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9752         remote_ost_nodsh && skip "remote OST with nodsh"
9753
9754         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9755         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9756         do_facet ost1 lctl set_param fail_loc=0x228
9757
9758         # write should retry several times and return -ENOSPC finally
9759         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9760         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9761         RC=$?
9762         ENOSPC=28
9763         if [ $RC -ne $ENOSPC ] ; then
9764                 error "dd should fail for -ENOSPC, but succeed."
9765         fi
9766 }
9767 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9768
9769 test_99() {
9770         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9771
9772         test_mkdir $DIR/$tdir.cvsroot
9773         chown $RUNAS_ID $DIR/$tdir.cvsroot
9774
9775         cd $TMP
9776         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9777
9778         cd /etc/init.d
9779         # some versions of cvs import exit(1) when asked to import links or
9780         # files they can't read.  ignore those files.
9781         local toignore=$(find . -type l -printf '-I %f\n' -o \
9782                          ! -perm /4 -printf '-I %f\n')
9783         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9784                 $tdir.reposname vtag rtag
9785
9786         cd $DIR
9787         test_mkdir $DIR/$tdir.reposname
9788         chown $RUNAS_ID $DIR/$tdir.reposname
9789         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9790
9791         cd $DIR/$tdir.reposname
9792         $RUNAS touch foo99
9793         $RUNAS cvs add -m 'addmsg' foo99
9794         $RUNAS cvs update
9795         $RUNAS cvs commit -m 'nomsg' foo99
9796         rm -fr $DIR/$tdir.cvsroot
9797 }
9798 run_test 99 "cvs strange file/directory operations"
9799
9800 test_100() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802         [[ "$NETTYPE" =~ tcp ]] ||
9803                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9804         remote_ost_nodsh && skip "remote OST with nodsh"
9805         remote_mds_nodsh && skip "remote MDS with nodsh"
9806         remote_servers ||
9807                 skip "useless for local single node setup"
9808
9809         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9810                 [ "$PROT" != "tcp" ] && continue
9811                 RPORT=$(echo $REMOTE | cut -d: -f2)
9812                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9813
9814                 rc=0
9815                 LPORT=`echo $LOCAL | cut -d: -f2`
9816                 if [ $LPORT -ge 1024 ]; then
9817                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9818                         netstat -tna
9819                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9820                 fi
9821         done
9822         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9823 }
9824 run_test 100 "check local port using privileged port ==========="
9825
9826 function get_named_value()
9827 {
9828     local tag=$1
9829
9830     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9831 }
9832
9833 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9834                    awk '/^max_cached_mb/ { print $2 }')
9835
9836 cleanup_101a() {
9837         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9838         trap 0
9839 }
9840
9841 test_101a() {
9842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9843
9844         local s
9845         local discard
9846         local nreads=10000
9847         local cache_limit=32
9848
9849         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9850         trap cleanup_101a EXIT
9851         $LCTL set_param -n llite.*.read_ahead_stats=0
9852         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9853
9854         #
9855         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9856         #
9857         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9858         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9859
9860         discard=0
9861         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9862                    get_named_value 'read.but.discarded'); do
9863                         discard=$(($discard + $s))
9864         done
9865         cleanup_101a
9866
9867         $LCTL get_param osc.*-osc*.rpc_stats
9868         $LCTL get_param llite.*.read_ahead_stats
9869
9870         # Discard is generally zero, but sometimes a few random reads line up
9871         # and trigger larger readahead, which is wasted & leads to discards.
9872         if [[ $(($discard)) -gt $nreads ]]; then
9873                 error "too many ($discard) discarded pages"
9874         fi
9875         rm -f $DIR/$tfile || true
9876 }
9877 run_test 101a "check read-ahead for random reads"
9878
9879 setup_test101bc() {
9880         test_mkdir $DIR/$tdir
9881         local ssize=$1
9882         local FILE_LENGTH=$2
9883         STRIPE_OFFSET=0
9884
9885         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9886
9887         local list=$(comma_list $(osts_nodes))
9888         set_osd_param $list '' read_cache_enable 0
9889         set_osd_param $list '' writethrough_cache_enable 0
9890
9891         trap cleanup_test101bc EXIT
9892         # prepare the read-ahead file
9893         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9894
9895         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9896                                 count=$FILE_SIZE_MB 2> /dev/null
9897
9898 }
9899
9900 cleanup_test101bc() {
9901         trap 0
9902         rm -rf $DIR/$tdir
9903         rm -f $DIR/$tfile
9904
9905         local list=$(comma_list $(osts_nodes))
9906         set_osd_param $list '' read_cache_enable 1
9907         set_osd_param $list '' writethrough_cache_enable 1
9908 }
9909
9910 calc_total() {
9911         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9912 }
9913
9914 ra_check_101() {
9915         local READ_SIZE=$1
9916         local STRIPE_SIZE=$2
9917         local FILE_LENGTH=$3
9918         local RA_INC=1048576
9919         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9920         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9921                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9922         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9923                   get_named_value 'read.but.discarded' | calc_total)
9924         if [[ $DISCARD -gt $discard_limit ]]; then
9925                 $LCTL get_param llite.*.read_ahead_stats
9926                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9927         else
9928                 echo "Read-ahead success for size ${READ_SIZE}"
9929         fi
9930 }
9931
9932 test_101b() {
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9935
9936         local STRIPE_SIZE=1048576
9937         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9938
9939         if [ $SLOW == "yes" ]; then
9940                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9941         else
9942                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9943         fi
9944
9945         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9946
9947         # prepare the read-ahead file
9948         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9949         cancel_lru_locks osc
9950         for BIDX in 2 4 8 16 32 64 128 256
9951         do
9952                 local BSIZE=$((BIDX*4096))
9953                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9954                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9955                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9956                 $LCTL set_param -n llite.*.read_ahead_stats=0
9957                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9958                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9959                 cancel_lru_locks osc
9960                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9961         done
9962         cleanup_test101bc
9963         true
9964 }
9965 run_test 101b "check stride-io mode read-ahead ================="
9966
9967 test_101c() {
9968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9969
9970         local STRIPE_SIZE=1048576
9971         local FILE_LENGTH=$((STRIPE_SIZE*100))
9972         local nreads=10000
9973         local rsize=65536
9974         local osc_rpc_stats
9975
9976         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9977
9978         cancel_lru_locks osc
9979         $LCTL set_param osc.*.rpc_stats=0
9980         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9981         $LCTL get_param osc.*.rpc_stats
9982         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9983                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9984                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9985                 local size
9986
9987                 if [ $lines -le 20 ]; then
9988                         echo "continue debug"
9989                         continue
9990                 fi
9991                 for size in 1 2 4 8; do
9992                         local rpc=$(echo "$stats" |
9993                                     awk '($1 == "'$size':") {print $2; exit; }')
9994                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9995                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9996                 done
9997                 echo "$osc_rpc_stats check passed!"
9998         done
9999         cleanup_test101bc
10000         true
10001 }
10002 run_test 101c "check stripe_size aligned read-ahead"
10003
10004 test_101d() {
10005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10006
10007         local file=$DIR/$tfile
10008         local sz_MB=${FILESIZE_101d:-80}
10009         local ra_MB=${READAHEAD_MB:-40}
10010
10011         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10012         [ $free_MB -lt $sz_MB ] &&
10013                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10014
10015         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10016         $LFS setstripe -c -1 $file || error "setstripe failed"
10017
10018         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10019         echo Cancel LRU locks on lustre client to flush the client cache
10020         cancel_lru_locks osc
10021
10022         echo Disable read-ahead
10023         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10024         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10025         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10026         $LCTL get_param -n llite.*.max_read_ahead_mb
10027
10028         echo "Reading the test file $file with read-ahead disabled"
10029         local sz_KB=$((sz_MB * 1024 / 4))
10030         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10031         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10032         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10033                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10034
10035         echo "Cancel LRU locks on lustre client to flush the client cache"
10036         cancel_lru_locks osc
10037         echo Enable read-ahead with ${ra_MB}MB
10038         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10039
10040         echo "Reading the test file $file with read-ahead enabled"
10041         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10042                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10043
10044         echo "read-ahead disabled time read $raOFF"
10045         echo "read-ahead enabled time read $raON"
10046
10047         rm -f $file
10048         wait_delete_completed
10049
10050         # use awk for this check instead of bash because it handles decimals
10051         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10052                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10053 }
10054 run_test 101d "file read with and without read-ahead enabled"
10055
10056 test_101e() {
10057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10058
10059         local file=$DIR/$tfile
10060         local size_KB=500  #KB
10061         local count=100
10062         local bsize=1024
10063
10064         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10065         local need_KB=$((count * size_KB))
10066         [[ $free_KB -le $need_KB ]] &&
10067                 skip_env "Need free space $need_KB, have $free_KB"
10068
10069         echo "Creating $count ${size_KB}K test files"
10070         for ((i = 0; i < $count; i++)); do
10071                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10072         done
10073
10074         echo "Cancel LRU locks on lustre client to flush the client cache"
10075         cancel_lru_locks $OSC
10076
10077         echo "Reset readahead stats"
10078         $LCTL set_param -n llite.*.read_ahead_stats=0
10079
10080         for ((i = 0; i < $count; i++)); do
10081                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10082         done
10083
10084         $LCTL get_param llite.*.max_cached_mb
10085         $LCTL get_param llite.*.read_ahead_stats
10086         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10087                      get_named_value 'misses' | calc_total)
10088
10089         for ((i = 0; i < $count; i++)); do
10090                 rm -rf $file.$i 2>/dev/null
10091         done
10092
10093         #10000 means 20% reads are missing in readahead
10094         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10095 }
10096 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10097
10098 test_101f() {
10099         which iozone || skip_env "no iozone installed"
10100
10101         local old_debug=$($LCTL get_param debug)
10102         old_debug=${old_debug#*=}
10103         $LCTL set_param debug="reada mmap"
10104
10105         # create a test file
10106         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10107
10108         echo Cancel LRU locks on lustre client to flush the client cache
10109         cancel_lru_locks osc
10110
10111         echo Reset readahead stats
10112         $LCTL set_param -n llite.*.read_ahead_stats=0
10113
10114         echo mmap read the file with small block size
10115         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10116                 > /dev/null 2>&1
10117
10118         echo checking missing pages
10119         $LCTL get_param llite.*.read_ahead_stats
10120         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10121                         get_named_value 'misses' | calc_total)
10122
10123         $LCTL set_param debug="$old_debug"
10124         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10125         rm -f $DIR/$tfile
10126 }
10127 run_test 101f "check mmap read performance"
10128
10129 test_101g_brw_size_test() {
10130         local mb=$1
10131         local pages=$((mb * 1048576 / PAGE_SIZE))
10132         local file=$DIR/$tfile
10133
10134         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10135                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10136         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10137                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10138                         return 2
10139         done
10140
10141         stack_trap "rm -f $file" EXIT
10142         $LCTL set_param -n osc.*.rpc_stats=0
10143
10144         # 10 RPCs should be enough for the test
10145         local count=10
10146         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10147                 { error "dd write ${mb} MB blocks failed"; return 3; }
10148         cancel_lru_locks osc
10149         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10150                 { error "dd write ${mb} MB blocks failed"; return 4; }
10151
10152         # calculate number of full-sized read and write RPCs
10153         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10154                 sed -n '/pages per rpc/,/^$/p' |
10155                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10156                 END { print reads,writes }'))
10157         # allow one extra full-sized read RPC for async readahead
10158         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10159                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10160         [[ ${rpcs[1]} == $count ]] ||
10161                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10162 }
10163
10164 test_101g() {
10165         remote_ost_nodsh && skip "remote OST with nodsh"
10166
10167         local rpcs
10168         local osts=$(get_facets OST)
10169         local list=$(comma_list $(osts_nodes))
10170         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10171         local brw_size="obdfilter.*.brw_size"
10172
10173         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10174
10175         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10176
10177         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10178                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10179                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10180            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10181                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10182                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10183
10184                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10185                         suffix="M"
10186
10187                 if [[ $orig_mb -lt 16 ]]; then
10188                         save_lustre_params $osts "$brw_size" > $p
10189                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10190                                 error "set 16MB RPC size failed"
10191
10192                         echo "remount client to enable new RPC size"
10193                         remount_client $MOUNT || error "remount_client failed"
10194                 fi
10195
10196                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10197                 # should be able to set brw_size=12, but no rpc_stats for that
10198                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10199         fi
10200
10201         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10202
10203         if [[ $orig_mb -lt 16 ]]; then
10204                 restore_lustre_params < $p
10205                 remount_client $MOUNT || error "remount_client restore failed"
10206         fi
10207
10208         rm -f $p $DIR/$tfile
10209 }
10210 run_test 101g "Big bulk(4/16 MiB) readahead"
10211
10212 test_101h() {
10213         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10214
10215         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10216                 error "dd 70M file failed"
10217         echo Cancel LRU locks on lustre client to flush the client cache
10218         cancel_lru_locks osc
10219
10220         echo "Reset readahead stats"
10221         $LCTL set_param -n llite.*.read_ahead_stats 0
10222
10223         echo "Read 10M of data but cross 64M bundary"
10224         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10225         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10226                      get_named_value 'misses' | calc_total)
10227         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10228         rm -f $p $DIR/$tfile
10229 }
10230 run_test 101h "Readahead should cover current read window"
10231
10232 test_101i() {
10233         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10234                 error "dd 10M file failed"
10235
10236         local max_per_file_mb=$($LCTL get_param -n \
10237                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10238         cancel_lru_locks osc
10239         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10240         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10241                 error "set max_read_ahead_per_file_mb to 1 failed"
10242
10243         echo "Reset readahead stats"
10244         $LCTL set_param llite.*.read_ahead_stats=0
10245
10246         dd if=$DIR/$tfile of=/dev/null bs=2M
10247
10248         $LCTL get_param llite.*.read_ahead_stats
10249         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10250                      awk '/misses/ { print $2 }')
10251         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10252         rm -f $DIR/$tfile
10253 }
10254 run_test 101i "allow current readahead to exceed reservation"
10255
10256 test_101j() {
10257         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10258                 error "setstripe $DIR/$tfile failed"
10259         local file_size=$((1048576 * 16))
10260         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10261         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10262
10263         echo Disable read-ahead
10264         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10265
10266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10267         for blk in $PAGE_SIZE 1048576 $file_size; do
10268                 cancel_lru_locks osc
10269                 echo "Reset readahead stats"
10270                 $LCTL set_param -n llite.*.read_ahead_stats=0
10271                 local count=$(($file_size / $blk))
10272                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10273                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10274                              get_named_value 'failed.to.fast.read' | calc_total)
10275                 $LCTL get_param -n llite.*.read_ahead_stats
10276                 [ $miss -eq $count ] || error "expected $count got $miss"
10277         done
10278
10279         rm -f $p $DIR/$tfile
10280 }
10281 run_test 101j "A complete read block should be submitted when no RA"
10282
10283 setup_test102() {
10284         test_mkdir $DIR/$tdir
10285         chown $RUNAS_ID $DIR/$tdir
10286         STRIPE_SIZE=65536
10287         STRIPE_OFFSET=1
10288         STRIPE_COUNT=$OSTCOUNT
10289         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10290
10291         trap cleanup_test102 EXIT
10292         cd $DIR
10293         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10294         cd $DIR/$tdir
10295         for num in 1 2 3 4; do
10296                 for count in $(seq 1 $STRIPE_COUNT); do
10297                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10298                                 local size=`expr $STRIPE_SIZE \* $num`
10299                                 local file=file"$num-$idx-$count"
10300                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10301                         done
10302                 done
10303         done
10304
10305         cd $DIR
10306         $1 tar cf $TMP/f102.tar $tdir --xattrs
10307 }
10308
10309 cleanup_test102() {
10310         trap 0
10311         rm -f $TMP/f102.tar
10312         rm -rf $DIR/d0.sanity/d102
10313 }
10314
10315 test_102a() {
10316         [ "$UID" != 0 ] && skip "must run as root"
10317         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10318                 skip_env "must have user_xattr"
10319
10320         [ -z "$(which setfattr 2>/dev/null)" ] &&
10321                 skip_env "could not find setfattr"
10322
10323         local testfile=$DIR/$tfile
10324
10325         touch $testfile
10326         echo "set/get xattr..."
10327         setfattr -n trusted.name1 -v value1 $testfile ||
10328                 error "setfattr -n trusted.name1=value1 $testfile failed"
10329         getfattr -n trusted.name1 $testfile 2> /dev/null |
10330           grep "trusted.name1=.value1" ||
10331                 error "$testfile missing trusted.name1=value1"
10332
10333         setfattr -n user.author1 -v author1 $testfile ||
10334                 error "setfattr -n user.author1=author1 $testfile failed"
10335         getfattr -n user.author1 $testfile 2> /dev/null |
10336           grep "user.author1=.author1" ||
10337                 error "$testfile missing trusted.author1=author1"
10338
10339         echo "listxattr..."
10340         setfattr -n trusted.name2 -v value2 $testfile ||
10341                 error "$testfile unable to set trusted.name2"
10342         setfattr -n trusted.name3 -v value3 $testfile ||
10343                 error "$testfile unable to set trusted.name3"
10344         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10345             grep "trusted.name" | wc -l) -eq 3 ] ||
10346                 error "$testfile missing 3 trusted.name xattrs"
10347
10348         setfattr -n user.author2 -v author2 $testfile ||
10349                 error "$testfile unable to set user.author2"
10350         setfattr -n user.author3 -v author3 $testfile ||
10351                 error "$testfile unable to set user.author3"
10352         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10353             grep "user.author" | wc -l) -eq 3 ] ||
10354                 error "$testfile missing 3 user.author xattrs"
10355
10356         echo "remove xattr..."
10357         setfattr -x trusted.name1 $testfile ||
10358                 error "$testfile error deleting trusted.name1"
10359         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10360                 error "$testfile did not delete trusted.name1 xattr"
10361
10362         setfattr -x user.author1 $testfile ||
10363                 error "$testfile error deleting user.author1"
10364         echo "set lustre special xattr ..."
10365         $LFS setstripe -c1 $testfile
10366         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10367                 awk -F "=" '/trusted.lov/ { print $2 }' )
10368         setfattr -n "trusted.lov" -v $lovea $testfile ||
10369                 error "$testfile doesn't ignore setting trusted.lov again"
10370         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10371                 error "$testfile allow setting invalid trusted.lov"
10372         rm -f $testfile
10373 }
10374 run_test 102a "user xattr test =================================="
10375
10376 check_102b_layout() {
10377         local layout="$*"
10378         local testfile=$DIR/$tfile
10379
10380         echo "test layout '$layout'"
10381         $LFS setstripe $layout $testfile || error "setstripe failed"
10382         $LFS getstripe -y $testfile
10383
10384         echo "get/set/list trusted.lov xattr ..." # b=10930
10385         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10386         [[ "$value" =~ "trusted.lov" ]] ||
10387                 error "can't get trusted.lov from $testfile"
10388         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10389                 error "getstripe failed"
10390
10391         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10392
10393         value=$(cut -d= -f2 <<<$value)
10394         # LU-13168: truncated xattr should fail if short lov_user_md header
10395         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10396                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10397         for len in $lens; do
10398                 echo "setfattr $len $testfile.2"
10399                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10400                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10401         done
10402         local stripe_size=$($LFS getstripe -S $testfile.2)
10403         local stripe_count=$($LFS getstripe -c $testfile.2)
10404         [[ $stripe_size -eq 65536 ]] ||
10405                 error "stripe size $stripe_size != 65536"
10406         [[ $stripe_count -eq $stripe_count_orig ]] ||
10407                 error "stripe count $stripe_count != $stripe_count_orig"
10408         rm $testfile $testfile.2
10409 }
10410
10411 test_102b() {
10412         [ -z "$(which setfattr 2>/dev/null)" ] &&
10413                 skip_env "could not find setfattr"
10414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10415
10416         # check plain layout
10417         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10418
10419         # and also check composite layout
10420         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10421
10422 }
10423 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10424
10425 test_102c() {
10426         [ -z "$(which setfattr 2>/dev/null)" ] &&
10427                 skip_env "could not find setfattr"
10428         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10429
10430         # b10930: get/set/list lustre.lov xattr
10431         echo "get/set/list lustre.lov xattr ..."
10432         test_mkdir $DIR/$tdir
10433         chown $RUNAS_ID $DIR/$tdir
10434         local testfile=$DIR/$tdir/$tfile
10435         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10436                 error "setstripe failed"
10437         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10438                 error "getstripe failed"
10439         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10440         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10441
10442         local testfile2=${testfile}2
10443         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10444                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10445
10446         $RUNAS $MCREATE $testfile2
10447         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10448         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10449         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10450         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10451         [ $stripe_count -eq $STRIPECOUNT ] ||
10452                 error "stripe count $stripe_count != $STRIPECOUNT"
10453 }
10454 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10455
10456 compare_stripe_info1() {
10457         local stripe_index_all_zero=true
10458
10459         for num in 1 2 3 4; do
10460                 for count in $(seq 1 $STRIPE_COUNT); do
10461                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10462                                 local size=$((STRIPE_SIZE * num))
10463                                 local file=file"$num-$offset-$count"
10464                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10465                                 [[ $stripe_size -ne $size ]] &&
10466                                     error "$file: size $stripe_size != $size"
10467                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10468                                 # allow fewer stripes to be created, ORI-601
10469                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10470                                     error "$file: count $stripe_count != $count"
10471                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10472                                 [[ $stripe_index -ne 0 ]] &&
10473                                         stripe_index_all_zero=false
10474                         done
10475                 done
10476         done
10477         $stripe_index_all_zero &&
10478                 error "all files are being extracted starting from OST index 0"
10479         return 0
10480 }
10481
10482 have_xattrs_include() {
10483         tar --help | grep -q xattrs-include &&
10484                 echo --xattrs-include="lustre.*"
10485 }
10486
10487 test_102d() {
10488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10489         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10490
10491         XINC=$(have_xattrs_include)
10492         setup_test102
10493         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10494         cd $DIR/$tdir/$tdir
10495         compare_stripe_info1
10496 }
10497 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10498
10499 test_102f() {
10500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10501         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10502
10503         XINC=$(have_xattrs_include)
10504         setup_test102
10505         test_mkdir $DIR/$tdir.restore
10506         cd $DIR
10507         tar cf - --xattrs $tdir | tar xf - \
10508                 -C $DIR/$tdir.restore --xattrs $XINC
10509         cd $DIR/$tdir.restore/$tdir
10510         compare_stripe_info1
10511 }
10512 run_test 102f "tar copy files, not keep osts"
10513
10514 grow_xattr() {
10515         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10516                 skip "must have user_xattr"
10517         [ -z "$(which setfattr 2>/dev/null)" ] &&
10518                 skip_env "could not find setfattr"
10519         [ -z "$(which getfattr 2>/dev/null)" ] &&
10520                 skip_env "could not find getfattr"
10521
10522         local xsize=${1:-1024}  # in bytes
10523         local file=$DIR/$tfile
10524         local value="$(generate_string $xsize)"
10525         local xbig=trusted.big
10526         local toobig=$2
10527
10528         touch $file
10529         log "save $xbig on $file"
10530         if [ -z "$toobig" ]
10531         then
10532                 setfattr -n $xbig -v $value $file ||
10533                         error "saving $xbig on $file failed"
10534         else
10535                 setfattr -n $xbig -v $value $file &&
10536                         error "saving $xbig on $file succeeded"
10537                 return 0
10538         fi
10539
10540         local orig=$(get_xattr_value $xbig $file)
10541         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10542
10543         local xsml=trusted.sml
10544         log "save $xsml on $file"
10545         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10546
10547         local new=$(get_xattr_value $xbig $file)
10548         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10549
10550         log "grow $xsml on $file"
10551         setfattr -n $xsml -v "$value" $file ||
10552                 error "growing $xsml on $file failed"
10553
10554         new=$(get_xattr_value $xbig $file)
10555         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10556         log "$xbig still valid after growing $xsml"
10557
10558         rm -f $file
10559 }
10560
10561 test_102h() { # bug 15777
10562         grow_xattr 1024
10563 }
10564 run_test 102h "grow xattr from inside inode to external block"
10565
10566 test_102ha() {
10567         large_xattr_enabled || skip_env "ea_inode feature disabled"
10568
10569         echo "setting xattr of max xattr size: $(max_xattr_size)"
10570         grow_xattr $(max_xattr_size)
10571
10572         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10573         echo "This should fail:"
10574         grow_xattr $(($(max_xattr_size) + 10)) 1
10575 }
10576 run_test 102ha "grow xattr from inside inode to external inode"
10577
10578 test_102i() { # bug 17038
10579         [ -z "$(which getfattr 2>/dev/null)" ] &&
10580                 skip "could not find getfattr"
10581
10582         touch $DIR/$tfile
10583         ln -s $DIR/$tfile $DIR/${tfile}link
10584         getfattr -n trusted.lov $DIR/$tfile ||
10585                 error "lgetxattr on $DIR/$tfile failed"
10586         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10587                 grep -i "no such attr" ||
10588                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10589         rm -f $DIR/$tfile $DIR/${tfile}link
10590 }
10591 run_test 102i "lgetxattr test on symbolic link ============"
10592
10593 test_102j() {
10594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10595         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10596
10597         XINC=$(have_xattrs_include)
10598         setup_test102 "$RUNAS"
10599         chown $RUNAS_ID $DIR/$tdir
10600         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10601         cd $DIR/$tdir/$tdir
10602         compare_stripe_info1 "$RUNAS"
10603 }
10604 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10605
10606 test_102k() {
10607         [ -z "$(which setfattr 2>/dev/null)" ] &&
10608                 skip "could not find setfattr"
10609
10610         touch $DIR/$tfile
10611         # b22187 just check that does not crash for regular file.
10612         setfattr -n trusted.lov $DIR/$tfile
10613         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10614         local test_kdir=$DIR/$tdir
10615         test_mkdir $test_kdir
10616         local default_size=$($LFS getstripe -S $test_kdir)
10617         local default_count=$($LFS getstripe -c $test_kdir)
10618         local default_offset=$($LFS getstripe -i $test_kdir)
10619         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10620                 error 'dir setstripe failed'
10621         setfattr -n trusted.lov $test_kdir
10622         local stripe_size=$($LFS getstripe -S $test_kdir)
10623         local stripe_count=$($LFS getstripe -c $test_kdir)
10624         local stripe_offset=$($LFS getstripe -i $test_kdir)
10625         [ $stripe_size -eq $default_size ] ||
10626                 error "stripe size $stripe_size != $default_size"
10627         [ $stripe_count -eq $default_count ] ||
10628                 error "stripe count $stripe_count != $default_count"
10629         [ $stripe_offset -eq $default_offset ] ||
10630                 error "stripe offset $stripe_offset != $default_offset"
10631         rm -rf $DIR/$tfile $test_kdir
10632 }
10633 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10634
10635 test_102l() {
10636         [ -z "$(which getfattr 2>/dev/null)" ] &&
10637                 skip "could not find getfattr"
10638
10639         # LU-532 trusted. xattr is invisible to non-root
10640         local testfile=$DIR/$tfile
10641
10642         touch $testfile
10643
10644         echo "listxattr as user..."
10645         chown $RUNAS_ID $testfile
10646         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10647             grep -q "trusted" &&
10648                 error "$testfile trusted xattrs are user visible"
10649
10650         return 0;
10651 }
10652 run_test 102l "listxattr size test =================================="
10653
10654 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10655         local path=$DIR/$tfile
10656         touch $path
10657
10658         listxattr_size_check $path || error "listattr_size_check $path failed"
10659 }
10660 run_test 102m "Ensure listxattr fails on small bufffer ========"
10661
10662 cleanup_test102
10663
10664 getxattr() { # getxattr path name
10665         # Return the base64 encoding of the value of xattr name on path.
10666         local path=$1
10667         local name=$2
10668
10669         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10670         # file: $path
10671         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10672         #
10673         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10674
10675         getfattr --absolute-names --encoding=base64 --name=$name $path |
10676                 awk -F= -v name=$name '$1 == name {
10677                         print substr($0, index($0, "=") + 1);
10678         }'
10679 }
10680
10681 test_102n() { # LU-4101 mdt: protect internal xattrs
10682         [ -z "$(which setfattr 2>/dev/null)" ] &&
10683                 skip "could not find setfattr"
10684         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10685         then
10686                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10687         fi
10688
10689         local file0=$DIR/$tfile.0
10690         local file1=$DIR/$tfile.1
10691         local xattr0=$TMP/$tfile.0
10692         local xattr1=$TMP/$tfile.1
10693         local namelist="lov lma lmv link fid version som hsm"
10694         local name
10695         local value
10696
10697         rm -rf $file0 $file1 $xattr0 $xattr1
10698         touch $file0 $file1
10699
10700         # Get 'before' xattrs of $file1.
10701         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10702
10703         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10704                 namelist+=" lfsck_namespace"
10705         for name in $namelist; do
10706                 # Try to copy xattr from $file0 to $file1.
10707                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10708
10709                 setfattr --name=trusted.$name --value="$value" $file1 ||
10710                         error "setxattr 'trusted.$name' failed"
10711
10712                 # Try to set a garbage xattr.
10713                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10714
10715                 if [[ x$name == "xlov" ]]; then
10716                         setfattr --name=trusted.lov --value="$value" $file1 &&
10717                         error "setxattr invalid 'trusted.lov' success"
10718                 else
10719                         setfattr --name=trusted.$name --value="$value" $file1 ||
10720                                 error "setxattr invalid 'trusted.$name' failed"
10721                 fi
10722
10723                 # Try to remove the xattr from $file1. We don't care if this
10724                 # appears to succeed or fail, we just don't want there to be
10725                 # any changes or crashes.
10726                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10727         done
10728
10729         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10730         then
10731                 name="lfsck_ns"
10732                 # Try to copy xattr from $file0 to $file1.
10733                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10734
10735                 setfattr --name=trusted.$name --value="$value" $file1 ||
10736                         error "setxattr 'trusted.$name' failed"
10737
10738                 # Try to set a garbage xattr.
10739                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10740
10741                 setfattr --name=trusted.$name --value="$value" $file1 ||
10742                         error "setxattr 'trusted.$name' failed"
10743
10744                 # Try to remove the xattr from $file1. We don't care if this
10745                 # appears to succeed or fail, we just don't want there to be
10746                 # any changes or crashes.
10747                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10748         fi
10749
10750         # Get 'after' xattrs of file1.
10751         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10752
10753         if ! diff $xattr0 $xattr1; then
10754                 error "before and after xattrs of '$file1' differ"
10755         fi
10756
10757         rm -rf $file0 $file1 $xattr0 $xattr1
10758
10759         return 0
10760 }
10761 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10762
10763 test_102p() { # LU-4703 setxattr did not check ownership
10764         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10765                 skip "MDS needs to be at least 2.5.56"
10766
10767         local testfile=$DIR/$tfile
10768
10769         touch $testfile
10770
10771         echo "setfacl as user..."
10772         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10773         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10774
10775         echo "setfattr as user..."
10776         setfacl -m "u:$RUNAS_ID:---" $testfile
10777         $RUNAS setfattr -x system.posix_acl_access $testfile
10778         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10779 }
10780 run_test 102p "check setxattr(2) correctly fails without permission"
10781
10782 test_102q() {
10783         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10784                 skip "MDS needs to be at least 2.6.92"
10785
10786         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10787 }
10788 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10789
10790 test_102r() {
10791         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10792                 skip "MDS needs to be at least 2.6.93"
10793
10794         touch $DIR/$tfile || error "touch"
10795         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10796         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10797         rm $DIR/$tfile || error "rm"
10798
10799         #normal directory
10800         mkdir -p $DIR/$tdir || error "mkdir"
10801         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10802         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10803         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10804                 error "$testfile error deleting user.author1"
10805         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10806                 grep "user.$(basename $tdir)" &&
10807                 error "$tdir did not delete user.$(basename $tdir)"
10808         rmdir $DIR/$tdir || error "rmdir"
10809
10810         #striped directory
10811         test_mkdir $DIR/$tdir
10812         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10813         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10814         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10815                 error "$testfile error deleting user.author1"
10816         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10817                 grep "user.$(basename $tdir)" &&
10818                 error "$tdir did not delete user.$(basename $tdir)"
10819         rmdir $DIR/$tdir || error "rm striped dir"
10820 }
10821 run_test 102r "set EAs with empty values"
10822
10823 test_102s() {
10824         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10825                 skip "MDS needs to be at least 2.11.52"
10826
10827         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10828
10829         save_lustre_params client "llite.*.xattr_cache" > $save
10830
10831         for cache in 0 1; do
10832                 lctl set_param llite.*.xattr_cache=$cache
10833
10834                 rm -f $DIR/$tfile
10835                 touch $DIR/$tfile || error "touch"
10836                 for prefix in lustre security system trusted user; do
10837                         # Note getxattr() may fail with 'Operation not
10838                         # supported' or 'No such attribute' depending
10839                         # on prefix and cache.
10840                         getfattr -n $prefix.n102s $DIR/$tfile &&
10841                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10842                 done
10843         done
10844
10845         restore_lustre_params < $save
10846 }
10847 run_test 102s "getting nonexistent xattrs should fail"
10848
10849 test_102t() {
10850         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10851                 skip "MDS needs to be at least 2.11.52"
10852
10853         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10854
10855         save_lustre_params client "llite.*.xattr_cache" > $save
10856
10857         for cache in 0 1; do
10858                 lctl set_param llite.*.xattr_cache=$cache
10859
10860                 for buf_size in 0 256; do
10861                         rm -f $DIR/$tfile
10862                         touch $DIR/$tfile || error "touch"
10863                         setfattr -n user.multiop $DIR/$tfile
10864                         $MULTIOP $DIR/$tfile oa$buf_size ||
10865                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10866                 done
10867         done
10868
10869         restore_lustre_params < $save
10870 }
10871 run_test 102t "zero length xattr values handled correctly"
10872
10873 run_acl_subtest()
10874 {
10875     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10876     return $?
10877 }
10878
10879 test_103a() {
10880         [ "$UID" != 0 ] && skip "must run as root"
10881         $GSS && skip_env "could not run under gss"
10882         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10883                 skip_env "must have acl enabled"
10884         [ -z "$(which setfacl 2>/dev/null)" ] &&
10885                 skip_env "could not find setfacl"
10886         remote_mds_nodsh && skip "remote MDS with nodsh"
10887
10888         gpasswd -a daemon bin                           # LU-5641
10889         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10890
10891         declare -a identity_old
10892
10893         for num in $(seq $MDSCOUNT); do
10894                 switch_identity $num true || identity_old[$num]=$?
10895         done
10896
10897         SAVE_UMASK=$(umask)
10898         umask 0022
10899         mkdir -p $DIR/$tdir
10900         cd $DIR/$tdir
10901
10902         echo "performing cp ..."
10903         run_acl_subtest cp || error "run_acl_subtest cp failed"
10904         echo "performing getfacl-noacl..."
10905         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10906         echo "performing misc..."
10907         run_acl_subtest misc || error  "misc test failed"
10908         echo "performing permissions..."
10909         run_acl_subtest permissions || error "permissions failed"
10910         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10911         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10912                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10913                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10914         then
10915                 echo "performing permissions xattr..."
10916                 run_acl_subtest permissions_xattr ||
10917                         error "permissions_xattr failed"
10918         fi
10919         echo "performing setfacl..."
10920         run_acl_subtest setfacl || error  "setfacl test failed"
10921
10922         # inheritance test got from HP
10923         echo "performing inheritance..."
10924         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10925         chmod +x make-tree || error "chmod +x failed"
10926         run_acl_subtest inheritance || error "inheritance test failed"
10927         rm -f make-tree
10928
10929         echo "LU-974 ignore umask when acl is enabled..."
10930         run_acl_subtest 974 || error "LU-974 umask test failed"
10931         if [ $MDSCOUNT -ge 2 ]; then
10932                 run_acl_subtest 974_remote ||
10933                         error "LU-974 umask test failed under remote dir"
10934         fi
10935
10936         echo "LU-2561 newly created file is same size as directory..."
10937         if [ "$mds1_FSTYPE" != "zfs" ]; then
10938                 run_acl_subtest 2561 || error "LU-2561 test failed"
10939         else
10940                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10941         fi
10942
10943         run_acl_subtest 4924 || error "LU-4924 test failed"
10944
10945         cd $SAVE_PWD
10946         umask $SAVE_UMASK
10947
10948         for num in $(seq $MDSCOUNT); do
10949                 if [ "${identity_old[$num]}" = 1 ]; then
10950                         switch_identity $num false || identity_old[$num]=$?
10951                 fi
10952         done
10953 }
10954 run_test 103a "acl test"
10955
10956 test_103b() {
10957         declare -a pids
10958         local U
10959
10960         for U in {0..511}; do
10961                 {
10962                 local O=$(printf "%04o" $U)
10963
10964                 umask $(printf "%04o" $((511 ^ $O)))
10965                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10966                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10967
10968                 (( $S == ($O & 0666) )) ||
10969                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10970
10971                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10972                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10973                 (( $S == ($O & 0666) )) ||
10974                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10975
10976                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10977                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10978                 (( $S == ($O & 0666) )) ||
10979                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10980                 rm -f $DIR/$tfile.[smp]$0
10981                 } &
10982                 local pid=$!
10983
10984                 # limit the concurrently running threads to 64. LU-11878
10985                 local idx=$((U % 64))
10986                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10987                 pids[idx]=$pid
10988         done
10989         wait
10990 }
10991 run_test 103b "umask lfs setstripe"
10992
10993 test_103c() {
10994         mkdir -p $DIR/$tdir
10995         cp -rp $DIR/$tdir $DIR/$tdir.bak
10996
10997         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10998                 error "$DIR/$tdir shouldn't contain default ACL"
10999         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11000                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11001         true
11002 }
11003 run_test 103c "'cp -rp' won't set empty acl"
11004
11005 test_103e() {
11006         local numacl
11007         local fileacl
11008         local saved_debug=$($LCTL get_param -n debug)
11009
11010         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11011                 skip "MDS needs to be at least 2.14.0"
11012
11013         large_xattr_enabled || skip_env "ea_inode feature disabled"
11014
11015         mkdir -p $DIR/$tdir
11016         # add big LOV EA to cause reply buffer overflow earlier
11017         $LFS setstripe -C 1000 $DIR/$tdir
11018         lctl set_param mdc.*-mdc*.stats=clear
11019
11020         $LCTL set_param debug=0
11021         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11022         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11023
11024         # add a large number of default ACLs (expect 8000+ for 2.13+)
11025         for U in {2..7000}; do
11026                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11027                         error "Able to add just $U default ACLs"
11028         done
11029         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11030         echo "$numacl default ACLs created"
11031
11032         stat $DIR/$tdir || error "Cannot stat directory"
11033         # check file creation
11034         touch $DIR/$tdir/$tfile ||
11035                 error "failed to create $tfile with $numacl default ACLs"
11036         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11037         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11038         echo "$fileacl ACLs were inherited"
11039         (( $fileacl == $numacl )) ||
11040                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11041         # check that new ACLs creation adds new ACLs to inherited ACLs
11042         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11043                 error "Cannot set new ACL"
11044         numacl=$((numacl + 1))
11045         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11046         (( $fileacl == $numacl )) ||
11047                 error "failed to add new ACL: $fileacl != $numacl as expected"
11048         # adds more ACLs to a file to reach their maximum at 8000+
11049         numacl=0
11050         for U in {20000..25000}; do
11051                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11052                 numacl=$((numacl + 1))
11053         done
11054         echo "Added $numacl more ACLs to the file"
11055         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11056         echo "Total $fileacl ACLs in file"
11057         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11058         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11059         rmdir $DIR/$tdir || error "Cannot remove directory"
11060 }
11061 run_test 103e "inheritance of big amount of default ACLs"
11062
11063 test_103f() {
11064         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11065                 skip "MDS needs to be at least 2.14.51"
11066
11067         large_xattr_enabled || skip_env "ea_inode feature disabled"
11068
11069         # enable changelog to consume more internal MDD buffers
11070         changelog_register
11071
11072         mkdir -p $DIR/$tdir
11073         # add big LOV EA
11074         $LFS setstripe -C 1000 $DIR/$tdir
11075         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11076         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11077         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11078         rmdir $DIR/$tdir || error "Cannot remove directory"
11079 }
11080 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11081
11082 test_104a() {
11083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11084
11085         touch $DIR/$tfile
11086         lfs df || error "lfs df failed"
11087         lfs df -ih || error "lfs df -ih failed"
11088         lfs df -h $DIR || error "lfs df -h $DIR failed"
11089         lfs df -i $DIR || error "lfs df -i $DIR failed"
11090         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11091         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11092
11093         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11094         lctl --device %$OSC deactivate
11095         lfs df || error "lfs df with deactivated OSC failed"
11096         lctl --device %$OSC activate
11097         # wait the osc back to normal
11098         wait_osc_import_ready client ost
11099
11100         lfs df || error "lfs df with reactivated OSC failed"
11101         rm -f $DIR/$tfile
11102 }
11103 run_test 104a "lfs df [-ih] [path] test ========================="
11104
11105 test_104b() {
11106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11107         [ $RUNAS_ID -eq $UID ] &&
11108                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11109
11110         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11111                         grep "Permission denied" | wc -l)))
11112         if [ $denied_cnt -ne 0 ]; then
11113                 error "lfs check servers test failed"
11114         fi
11115 }
11116 run_test 104b "$RUNAS lfs check servers test ===================="
11117
11118 #
11119 # Verify $1 is within range of $2.
11120 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11121 # $1 is <= 2% of $2. Else Fail.
11122 #
11123 value_in_range() {
11124         # Strip all units (M, G, T)
11125         actual=$(echo $1 | tr -d A-Z)
11126         expect=$(echo $2 | tr -d A-Z)
11127
11128         expect_lo=$(($expect * 98 / 100)) # 2% below
11129         expect_hi=$(($expect * 102 / 100)) # 2% above
11130
11131         # permit 2% drift above and below
11132         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11133 }
11134
11135 test_104c() {
11136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11137         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11138
11139         local ost_param="osd-zfs.$FSNAME-OST0000."
11140         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11141         local ofacets=$(get_facets OST)
11142         local mfacets=$(get_facets MDS)
11143         local saved_ost_blocks=
11144         local saved_mdt_blocks=
11145
11146         echo "Before recordsize change"
11147         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11148         df=($(df -h | grep "/mnt/lustre"$))
11149
11150         # For checking.
11151         echo "lfs output : ${lfs_df[*]}"
11152         echo "df  output : ${df[*]}"
11153
11154         for facet in ${ofacets//,/ }; do
11155                 if [ -z $saved_ost_blocks ]; then
11156                         saved_ost_blocks=$(do_facet $facet \
11157                                 lctl get_param -n $ost_param.blocksize)
11158                         echo "OST Blocksize: $saved_ost_blocks"
11159                 fi
11160                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11161                 do_facet $facet zfs set recordsize=32768 $ost
11162         done
11163
11164         # BS too small. Sufficient for functional testing.
11165         for facet in ${mfacets//,/ }; do
11166                 if [ -z $saved_mdt_blocks ]; then
11167                         saved_mdt_blocks=$(do_facet $facet \
11168                                 lctl get_param -n $mdt_param.blocksize)
11169                         echo "MDT Blocksize: $saved_mdt_blocks"
11170                 fi
11171                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11172                 do_facet $facet zfs set recordsize=32768 $mdt
11173         done
11174
11175         # Give new values chance to reflect change
11176         sleep 2
11177
11178         echo "After recordsize change"
11179         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11180         df_after=($(df -h | grep "/mnt/lustre"$))
11181
11182         # For checking.
11183         echo "lfs output : ${lfs_df_after[*]}"
11184         echo "df  output : ${df_after[*]}"
11185
11186         # Verify lfs df
11187         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11188                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11189         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11190                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11191         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11192                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11193
11194         # Verify df
11195         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11196                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11197         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11198                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11199         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11200                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11201
11202         # Restore MDT recordize back to original
11203         for facet in ${mfacets//,/ }; do
11204                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11205                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11206         done
11207
11208         # Restore OST recordize back to original
11209         for facet in ${ofacets//,/ }; do
11210                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11211                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11212         done
11213
11214         return 0
11215 }
11216 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11217
11218 test_105a() {
11219         # doesn't work on 2.4 kernels
11220         touch $DIR/$tfile
11221         if $(flock_is_enabled); then
11222                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11223         else
11224                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11225         fi
11226         rm -f $DIR/$tfile
11227 }
11228 run_test 105a "flock when mounted without -o flock test ========"
11229
11230 test_105b() {
11231         touch $DIR/$tfile
11232         if $(flock_is_enabled); then
11233                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11234         else
11235                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11236         fi
11237         rm -f $DIR/$tfile
11238 }
11239 run_test 105b "fcntl when mounted without -o flock test ========"
11240
11241 test_105c() {
11242         touch $DIR/$tfile
11243         if $(flock_is_enabled); then
11244                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11245         else
11246                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11247         fi
11248         rm -f $DIR/$tfile
11249 }
11250 run_test 105c "lockf when mounted without -o flock test"
11251
11252 test_105d() { # bug 15924
11253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11254
11255         test_mkdir $DIR/$tdir
11256         flock_is_enabled || skip_env "mount w/o flock enabled"
11257         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11258         $LCTL set_param fail_loc=0x80000315
11259         flocks_test 2 $DIR/$tdir
11260 }
11261 run_test 105d "flock race (should not freeze) ========"
11262
11263 test_105e() { # bug 22660 && 22040
11264         flock_is_enabled || skip_env "mount w/o flock enabled"
11265
11266         touch $DIR/$tfile
11267         flocks_test 3 $DIR/$tfile
11268 }
11269 run_test 105e "Two conflicting flocks from same process"
11270
11271 test_106() { #bug 10921
11272         test_mkdir $DIR/$tdir
11273         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11274         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11275 }
11276 run_test 106 "attempt exec of dir followed by chown of that dir"
11277
11278 test_107() {
11279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11280
11281         CDIR=`pwd`
11282         local file=core
11283
11284         cd $DIR
11285         rm -f $file
11286
11287         local save_pattern=$(sysctl -n kernel.core_pattern)
11288         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11289         sysctl -w kernel.core_pattern=$file
11290         sysctl -w kernel.core_uses_pid=0
11291
11292         ulimit -c unlimited
11293         sleep 60 &
11294         SLEEPPID=$!
11295
11296         sleep 1
11297
11298         kill -s 11 $SLEEPPID
11299         wait $SLEEPPID
11300         if [ -e $file ]; then
11301                 size=`stat -c%s $file`
11302                 [ $size -eq 0 ] && error "Fail to create core file $file"
11303         else
11304                 error "Fail to create core file $file"
11305         fi
11306         rm -f $file
11307         sysctl -w kernel.core_pattern=$save_pattern
11308         sysctl -w kernel.core_uses_pid=$save_uses_pid
11309         cd $CDIR
11310 }
11311 run_test 107 "Coredump on SIG"
11312
11313 test_110() {
11314         test_mkdir $DIR/$tdir
11315         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11316         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11317                 error "mkdir with 256 char should fail, but did not"
11318         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11319                 error "create with 255 char failed"
11320         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11321                 error "create with 256 char should fail, but did not"
11322
11323         ls -l $DIR/$tdir
11324         rm -rf $DIR/$tdir
11325 }
11326 run_test 110 "filename length checking"
11327
11328 #
11329 # Purpose: To verify dynamic thread (OSS) creation.
11330 #
11331 test_115() {
11332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11333         remote_ost_nodsh && skip "remote OST with nodsh"
11334
11335         # Lustre does not stop service threads once they are started.
11336         # Reset number of running threads to default.
11337         stopall
11338         setupall
11339
11340         local OSTIO_pre
11341         local save_params="$TMP/sanity-$TESTNAME.parameters"
11342
11343         # Get ll_ost_io count before I/O
11344         OSTIO_pre=$(do_facet ost1 \
11345                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11346         # Exit if lustre is not running (ll_ost_io not running).
11347         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11348
11349         echo "Starting with $OSTIO_pre threads"
11350         local thread_max=$((OSTIO_pre * 2))
11351         local rpc_in_flight=$((thread_max * 2))
11352         # Number of I/O Process proposed to be started.
11353         local nfiles
11354         local facets=$(get_facets OST)
11355
11356         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11357         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11358
11359         # Set in_flight to $rpc_in_flight
11360         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11361                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11362         nfiles=${rpc_in_flight}
11363         # Set ost thread_max to $thread_max
11364         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11365
11366         # 5 Minutes should be sufficient for max number of OSS
11367         # threads(thread_max) to be created.
11368         local timeout=300
11369
11370         # Start I/O.
11371         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11372         test_mkdir $DIR/$tdir
11373         for i in $(seq $nfiles); do
11374                 local file=$DIR/$tdir/${tfile}-$i
11375                 $LFS setstripe -c -1 -i 0 $file
11376                 ($WTL $file $timeout)&
11377         done
11378
11379         # I/O Started - Wait for thread_started to reach thread_max or report
11380         # error if thread_started is more than thread_max.
11381         echo "Waiting for thread_started to reach thread_max"
11382         local thread_started=0
11383         local end_time=$((SECONDS + timeout))
11384
11385         while [ $SECONDS -le $end_time ] ; do
11386                 echo -n "."
11387                 # Get ost i/o thread_started count.
11388                 thread_started=$(do_facet ost1 \
11389                         "$LCTL get_param \
11390                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11391                 # Break out if thread_started is equal/greater than thread_max
11392                 if [[ $thread_started -ge $thread_max ]]; then
11393                         echo ll_ost_io thread_started $thread_started, \
11394                                 equal/greater than thread_max $thread_max
11395                         break
11396                 fi
11397                 sleep 1
11398         done
11399
11400         # Cleanup - We have the numbers, Kill i/o jobs if running.
11401         jobcount=($(jobs -p))
11402         for i in $(seq 0 $((${#jobcount[@]}-1)))
11403         do
11404                 kill -9 ${jobcount[$i]}
11405                 if [ $? -ne 0 ] ; then
11406                         echo Warning: \
11407                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11408                 fi
11409         done
11410
11411         # Cleanup files left by WTL binary.
11412         for i in $(seq $nfiles); do
11413                 local file=$DIR/$tdir/${tfile}-$i
11414                 rm -rf $file
11415                 if [ $? -ne 0 ] ; then
11416                         echo "Warning: Failed to delete file $file"
11417                 fi
11418         done
11419
11420         restore_lustre_params <$save_params
11421         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11422
11423         # Error out if no new thread has started or Thread started is greater
11424         # than thread max.
11425         if [[ $thread_started -le $OSTIO_pre ||
11426                         $thread_started -gt $thread_max ]]; then
11427                 error "ll_ost_io: thread_started $thread_started" \
11428                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11429                       "No new thread started or thread started greater " \
11430                       "than thread_max."
11431         fi
11432 }
11433 run_test 115 "verify dynamic thread creation===================="
11434
11435 free_min_max () {
11436         wait_delete_completed
11437         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11438         echo "OST kbytes available: ${AVAIL[@]}"
11439         MAXV=${AVAIL[0]}
11440         MAXI=0
11441         MINV=${AVAIL[0]}
11442         MINI=0
11443         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11444                 #echo OST $i: ${AVAIL[i]}kb
11445                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11446                         MAXV=${AVAIL[i]}
11447                         MAXI=$i
11448                 fi
11449                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11450                         MINV=${AVAIL[i]}
11451                         MINI=$i
11452                 fi
11453         done
11454         echo "Min free space: OST $MINI: $MINV"
11455         echo "Max free space: OST $MAXI: $MAXV"
11456 }
11457
11458 test_116a() { # was previously test_116()
11459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11460         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11461         remote_mds_nodsh && skip "remote MDS with nodsh"
11462
11463         echo -n "Free space priority "
11464         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11465                 head -n1
11466         declare -a AVAIL
11467         free_min_max
11468
11469         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11470         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11471         trap simple_cleanup_common EXIT
11472
11473         # Check if we need to generate uneven OSTs
11474         test_mkdir -p $DIR/$tdir/OST${MINI}
11475         local FILL=$((MINV / 4))
11476         local DIFF=$((MAXV - MINV))
11477         local DIFF2=$((DIFF * 100 / MINV))
11478
11479         local threshold=$(do_facet $SINGLEMDS \
11480                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11481         threshold=${threshold%%%}
11482         echo -n "Check for uneven OSTs: "
11483         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11484
11485         if [[ $DIFF2 -gt $threshold ]]; then
11486                 echo "ok"
11487                 echo "Don't need to fill OST$MINI"
11488         else
11489                 # generate uneven OSTs. Write 2% over the QOS threshold value
11490                 echo "no"
11491                 DIFF=$((threshold - DIFF2 + 2))
11492                 DIFF2=$((MINV * DIFF / 100))
11493                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11494                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11495                         error "setstripe failed"
11496                 DIFF=$((DIFF2 / 2048))
11497                 i=0
11498                 while [ $i -lt $DIFF ]; do
11499                         i=$((i + 1))
11500                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11501                                 bs=2M count=1 2>/dev/null
11502                         echo -n .
11503                 done
11504                 echo .
11505                 sync
11506                 sleep_maxage
11507                 free_min_max
11508         fi
11509
11510         DIFF=$((MAXV - MINV))
11511         DIFF2=$((DIFF * 100 / MINV))
11512         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11513         if [ $DIFF2 -gt $threshold ]; then
11514                 echo "ok"
11515         else
11516                 echo "failed - QOS mode won't be used"
11517                 simple_cleanup_common
11518                 skip "QOS imbalance criteria not met"
11519         fi
11520
11521         MINI1=$MINI
11522         MINV1=$MINV
11523         MAXI1=$MAXI
11524         MAXV1=$MAXV
11525
11526         # now fill using QOS
11527         $LFS setstripe -c 1 $DIR/$tdir
11528         FILL=$((FILL / 200))
11529         if [ $FILL -gt 600 ]; then
11530                 FILL=600
11531         fi
11532         echo "writing $FILL files to QOS-assigned OSTs"
11533         i=0
11534         while [ $i -lt $FILL ]; do
11535                 i=$((i + 1))
11536                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11537                         count=1 2>/dev/null
11538                 echo -n .
11539         done
11540         echo "wrote $i 200k files"
11541         sync
11542         sleep_maxage
11543
11544         echo "Note: free space may not be updated, so measurements might be off"
11545         free_min_max
11546         DIFF2=$((MAXV - MINV))
11547         echo "free space delta: orig $DIFF final $DIFF2"
11548         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11549         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11550         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11551         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11552         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11553         if [[ $DIFF -gt 0 ]]; then
11554                 FILL=$((DIFF2 * 100 / DIFF - 100))
11555                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11556         fi
11557
11558         # Figure out which files were written where
11559         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11560                awk '/'$MINI1': / {print $2; exit}')
11561         echo $UUID
11562         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11563         echo "$MINC files created on smaller OST $MINI1"
11564         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11565                awk '/'$MAXI1': / {print $2; exit}')
11566         echo $UUID
11567         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11568         echo "$MAXC files created on larger OST $MAXI1"
11569         if [[ $MINC -gt 0 ]]; then
11570                 FILL=$((MAXC * 100 / MINC - 100))
11571                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11572         fi
11573         [[ $MAXC -gt $MINC ]] ||
11574                 error_ignore LU-9 "stripe QOS didn't balance free space"
11575         simple_cleanup_common
11576 }
11577 run_test 116a "stripe QOS: free space balance ==================="
11578
11579 test_116b() { # LU-2093
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         remote_mds_nodsh && skip "remote MDS with nodsh"
11582
11583 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11584         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11585                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11586         [ -z "$old_rr" ] && skip "no QOS"
11587         do_facet $SINGLEMDS lctl set_param \
11588                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11589         mkdir -p $DIR/$tdir
11590         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11591         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11592         do_facet $SINGLEMDS lctl set_param fail_loc=0
11593         rm -rf $DIR/$tdir
11594         do_facet $SINGLEMDS lctl set_param \
11595                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11596 }
11597 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11598
11599 test_117() # bug 10891
11600 {
11601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11602
11603         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11604         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11605         lctl set_param fail_loc=0x21e
11606         > $DIR/$tfile || error "truncate failed"
11607         lctl set_param fail_loc=0
11608         echo "Truncate succeeded."
11609         rm -f $DIR/$tfile
11610 }
11611 run_test 117 "verify osd extend =========="
11612
11613 NO_SLOW_RESENDCOUNT=4
11614 export OLD_RESENDCOUNT=""
11615 set_resend_count () {
11616         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11617         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11618         lctl set_param -n $PROC_RESENDCOUNT $1
11619         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11620 }
11621
11622 # for reduce test_118* time (b=14842)
11623 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11624
11625 # Reset async IO behavior after error case
11626 reset_async() {
11627         FILE=$DIR/reset_async
11628
11629         # Ensure all OSCs are cleared
11630         $LFS setstripe -c -1 $FILE
11631         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11632         sync
11633         rm $FILE
11634 }
11635
11636 test_118a() #bug 11710
11637 {
11638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11639
11640         reset_async
11641
11642         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11643         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11644         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11645
11646         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11647                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11648                 return 1;
11649         fi
11650         rm -f $DIR/$tfile
11651 }
11652 run_test 118a "verify O_SYNC works =========="
11653
11654 test_118b()
11655 {
11656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11657         remote_ost_nodsh && skip "remote OST with nodsh"
11658
11659         reset_async
11660
11661         #define OBD_FAIL_SRV_ENOENT 0x217
11662         set_nodes_failloc "$(osts_nodes)" 0x217
11663         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11664         RC=$?
11665         set_nodes_failloc "$(osts_nodes)" 0
11666         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11667         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11668                     grep -c writeback)
11669
11670         if [[ $RC -eq 0 ]]; then
11671                 error "Must return error due to dropped pages, rc=$RC"
11672                 return 1;
11673         fi
11674
11675         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11676                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11677                 return 1;
11678         fi
11679
11680         echo "Dirty pages not leaked on ENOENT"
11681
11682         # Due to the above error the OSC will issue all RPCs syncronously
11683         # until a subsequent RPC completes successfully without error.
11684         $MULTIOP $DIR/$tfile Ow4096yc
11685         rm -f $DIR/$tfile
11686
11687         return 0
11688 }
11689 run_test 118b "Reclaim dirty pages on fatal error =========="
11690
11691 test_118c()
11692 {
11693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11694
11695         # for 118c, restore the original resend count, LU-1940
11696         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11697                                 set_resend_count $OLD_RESENDCOUNT
11698         remote_ost_nodsh && skip "remote OST with nodsh"
11699
11700         reset_async
11701
11702         #define OBD_FAIL_OST_EROFS               0x216
11703         set_nodes_failloc "$(osts_nodes)" 0x216
11704
11705         # multiop should block due to fsync until pages are written
11706         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11707         MULTIPID=$!
11708         sleep 1
11709
11710         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11711                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11712         fi
11713
11714         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11715                     grep -c writeback)
11716         if [[ $WRITEBACK -eq 0 ]]; then
11717                 error "No page in writeback, writeback=$WRITEBACK"
11718         fi
11719
11720         set_nodes_failloc "$(osts_nodes)" 0
11721         wait $MULTIPID
11722         RC=$?
11723         if [[ $RC -ne 0 ]]; then
11724                 error "Multiop fsync failed, rc=$RC"
11725         fi
11726
11727         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11728         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11729                     grep -c writeback)
11730         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11731                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11732         fi
11733
11734         rm -f $DIR/$tfile
11735         echo "Dirty pages flushed via fsync on EROFS"
11736         return 0
11737 }
11738 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11739
11740 # continue to use small resend count to reduce test_118* time (b=14842)
11741 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11742
11743 test_118d()
11744 {
11745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11746         remote_ost_nodsh && skip "remote OST with nodsh"
11747
11748         reset_async
11749
11750         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11751         set_nodes_failloc "$(osts_nodes)" 0x214
11752         # multiop should block due to fsync until pages are written
11753         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11754         MULTIPID=$!
11755         sleep 1
11756
11757         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11758                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11759         fi
11760
11761         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11762                     grep -c writeback)
11763         if [[ $WRITEBACK -eq 0 ]]; then
11764                 error "No page in writeback, writeback=$WRITEBACK"
11765         fi
11766
11767         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11768         set_nodes_failloc "$(osts_nodes)" 0
11769
11770         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11771         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11772                     grep -c writeback)
11773         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11774                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11775         fi
11776
11777         rm -f $DIR/$tfile
11778         echo "Dirty pages gaurenteed flushed via fsync"
11779         return 0
11780 }
11781 run_test 118d "Fsync validation inject a delay of the bulk =========="
11782
11783 test_118f() {
11784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11785
11786         reset_async
11787
11788         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11789         lctl set_param fail_loc=0x8000040a
11790
11791         # Should simulate EINVAL error which is fatal
11792         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11793         RC=$?
11794         if [[ $RC -eq 0 ]]; then
11795                 error "Must return error due to dropped pages, rc=$RC"
11796         fi
11797
11798         lctl set_param fail_loc=0x0
11799
11800         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11801         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11802         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11803                     grep -c writeback)
11804         if [[ $LOCKED -ne 0 ]]; then
11805                 error "Locked pages remain in cache, locked=$LOCKED"
11806         fi
11807
11808         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11809                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11810         fi
11811
11812         rm -f $DIR/$tfile
11813         echo "No pages locked after fsync"
11814
11815         reset_async
11816         return 0
11817 }
11818 run_test 118f "Simulate unrecoverable OSC side error =========="
11819
11820 test_118g() {
11821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11822
11823         reset_async
11824
11825         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11826         lctl set_param fail_loc=0x406
11827
11828         # simulate local -ENOMEM
11829         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11830         RC=$?
11831
11832         lctl set_param fail_loc=0
11833         if [[ $RC -eq 0 ]]; then
11834                 error "Must return error due to dropped pages, rc=$RC"
11835         fi
11836
11837         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11838         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11839         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11840                         grep -c writeback)
11841         if [[ $LOCKED -ne 0 ]]; then
11842                 error "Locked pages remain in cache, locked=$LOCKED"
11843         fi
11844
11845         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11846                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11847         fi
11848
11849         rm -f $DIR/$tfile
11850         echo "No pages locked after fsync"
11851
11852         reset_async
11853         return 0
11854 }
11855 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11856
11857 test_118h() {
11858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11859         remote_ost_nodsh && skip "remote OST with nodsh"
11860
11861         reset_async
11862
11863         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11864         set_nodes_failloc "$(osts_nodes)" 0x20e
11865         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11866         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11867         RC=$?
11868
11869         set_nodes_failloc "$(osts_nodes)" 0
11870         if [[ $RC -eq 0 ]]; then
11871                 error "Must return error due to dropped pages, rc=$RC"
11872         fi
11873
11874         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11875         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11876         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11877                     grep -c writeback)
11878         if [[ $LOCKED -ne 0 ]]; then
11879                 error "Locked pages remain in cache, locked=$LOCKED"
11880         fi
11881
11882         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11883                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11884         fi
11885
11886         rm -f $DIR/$tfile
11887         echo "No pages locked after fsync"
11888
11889         return 0
11890 }
11891 run_test 118h "Verify timeout in handling recoverables errors  =========="
11892
11893 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11894
11895 test_118i() {
11896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11897         remote_ost_nodsh && skip "remote OST with nodsh"
11898
11899         reset_async
11900
11901         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11902         set_nodes_failloc "$(osts_nodes)" 0x20e
11903
11904         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11905         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11906         PID=$!
11907         sleep 5
11908         set_nodes_failloc "$(osts_nodes)" 0
11909
11910         wait $PID
11911         RC=$?
11912         if [[ $RC -ne 0 ]]; then
11913                 error "got error, but should be not, rc=$RC"
11914         fi
11915
11916         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11917         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11918         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11919         if [[ $LOCKED -ne 0 ]]; then
11920                 error "Locked pages remain in cache, locked=$LOCKED"
11921         fi
11922
11923         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11924                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11925         fi
11926
11927         rm -f $DIR/$tfile
11928         echo "No pages locked after fsync"
11929
11930         return 0
11931 }
11932 run_test 118i "Fix error before timeout in recoverable error  =========="
11933
11934 [ "$SLOW" = "no" ] && set_resend_count 4
11935
11936 test_118j() {
11937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11938         remote_ost_nodsh && skip "remote OST with nodsh"
11939
11940         reset_async
11941
11942         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11943         set_nodes_failloc "$(osts_nodes)" 0x220
11944
11945         # return -EIO from OST
11946         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11947         RC=$?
11948         set_nodes_failloc "$(osts_nodes)" 0x0
11949         if [[ $RC -eq 0 ]]; then
11950                 error "Must return error due to dropped pages, rc=$RC"
11951         fi
11952
11953         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11954         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11955         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11956         if [[ $LOCKED -ne 0 ]]; then
11957                 error "Locked pages remain in cache, locked=$LOCKED"
11958         fi
11959
11960         # in recoverable error on OST we want resend and stay until it finished
11961         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11962                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11963         fi
11964
11965         rm -f $DIR/$tfile
11966         echo "No pages locked after fsync"
11967
11968         return 0
11969 }
11970 run_test 118j "Simulate unrecoverable OST side error =========="
11971
11972 test_118k()
11973 {
11974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11975         remote_ost_nodsh && skip "remote OSTs with nodsh"
11976
11977         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11978         set_nodes_failloc "$(osts_nodes)" 0x20e
11979         test_mkdir $DIR/$tdir
11980
11981         for ((i=0;i<10;i++)); do
11982                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11983                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11984                 SLEEPPID=$!
11985                 sleep 0.500s
11986                 kill $SLEEPPID
11987                 wait $SLEEPPID
11988         done
11989
11990         set_nodes_failloc "$(osts_nodes)" 0
11991         rm -rf $DIR/$tdir
11992 }
11993 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11994
11995 test_118l() # LU-646
11996 {
11997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11998
11999         test_mkdir $DIR/$tdir
12000         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12001         rm -rf $DIR/$tdir
12002 }
12003 run_test 118l "fsync dir"
12004
12005 test_118m() # LU-3066
12006 {
12007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12008
12009         test_mkdir $DIR/$tdir
12010         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12011         rm -rf $DIR/$tdir
12012 }
12013 run_test 118m "fdatasync dir ========="
12014
12015 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12016
12017 test_118n()
12018 {
12019         local begin
12020         local end
12021
12022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12023         remote_ost_nodsh && skip "remote OSTs with nodsh"
12024
12025         # Sleep to avoid a cached response.
12026         #define OBD_STATFS_CACHE_SECONDS 1
12027         sleep 2
12028
12029         # Inject a 10 second delay in the OST_STATFS handler.
12030         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12031         set_nodes_failloc "$(osts_nodes)" 0x242
12032
12033         begin=$SECONDS
12034         stat --file-system $MOUNT > /dev/null
12035         end=$SECONDS
12036
12037         set_nodes_failloc "$(osts_nodes)" 0
12038
12039         if ((end - begin > 20)); then
12040             error "statfs took $((end - begin)) seconds, expected 10"
12041         fi
12042 }
12043 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12044
12045 test_119a() # bug 11737
12046 {
12047         BSIZE=$((512 * 1024))
12048         directio write $DIR/$tfile 0 1 $BSIZE
12049         # We ask to read two blocks, which is more than a file size.
12050         # directio will indicate an error when requested and actual
12051         # sizes aren't equeal (a normal situation in this case) and
12052         # print actual read amount.
12053         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12054         if [ "$NOB" != "$BSIZE" ]; then
12055                 error "read $NOB bytes instead of $BSIZE"
12056         fi
12057         rm -f $DIR/$tfile
12058 }
12059 run_test 119a "Short directIO read must return actual read amount"
12060
12061 test_119b() # bug 11737
12062 {
12063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12064
12065         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12066         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12067         sync
12068         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12069                 error "direct read failed"
12070         rm -f $DIR/$tfile
12071 }
12072 run_test 119b "Sparse directIO read must return actual read amount"
12073
12074 test_119c() # bug 13099
12075 {
12076         BSIZE=1048576
12077         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12078         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12079         rm -f $DIR/$tfile
12080 }
12081 run_test 119c "Testing for direct read hitting hole"
12082
12083 test_119d() # bug 15950
12084 {
12085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12086
12087         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12088         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12089         BSIZE=1048576
12090         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12091         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12092         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12093         lctl set_param fail_loc=0x40d
12094         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12095         pid_dio=$!
12096         sleep 1
12097         cat $DIR/$tfile > /dev/null &
12098         lctl set_param fail_loc=0
12099         pid_reads=$!
12100         wait $pid_dio
12101         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12102         sleep 2
12103         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12104         error "the read rpcs have not completed in 2s"
12105         rm -f $DIR/$tfile
12106         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12107 }
12108 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12109
12110 test_120a() {
12111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12112         remote_mds_nodsh && skip "remote MDS with nodsh"
12113         test_mkdir -i0 -c1 $DIR/$tdir
12114         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12115                 skip_env "no early lock cancel on server"
12116
12117         lru_resize_disable mdc
12118         lru_resize_disable osc
12119         cancel_lru_locks mdc
12120         # asynchronous object destroy at MDT could cause bl ast to client
12121         cancel_lru_locks osc
12122
12123         stat $DIR/$tdir > /dev/null
12124         can1=$(do_facet mds1 \
12125                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12126                awk '/ldlm_cancel/ {print $2}')
12127         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12128                awk '/ldlm_bl_callback/ {print $2}')
12129         test_mkdir -i0 -c1 $DIR/$tdir/d1
12130         can2=$(do_facet mds1 \
12131                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12132                awk '/ldlm_cancel/ {print $2}')
12133         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12134                awk '/ldlm_bl_callback/ {print $2}')
12135         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12136         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12137         lru_resize_enable mdc
12138         lru_resize_enable osc
12139 }
12140 run_test 120a "Early Lock Cancel: mkdir test"
12141
12142 test_120b() {
12143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12144         remote_mds_nodsh && skip "remote MDS with nodsh"
12145         test_mkdir $DIR/$tdir
12146         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12147                 skip_env "no early lock cancel on server"
12148
12149         lru_resize_disable mdc
12150         lru_resize_disable osc
12151         cancel_lru_locks mdc
12152         stat $DIR/$tdir > /dev/null
12153         can1=$(do_facet $SINGLEMDS \
12154                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12155                awk '/ldlm_cancel/ {print $2}')
12156         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12157                awk '/ldlm_bl_callback/ {print $2}')
12158         touch $DIR/$tdir/f1
12159         can2=$(do_facet $SINGLEMDS \
12160                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12161                awk '/ldlm_cancel/ {print $2}')
12162         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12163                awk '/ldlm_bl_callback/ {print $2}')
12164         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12165         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12166         lru_resize_enable mdc
12167         lru_resize_enable osc
12168 }
12169 run_test 120b "Early Lock Cancel: create test"
12170
12171 test_120c() {
12172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12173         remote_mds_nodsh && skip "remote MDS with nodsh"
12174         test_mkdir -i0 -c1 $DIR/$tdir
12175         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12176                 skip "no early lock cancel on server"
12177
12178         lru_resize_disable mdc
12179         lru_resize_disable osc
12180         test_mkdir -i0 -c1 $DIR/$tdir/d1
12181         test_mkdir -i0 -c1 $DIR/$tdir/d2
12182         touch $DIR/$tdir/d1/f1
12183         cancel_lru_locks mdc
12184         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12185         can1=$(do_facet mds1 \
12186                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12187                awk '/ldlm_cancel/ {print $2}')
12188         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12189                awk '/ldlm_bl_callback/ {print $2}')
12190         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12191         can2=$(do_facet mds1 \
12192                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12193                awk '/ldlm_cancel/ {print $2}')
12194         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12195                awk '/ldlm_bl_callback/ {print $2}')
12196         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12197         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12198         lru_resize_enable mdc
12199         lru_resize_enable osc
12200 }
12201 run_test 120c "Early Lock Cancel: link test"
12202
12203 test_120d() {
12204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12205         remote_mds_nodsh && skip "remote MDS with nodsh"
12206         test_mkdir -i0 -c1 $DIR/$tdir
12207         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12208                 skip_env "no early lock cancel on server"
12209
12210         lru_resize_disable mdc
12211         lru_resize_disable osc
12212         touch $DIR/$tdir
12213         cancel_lru_locks mdc
12214         stat $DIR/$tdir > /dev/null
12215         can1=$(do_facet mds1 \
12216                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12217                awk '/ldlm_cancel/ {print $2}')
12218         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12219                awk '/ldlm_bl_callback/ {print $2}')
12220         chmod a+x $DIR/$tdir
12221         can2=$(do_facet mds1 \
12222                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12223                awk '/ldlm_cancel/ {print $2}')
12224         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12225                awk '/ldlm_bl_callback/ {print $2}')
12226         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12227         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12228         lru_resize_enable mdc
12229         lru_resize_enable osc
12230 }
12231 run_test 120d "Early Lock Cancel: setattr test"
12232
12233 test_120e() {
12234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12235         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12236                 skip_env "no early lock cancel on server"
12237         remote_mds_nodsh && skip "remote MDS with nodsh"
12238
12239         local dlmtrace_set=false
12240
12241         test_mkdir -i0 -c1 $DIR/$tdir
12242         lru_resize_disable mdc
12243         lru_resize_disable osc
12244         ! $LCTL get_param debug | grep -q dlmtrace &&
12245                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12246         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12247         cancel_lru_locks mdc
12248         cancel_lru_locks osc
12249         dd if=$DIR/$tdir/f1 of=/dev/null
12250         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12251         # XXX client can not do early lock cancel of OST lock
12252         # during unlink (LU-4206), so cancel osc lock now.
12253         sleep 2
12254         cancel_lru_locks osc
12255         can1=$(do_facet mds1 \
12256                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12257                awk '/ldlm_cancel/ {print $2}')
12258         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12259                awk '/ldlm_bl_callback/ {print $2}')
12260         unlink $DIR/$tdir/f1
12261         sleep 5
12262         can2=$(do_facet mds1 \
12263                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12264                awk '/ldlm_cancel/ {print $2}')
12265         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12266                awk '/ldlm_bl_callback/ {print $2}')
12267         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12268                 $LCTL dk $TMP/cancel.debug.txt
12269         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12270                 $LCTL dk $TMP/blocking.debug.txt
12271         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12272         lru_resize_enable mdc
12273         lru_resize_enable osc
12274 }
12275 run_test 120e "Early Lock Cancel: unlink test"
12276
12277 test_120f() {
12278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12279         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12280                 skip_env "no early lock cancel on server"
12281         remote_mds_nodsh && skip "remote MDS with nodsh"
12282
12283         test_mkdir -i0 -c1 $DIR/$tdir
12284         lru_resize_disable mdc
12285         lru_resize_disable osc
12286         test_mkdir -i0 -c1 $DIR/$tdir/d1
12287         test_mkdir -i0 -c1 $DIR/$tdir/d2
12288         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12289         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12290         cancel_lru_locks mdc
12291         cancel_lru_locks osc
12292         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12293         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12294         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12295         # XXX client can not do early lock cancel of OST lock
12296         # during rename (LU-4206), so cancel osc lock now.
12297         sleep 2
12298         cancel_lru_locks osc
12299         can1=$(do_facet mds1 \
12300                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12301                awk '/ldlm_cancel/ {print $2}')
12302         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12303                awk '/ldlm_bl_callback/ {print $2}')
12304         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12305         sleep 5
12306         can2=$(do_facet mds1 \
12307                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12308                awk '/ldlm_cancel/ {print $2}')
12309         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12310                awk '/ldlm_bl_callback/ {print $2}')
12311         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12312         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12313         lru_resize_enable mdc
12314         lru_resize_enable osc
12315 }
12316 run_test 120f "Early Lock Cancel: rename test"
12317
12318 test_120g() {
12319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12320         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12321                 skip_env "no early lock cancel on server"
12322         remote_mds_nodsh && skip "remote MDS with nodsh"
12323
12324         lru_resize_disable mdc
12325         lru_resize_disable osc
12326         count=10000
12327         echo create $count files
12328         test_mkdir $DIR/$tdir
12329         cancel_lru_locks mdc
12330         cancel_lru_locks osc
12331         t0=$(date +%s)
12332
12333         can0=$(do_facet $SINGLEMDS \
12334                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12335                awk '/ldlm_cancel/ {print $2}')
12336         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12337                awk '/ldlm_bl_callback/ {print $2}')
12338         createmany -o $DIR/$tdir/f $count
12339         sync
12340         can1=$(do_facet $SINGLEMDS \
12341                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12342                awk '/ldlm_cancel/ {print $2}')
12343         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12344                awk '/ldlm_bl_callback/ {print $2}')
12345         t1=$(date +%s)
12346         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12347         echo rm $count files
12348         rm -r $DIR/$tdir
12349         sync
12350         can2=$(do_facet $SINGLEMDS \
12351                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12352                awk '/ldlm_cancel/ {print $2}')
12353         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12354                awk '/ldlm_bl_callback/ {print $2}')
12355         t2=$(date +%s)
12356         echo total: $count removes in $((t2-t1))
12357         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12358         sleep 2
12359         # wait for commitment of removal
12360         lru_resize_enable mdc
12361         lru_resize_enable osc
12362 }
12363 run_test 120g "Early Lock Cancel: performance test"
12364
12365 test_121() { #bug #10589
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367
12368         rm -rf $DIR/$tfile
12369         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12370 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12371         lctl set_param fail_loc=0x310
12372         cancel_lru_locks osc > /dev/null
12373         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12374         lctl set_param fail_loc=0
12375         [[ $reads -eq $writes ]] ||
12376                 error "read $reads blocks, must be $writes blocks"
12377 }
12378 run_test 121 "read cancel race ========="
12379
12380 test_123a_base() { # was test 123, statahead(bug 11401)
12381         local lsx="$1"
12382
12383         SLOWOK=0
12384         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12385                 log "testing UP system. Performance may be lower than expected."
12386                 SLOWOK=1
12387         fi
12388
12389         rm -rf $DIR/$tdir
12390         test_mkdir $DIR/$tdir
12391         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12392         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12393         MULT=10
12394         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12395                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12396
12397                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12398                 lctl set_param -n llite.*.statahead_max 0
12399                 lctl get_param llite.*.statahead_max
12400                 cancel_lru_locks mdc
12401                 cancel_lru_locks osc
12402                 stime=$(date +%s)
12403                 time $lsx $DIR/$tdir | wc -l
12404                 etime=$(date +%s)
12405                 delta=$((etime - stime))
12406                 log "$lsx $i files without statahead: $delta sec"
12407                 lctl set_param llite.*.statahead_max=$max
12408
12409                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12410                         grep "statahead wrong:" | awk '{print $3}')
12411                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12412                 cancel_lru_locks mdc
12413                 cancel_lru_locks osc
12414                 stime=$(date +%s)
12415                 time $lsx $DIR/$tdir | wc -l
12416                 etime=$(date +%s)
12417                 delta_sa=$((etime - stime))
12418                 log "$lsx $i files with statahead: $delta_sa sec"
12419                 lctl get_param -n llite.*.statahead_stats
12420                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12421                         grep "statahead wrong:" | awk '{print $3}')
12422
12423                 [[ $swrong -lt $ewrong ]] &&
12424                         log "statahead was stopped, maybe too many locks held!"
12425                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12426
12427                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12428                         max=$(lctl get_param -n llite.*.statahead_max |
12429                                 head -n 1)
12430                         lctl set_param -n llite.*.statahead_max 0
12431                         lctl get_param llite.*.statahead_max
12432                         cancel_lru_locks mdc
12433                         cancel_lru_locks osc
12434                         stime=$(date +%s)
12435                         time $lsx $DIR/$tdir | wc -l
12436                         etime=$(date +%s)
12437                         delta=$((etime - stime))
12438                         log "$lsx $i files again without statahead: $delta sec"
12439                         lctl set_param llite.*.statahead_max=$max
12440                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12441                                 if [  $SLOWOK -eq 0 ]; then
12442                                         error "$lsx $i files is slower with statahead!"
12443                                 else
12444                                         log "$lsx $i files is slower with statahead!"
12445                                 fi
12446                                 break
12447                         fi
12448                 fi
12449
12450                 [ $delta -gt 20 ] && break
12451                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12452                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12453         done
12454         log "$lsx done"
12455
12456         stime=$(date +%s)
12457         rm -r $DIR/$tdir
12458         sync
12459         etime=$(date +%s)
12460         delta=$((etime - stime))
12461         log "rm -r $DIR/$tdir/: $delta seconds"
12462         log "rm done"
12463         lctl get_param -n llite.*.statahead_stats
12464 }
12465
12466 test_123aa() {
12467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12468
12469         test_123a_base "ls -l"
12470 }
12471 run_test 123aa "verify statahead work"
12472
12473 test_123ab() {
12474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12475
12476         statx_supported || skip_env "Test must be statx() syscall supported"
12477
12478         test_123a_base "$STATX -l"
12479 }
12480 run_test 123ab "verify statahead work by using statx"
12481
12482 test_123ac() {
12483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12484
12485         statx_supported || skip_env "Test must be statx() syscall supported"
12486
12487         local rpcs_before
12488         local rpcs_after
12489         local agl_before
12490         local agl_after
12491
12492         cancel_lru_locks $OSC
12493         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12494         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12495                 awk '/agl.total:/ {print $3}')
12496         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12497         test_123a_base "$STATX --cached=always -D"
12498         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12499                 awk '/agl.total:/ {print $3}')
12500         [ $agl_before -eq $agl_after ] ||
12501                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12502         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12503         [ $rpcs_after -eq $rpcs_before ] ||
12504                 error "$STATX should not send glimpse RPCs to $OSC"
12505 }
12506 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12507
12508 test_123b () { # statahead(bug 15027)
12509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12510
12511         test_mkdir $DIR/$tdir
12512         createmany -o $DIR/$tdir/$tfile-%d 1000
12513
12514         cancel_lru_locks mdc
12515         cancel_lru_locks osc
12516
12517 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12518         lctl set_param fail_loc=0x80000803
12519         ls -lR $DIR/$tdir > /dev/null
12520         log "ls done"
12521         lctl set_param fail_loc=0x0
12522         lctl get_param -n llite.*.statahead_stats
12523         rm -r $DIR/$tdir
12524         sync
12525
12526 }
12527 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12528
12529 test_123c() {
12530         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12531
12532         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12533         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12534         touch $DIR/$tdir.1/{1..3}
12535         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12536
12537         remount_client $MOUNT
12538
12539         $MULTIOP $DIR/$tdir.0 Q
12540
12541         # let statahead to complete
12542         ls -l $DIR/$tdir.0 > /dev/null
12543
12544         testid=$(echo $TESTNAME | tr '_' ' ')
12545         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12546                 error "statahead warning" || true
12547 }
12548 run_test 123c "Can not initialize inode warning on DNE statahead"
12549
12550 test_124a() {
12551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12552         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12553                 skip_env "no lru resize on server"
12554
12555         local NR=2000
12556
12557         test_mkdir $DIR/$tdir
12558
12559         log "create $NR files at $DIR/$tdir"
12560         createmany -o $DIR/$tdir/f $NR ||
12561                 error "failed to create $NR files in $DIR/$tdir"
12562
12563         cancel_lru_locks mdc
12564         ls -l $DIR/$tdir > /dev/null
12565
12566         local NSDIR=""
12567         local LRU_SIZE=0
12568         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12569                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12570                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12571                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12572                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12573                         log "NSDIR=$NSDIR"
12574                         log "NS=$(basename $NSDIR)"
12575                         break
12576                 fi
12577         done
12578
12579         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12580                 skip "Not enough cached locks created!"
12581         fi
12582         log "LRU=$LRU_SIZE"
12583
12584         local SLEEP=30
12585
12586         # We know that lru resize allows one client to hold $LIMIT locks
12587         # for 10h. After that locks begin to be killed by client.
12588         local MAX_HRS=10
12589         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12590         log "LIMIT=$LIMIT"
12591         if [ $LIMIT -lt $LRU_SIZE ]; then
12592                 skip "Limit is too small $LIMIT"
12593         fi
12594
12595         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12596         # killing locks. Some time was spent for creating locks. This means
12597         # that up to the moment of sleep finish we must have killed some of
12598         # them (10-100 locks). This depends on how fast ther were created.
12599         # Many of them were touched in almost the same moment and thus will
12600         # be killed in groups.
12601         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12602
12603         # Use $LRU_SIZE_B here to take into account real number of locks
12604         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12605         local LRU_SIZE_B=$LRU_SIZE
12606         log "LVF=$LVF"
12607         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12608         log "OLD_LVF=$OLD_LVF"
12609         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12610
12611         # Let's make sure that we really have some margin. Client checks
12612         # cached locks every 10 sec.
12613         SLEEP=$((SLEEP+20))
12614         log "Sleep ${SLEEP} sec"
12615         local SEC=0
12616         while ((SEC<$SLEEP)); do
12617                 echo -n "..."
12618                 sleep 5
12619                 SEC=$((SEC+5))
12620                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12621                 echo -n "$LRU_SIZE"
12622         done
12623         echo ""
12624         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12625         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12626
12627         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12628                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12629                 unlinkmany $DIR/$tdir/f $NR
12630                 return
12631         }
12632
12633         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12634         log "unlink $NR files at $DIR/$tdir"
12635         unlinkmany $DIR/$tdir/f $NR
12636 }
12637 run_test 124a "lru resize ======================================="
12638
12639 get_max_pool_limit()
12640 {
12641         local limit=$($LCTL get_param \
12642                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12643         local max=0
12644         for l in $limit; do
12645                 if [[ $l -gt $max ]]; then
12646                         max=$l
12647                 fi
12648         done
12649         echo $max
12650 }
12651
12652 test_124b() {
12653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12654         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12655                 skip_env "no lru resize on server"
12656
12657         LIMIT=$(get_max_pool_limit)
12658
12659         NR=$(($(default_lru_size)*20))
12660         if [[ $NR -gt $LIMIT ]]; then
12661                 log "Limit lock number by $LIMIT locks"
12662                 NR=$LIMIT
12663         fi
12664
12665         IFree=$(mdsrate_inodes_available)
12666         if [ $IFree -lt $NR ]; then
12667                 log "Limit lock number by $IFree inodes"
12668                 NR=$IFree
12669         fi
12670
12671         lru_resize_disable mdc
12672         test_mkdir -p $DIR/$tdir/disable_lru_resize
12673
12674         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12675         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12676         cancel_lru_locks mdc
12677         stime=`date +%s`
12678         PID=""
12679         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12680         PID="$PID $!"
12681         sleep 2
12682         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12683         PID="$PID $!"
12684         sleep 2
12685         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12686         PID="$PID $!"
12687         wait $PID
12688         etime=`date +%s`
12689         nolruresize_delta=$((etime-stime))
12690         log "ls -la time: $nolruresize_delta seconds"
12691         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12692         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12693
12694         lru_resize_enable mdc
12695         test_mkdir -p $DIR/$tdir/enable_lru_resize
12696
12697         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12698         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12699         cancel_lru_locks mdc
12700         stime=`date +%s`
12701         PID=""
12702         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12703         PID="$PID $!"
12704         sleep 2
12705         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12706         PID="$PID $!"
12707         sleep 2
12708         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12709         PID="$PID $!"
12710         wait $PID
12711         etime=`date +%s`
12712         lruresize_delta=$((etime-stime))
12713         log "ls -la time: $lruresize_delta seconds"
12714         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12715
12716         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12717                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12718         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12719                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12720         else
12721                 log "lru resize performs the same with no lru resize"
12722         fi
12723         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12724 }
12725 run_test 124b "lru resize (performance test) ======================="
12726
12727 test_124c() {
12728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12729         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12730                 skip_env "no lru resize on server"
12731
12732         # cache ununsed locks on client
12733         local nr=100
12734         cancel_lru_locks mdc
12735         test_mkdir $DIR/$tdir
12736         createmany -o $DIR/$tdir/f $nr ||
12737                 error "failed to create $nr files in $DIR/$tdir"
12738         ls -l $DIR/$tdir > /dev/null
12739
12740         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12741         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12742         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12743         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12744         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12745
12746         # set lru_max_age to 1 sec
12747         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12748         echo "sleep $((recalc_p * 2)) seconds..."
12749         sleep $((recalc_p * 2))
12750
12751         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12752         # restore lru_max_age
12753         $LCTL set_param -n $nsdir.lru_max_age $max_age
12754         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12755         unlinkmany $DIR/$tdir/f $nr
12756 }
12757 run_test 124c "LRUR cancel very aged locks"
12758
12759 test_124d() {
12760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12761         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12762                 skip_env "no lru resize on server"
12763
12764         # cache ununsed locks on client
12765         local nr=100
12766
12767         lru_resize_disable mdc
12768         stack_trap "lru_resize_enable mdc" EXIT
12769
12770         cancel_lru_locks mdc
12771
12772         # asynchronous object destroy at MDT could cause bl ast to client
12773         test_mkdir $DIR/$tdir
12774         createmany -o $DIR/$tdir/f $nr ||
12775                 error "failed to create $nr files in $DIR/$tdir"
12776         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12777
12778         ls -l $DIR/$tdir > /dev/null
12779
12780         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12781         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12782         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12783         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12784
12785         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12786
12787         # set lru_max_age to 1 sec
12788         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12789         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12790
12791         echo "sleep $((recalc_p * 2)) seconds..."
12792         sleep $((recalc_p * 2))
12793
12794         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12795
12796         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12797 }
12798 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12799
12800 test_125() { # 13358
12801         $LCTL get_param -n llite.*.client_type | grep -q local ||
12802                 skip "must run as local client"
12803         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12804                 skip_env "must have acl enabled"
12805         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12806
12807         test_mkdir $DIR/$tdir
12808         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12809         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12810         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12811 }
12812 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12813
12814 test_126() { # bug 12829/13455
12815         $GSS && skip_env "must run as gss disabled"
12816         $LCTL get_param -n llite.*.client_type | grep -q local ||
12817                 skip "must run as local client"
12818         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12819
12820         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12821         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12822         rm -f $DIR/$tfile
12823         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12824 }
12825 run_test 126 "check that the fsgid provided by the client is taken into account"
12826
12827 test_127a() { # bug 15521
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829         local name count samp unit min max sum sumsq
12830
12831         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12832         echo "stats before reset"
12833         $LCTL get_param osc.*.stats
12834         $LCTL set_param osc.*.stats=0
12835         local fsize=$((2048 * 1024))
12836
12837         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12838         cancel_lru_locks osc
12839         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12840
12841         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12842         stack_trap "rm -f $TMP/$tfile.tmp"
12843         while read name count samp unit min max sum sumsq; do
12844                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12845                 [ ! $min ] && error "Missing min value for $name proc entry"
12846                 eval $name=$count || error "Wrong proc format"
12847
12848                 case $name in
12849                 read_bytes|write_bytes)
12850                         [[ "$unit" =~ "bytes" ]] ||
12851                                 error "unit is not 'bytes': $unit"
12852                         (( $min >= 4096 )) || error "min is too small: $min"
12853                         (( $min <= $fsize )) || error "min is too big: $min"
12854                         (( $max >= 4096 )) || error "max is too small: $max"
12855                         (( $max <= $fsize )) || error "max is too big: $max"
12856                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12857                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12858                                 error "sumsquare is too small: $sumsq"
12859                         (( $sumsq <= $fsize * $fsize )) ||
12860                                 error "sumsquare is too big: $sumsq"
12861                         ;;
12862                 ost_read|ost_write)
12863                         [[ "$unit" =~ "usec" ]] ||
12864                                 error "unit is not 'usec': $unit"
12865                         ;;
12866                 *)      ;;
12867                 esac
12868         done < $DIR/$tfile.tmp
12869
12870         #check that we actually got some stats
12871         [ "$read_bytes" ] || error "Missing read_bytes stats"
12872         [ "$write_bytes" ] || error "Missing write_bytes stats"
12873         [ "$read_bytes" != 0 ] || error "no read done"
12874         [ "$write_bytes" != 0 ] || error "no write done"
12875 }
12876 run_test 127a "verify the client stats are sane"
12877
12878 test_127b() { # bug LU-333
12879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12880         local name count samp unit min max sum sumsq
12881
12882         echo "stats before reset"
12883         $LCTL get_param llite.*.stats
12884         $LCTL set_param llite.*.stats=0
12885
12886         # perform 2 reads and writes so MAX is different from SUM.
12887         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12888         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12889         cancel_lru_locks osc
12890         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12891         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12892
12893         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12894         stack_trap "rm -f $TMP/$tfile.tmp"
12895         while read name count samp unit min max sum sumsq; do
12896                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12897                 eval $name=$count || error "Wrong proc format"
12898
12899                 case $name in
12900                 read_bytes|write_bytes)
12901                         [[ "$unit" =~ "bytes" ]] ||
12902                                 error "unit is not 'bytes': $unit"
12903                         (( $count == 2 )) || error "count is not 2: $count"
12904                         (( $min == $PAGE_SIZE )) ||
12905                                 error "min is not $PAGE_SIZE: $min"
12906                         (( $max == $PAGE_SIZE )) ||
12907                                 error "max is not $PAGE_SIZE: $max"
12908                         (( $sum == $PAGE_SIZE * 2 )) ||
12909                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12910                         ;;
12911                 read|write)
12912                         [[ "$unit" =~ "usec" ]] ||
12913                                 error "unit is not 'usec': $unit"
12914                         ;;
12915                 *)      ;;
12916                 esac
12917         done < $TMP/$tfile.tmp
12918
12919         #check that we actually got some stats
12920         [ "$read_bytes" ] || error "Missing read_bytes stats"
12921         [ "$write_bytes" ] || error "Missing write_bytes stats"
12922         [ "$read_bytes" != 0 ] || error "no read done"
12923         [ "$write_bytes" != 0 ] || error "no write done"
12924 }
12925 run_test 127b "verify the llite client stats are sane"
12926
12927 test_127c() { # LU-12394
12928         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12929         local size
12930         local bsize
12931         local reads
12932         local writes
12933         local count
12934
12935         $LCTL set_param llite.*.extents_stats=1
12936         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12937
12938         # Use two stripes so there is enough space in default config
12939         $LFS setstripe -c 2 $DIR/$tfile
12940
12941         # Extent stats start at 0-4K and go in power of two buckets
12942         # LL_HIST_START = 12 --> 2^12 = 4K
12943         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12944         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12945         # small configs
12946         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12947                 do
12948                 # Write and read, 2x each, second time at a non-zero offset
12949                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12950                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12951                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12952                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12953                 rm -f $DIR/$tfile
12954         done
12955
12956         $LCTL get_param llite.*.extents_stats
12957
12958         count=2
12959         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12960                 do
12961                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12962                                 grep -m 1 $bsize)
12963                 reads=$(echo $bucket | awk '{print $5}')
12964                 writes=$(echo $bucket | awk '{print $9}')
12965                 [ "$reads" -eq $count ] ||
12966                         error "$reads reads in < $bsize bucket, expect $count"
12967                 [ "$writes" -eq $count ] ||
12968                         error "$writes writes in < $bsize bucket, expect $count"
12969         done
12970
12971         # Test mmap write and read
12972         $LCTL set_param llite.*.extents_stats=c
12973         size=512
12974         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12975         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12976         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12977
12978         $LCTL get_param llite.*.extents_stats
12979
12980         count=$(((size*1024) / PAGE_SIZE))
12981
12982         bsize=$((2 * PAGE_SIZE / 1024))K
12983
12984         bucket=$($LCTL get_param -n llite.*.extents_stats |
12985                         grep -m 1 $bsize)
12986         reads=$(echo $bucket | awk '{print $5}')
12987         writes=$(echo $bucket | awk '{print $9}')
12988         # mmap writes fault in the page first, creating an additonal read
12989         [ "$reads" -eq $((2 * count)) ] ||
12990                 error "$reads reads in < $bsize bucket, expect $count"
12991         [ "$writes" -eq $count ] ||
12992                 error "$writes writes in < $bsize bucket, expect $count"
12993 }
12994 run_test 127c "test llite extent stats with regular & mmap i/o"
12995
12996 test_128() { # bug 15212
12997         touch $DIR/$tfile
12998         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12999                 find $DIR/$tfile
13000                 find $DIR/$tfile
13001         EOF
13002
13003         result=$(grep error $TMP/$tfile.log)
13004         rm -f $DIR/$tfile $TMP/$tfile.log
13005         [ -z "$result" ] ||
13006                 error "consecutive find's under interactive lfs failed"
13007 }
13008 run_test 128 "interactive lfs for 2 consecutive find's"
13009
13010 set_dir_limits () {
13011         local mntdev
13012         local canondev
13013         local node
13014
13015         local ldproc=/proc/fs/ldiskfs
13016         local facets=$(get_facets MDS)
13017
13018         for facet in ${facets//,/ }; do
13019                 canondev=$(ldiskfs_canon \
13020                            *.$(convert_facet2label $facet).mntdev $facet)
13021                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13022                         ldproc=/sys/fs/ldiskfs
13023                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13024                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13025         done
13026 }
13027
13028 check_mds_dmesg() {
13029         local facets=$(get_facets MDS)
13030         for facet in ${facets//,/ }; do
13031                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13032         done
13033         return 1
13034 }
13035
13036 test_129() {
13037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13038         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13039                 skip "Need MDS version with at least 2.5.56"
13040         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13041                 skip_env "ldiskfs only test"
13042         fi
13043         remote_mds_nodsh && skip "remote MDS with nodsh"
13044
13045         local ENOSPC=28
13046         local has_warning=false
13047
13048         rm -rf $DIR/$tdir
13049         mkdir -p $DIR/$tdir
13050
13051         # block size of mds1
13052         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13053         set_dir_limits $maxsize $((maxsize * 6 / 8))
13054         stack_trap "set_dir_limits 0 0"
13055         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13056         local dirsize=$(stat -c%s "$DIR/$tdir")
13057         local nfiles=0
13058         while (( $dirsize <= $maxsize )); do
13059                 $MCREATE $DIR/$tdir/file_base_$nfiles
13060                 rc=$?
13061                 # check two errors:
13062                 # ENOSPC for ext4 max_dir_size, which has been used since
13063                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13064                 if (( rc == ENOSPC )); then
13065                         set_dir_limits 0 0
13066                         echo "rc=$rc returned as expected after $nfiles files"
13067
13068                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13069                                 error "create failed w/o dir size limit"
13070
13071                         # messages may be rate limited if test is run repeatedly
13072                         check_mds_dmesg '"is approaching max"' ||
13073                                 echo "warning message should be output"
13074                         check_mds_dmesg '"has reached max"' ||
13075                                 echo "reached message should be output"
13076
13077                         dirsize=$(stat -c%s "$DIR/$tdir")
13078
13079                         [[ $dirsize -ge $maxsize ]] && return 0
13080                         error "dirsize $dirsize < $maxsize after $nfiles files"
13081                 elif (( rc != 0 )); then
13082                         break
13083                 fi
13084                 nfiles=$((nfiles + 1))
13085                 dirsize=$(stat -c%s "$DIR/$tdir")
13086         done
13087
13088         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13089 }
13090 run_test 129 "test directory size limit ========================"
13091
13092 OLDIFS="$IFS"
13093 cleanup_130() {
13094         trap 0
13095         IFS="$OLDIFS"
13096 }
13097
13098 test_130a() {
13099         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13100         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13101
13102         trap cleanup_130 EXIT RETURN
13103
13104         local fm_file=$DIR/$tfile
13105         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13106         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13107                 error "dd failed for $fm_file"
13108
13109         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13110         filefrag -ves $fm_file
13111         RC=$?
13112         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13113                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13114         [ $RC != 0 ] && error "filefrag $fm_file failed"
13115
13116         filefrag_op=$(filefrag -ve -k $fm_file |
13117                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13118         lun=$($LFS getstripe -i $fm_file)
13119
13120         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13121         IFS=$'\n'
13122         tot_len=0
13123         for line in $filefrag_op
13124         do
13125                 frag_lun=`echo $line | cut -d: -f5`
13126                 ext_len=`echo $line | cut -d: -f4`
13127                 if (( $frag_lun != $lun )); then
13128                         cleanup_130
13129                         error "FIEMAP on 1-stripe file($fm_file) failed"
13130                         return
13131                 fi
13132                 (( tot_len += ext_len ))
13133         done
13134
13135         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13136                 cleanup_130
13137                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13138                 return
13139         fi
13140
13141         cleanup_130
13142
13143         echo "FIEMAP on single striped file succeeded"
13144 }
13145 run_test 130a "FIEMAP (1-stripe file)"
13146
13147 test_130b() {
13148         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13149
13150         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13151         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13152
13153         trap cleanup_130 EXIT RETURN
13154
13155         local fm_file=$DIR/$tfile
13156         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13157                         error "setstripe on $fm_file"
13158         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13159                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13160
13161         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13162                 error "dd failed on $fm_file"
13163
13164         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13165         filefrag_op=$(filefrag -ve -k $fm_file |
13166                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13167
13168         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13169                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13170
13171         IFS=$'\n'
13172         tot_len=0
13173         num_luns=1
13174         for line in $filefrag_op
13175         do
13176                 frag_lun=$(echo $line | cut -d: -f5 |
13177                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13178                 ext_len=$(echo $line | cut -d: -f4)
13179                 if (( $frag_lun != $last_lun )); then
13180                         if (( tot_len != 1024 )); then
13181                                 cleanup_130
13182                                 error "FIEMAP on $fm_file failed; returned " \
13183                                 "len $tot_len for OST $last_lun instead of 1024"
13184                                 return
13185                         else
13186                                 (( num_luns += 1 ))
13187                                 tot_len=0
13188                         fi
13189                 fi
13190                 (( tot_len += ext_len ))
13191                 last_lun=$frag_lun
13192         done
13193         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13194                 cleanup_130
13195                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13196                         "luns or wrong len for OST $last_lun"
13197                 return
13198         fi
13199
13200         cleanup_130
13201
13202         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13203 }
13204 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13205
13206 test_130c() {
13207         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13208
13209         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13210         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13211
13212         trap cleanup_130 EXIT RETURN
13213
13214         local fm_file=$DIR/$tfile
13215         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13216         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13217                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13218
13219         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13220                         error "dd failed on $fm_file"
13221
13222         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13223         filefrag_op=$(filefrag -ve -k $fm_file |
13224                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13225
13226         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13227                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13228
13229         IFS=$'\n'
13230         tot_len=0
13231         num_luns=1
13232         for line in $filefrag_op
13233         do
13234                 frag_lun=$(echo $line | cut -d: -f5 |
13235                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13236                 ext_len=$(echo $line | cut -d: -f4)
13237                 if (( $frag_lun != $last_lun )); then
13238                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13239                         if (( logical != 512 )); then
13240                                 cleanup_130
13241                                 error "FIEMAP on $fm_file failed; returned " \
13242                                 "logical start for lun $logical instead of 512"
13243                                 return
13244                         fi
13245                         if (( tot_len != 512 )); then
13246                                 cleanup_130
13247                                 error "FIEMAP on $fm_file failed; returned " \
13248                                 "len $tot_len for OST $last_lun instead of 1024"
13249                                 return
13250                         else
13251                                 (( num_luns += 1 ))
13252                                 tot_len=0
13253                         fi
13254                 fi
13255                 (( tot_len += ext_len ))
13256                 last_lun=$frag_lun
13257         done
13258         if (( num_luns != 2 || tot_len != 512 )); then
13259                 cleanup_130
13260                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13261                         "luns or wrong len for OST $last_lun"
13262                 return
13263         fi
13264
13265         cleanup_130
13266
13267         echo "FIEMAP on 2-stripe file with hole succeeded"
13268 }
13269 run_test 130c "FIEMAP (2-stripe file with hole)"
13270
13271 test_130d() {
13272         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13273
13274         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13275         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13276
13277         trap cleanup_130 EXIT RETURN
13278
13279         local fm_file=$DIR/$tfile
13280         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13281                         error "setstripe on $fm_file"
13282         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13283                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13284
13285         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13286         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13287                 error "dd failed on $fm_file"
13288
13289         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13290         filefrag_op=$(filefrag -ve -k $fm_file |
13291                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13292
13293         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13294                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13295
13296         IFS=$'\n'
13297         tot_len=0
13298         num_luns=1
13299         for line in $filefrag_op
13300         do
13301                 frag_lun=$(echo $line | cut -d: -f5 |
13302                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13303                 ext_len=$(echo $line | cut -d: -f4)
13304                 if (( $frag_lun != $last_lun )); then
13305                         if (( tot_len != 1024 )); then
13306                                 cleanup_130
13307                                 error "FIEMAP on $fm_file failed; returned " \
13308                                 "len $tot_len for OST $last_lun instead of 1024"
13309                                 return
13310                         else
13311                                 (( num_luns += 1 ))
13312                                 tot_len=0
13313                         fi
13314                 fi
13315                 (( tot_len += ext_len ))
13316                 last_lun=$frag_lun
13317         done
13318         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13319                 cleanup_130
13320                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13321                         "luns or wrong len for OST $last_lun"
13322                 return
13323         fi
13324
13325         cleanup_130
13326
13327         echo "FIEMAP on N-stripe file succeeded"
13328 }
13329 run_test 130d "FIEMAP (N-stripe file)"
13330
13331 test_130e() {
13332         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13333
13334         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13335         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13336
13337         trap cleanup_130 EXIT RETURN
13338
13339         local fm_file=$DIR/$tfile
13340         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13341
13342         NUM_BLKS=512
13343         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13344         for ((i = 0; i < $NUM_BLKS; i++)); do
13345                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13346                         conv=notrunc > /dev/null 2>&1
13347         done
13348
13349         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13350         filefrag_op=$(filefrag -ve -k $fm_file |
13351                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13352
13353         last_lun=$(echo $filefrag_op | cut -d: -f5)
13354
13355         IFS=$'\n'
13356         tot_len=0
13357         num_luns=1
13358         for line in $filefrag_op; do
13359                 frag_lun=$(echo $line | cut -d: -f5)
13360                 ext_len=$(echo $line | cut -d: -f4)
13361                 if [[ "$frag_lun" != "$last_lun" ]]; then
13362                         if (( tot_len != $EXPECTED_LEN )); then
13363                                 cleanup_130
13364                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13365                         else
13366                                 (( num_luns += 1 ))
13367                                 tot_len=0
13368                         fi
13369                 fi
13370                 (( tot_len += ext_len ))
13371                 last_lun=$frag_lun
13372         done
13373         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13374                 cleanup_130
13375                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13376         fi
13377
13378         echo "FIEMAP with continuation calls succeeded"
13379 }
13380 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13381
13382 test_130f() {
13383         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13384         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13385
13386         local fm_file=$DIR/$tfile
13387         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13388                 error "multiop create with lov_delay_create on $fm_file"
13389
13390         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13391         filefrag_extents=$(filefrag -vek $fm_file |
13392                            awk '/extents? found/ { print $2 }')
13393         if [[ "$filefrag_extents" != "0" ]]; then
13394                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13395         fi
13396
13397         rm -f $fm_file
13398 }
13399 run_test 130f "FIEMAP (unstriped file)"
13400
13401 test_130g() {
13402         local file=$DIR/$tfile
13403         local nr=$((OSTCOUNT * 100))
13404
13405         $LFS setstripe -C $nr $file ||
13406                 error "failed to setstripe -C $nr $file"
13407
13408         dd if=/dev/zero of=$file count=$nr bs=1M
13409         sync
13410         nr=$($LFS getstripe -c $file)
13411
13412         local extents=$(filefrag -v $file |
13413                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13414
13415         echo "filefrag list $extents extents in file with stripecount $nr"
13416         if (( extents < nr )); then
13417                 $LFS getstripe $file
13418                 filefrag -v $file
13419                 error "filefrag printed $extents < $nr extents"
13420         fi
13421
13422         rm -f $file
13423 }
13424 run_test 130g "FIEMAP (overstripe file)"
13425
13426 # Test for writev/readv
13427 test_131a() {
13428         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13429                 error "writev test failed"
13430         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13431                 error "readv failed"
13432         rm -f $DIR/$tfile
13433 }
13434 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13435
13436 test_131b() {
13437         local fsize=$((524288 + 1048576 + 1572864))
13438         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13439                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13440                         error "append writev test failed"
13441
13442         ((fsize += 1572864 + 1048576))
13443         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13444                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13445                         error "append writev test failed"
13446         rm -f $DIR/$tfile
13447 }
13448 run_test 131b "test append writev"
13449
13450 test_131c() {
13451         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13452         error "NOT PASS"
13453 }
13454 run_test 131c "test read/write on file w/o objects"
13455
13456 test_131d() {
13457         rwv -f $DIR/$tfile -w -n 1 1572864
13458         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13459         if [ "$NOB" != 1572864 ]; then
13460                 error "Short read filed: read $NOB bytes instead of 1572864"
13461         fi
13462         rm -f $DIR/$tfile
13463 }
13464 run_test 131d "test short read"
13465
13466 test_131e() {
13467         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13468         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13469         error "read hitting hole failed"
13470         rm -f $DIR/$tfile
13471 }
13472 run_test 131e "test read hitting hole"
13473
13474 check_stats() {
13475         local facet=$1
13476         local op=$2
13477         local want=${3:-0}
13478         local res
13479
13480         case $facet in
13481         mds*) res=$(do_facet $facet \
13482                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13483                  ;;
13484         ost*) res=$(do_facet $facet \
13485                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13486                  ;;
13487         *) error "Wrong facet '$facet'" ;;
13488         esac
13489         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13490         # if the argument $3 is zero, it means any stat increment is ok.
13491         if [[ $want -gt 0 ]]; then
13492                 local count=$(echo $res | awk '{ print $2 }')
13493                 [[ $count -ne $want ]] &&
13494                         error "The $op counter on $facet is $count, not $want"
13495         fi
13496 }
13497
13498 test_133a() {
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500         remote_ost_nodsh && skip "remote OST with nodsh"
13501         remote_mds_nodsh && skip "remote MDS with nodsh"
13502         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13503                 skip_env "MDS doesn't support rename stats"
13504
13505         local testdir=$DIR/${tdir}/stats_testdir
13506
13507         mkdir -p $DIR/${tdir}
13508
13509         # clear stats.
13510         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13511         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13512
13513         # verify mdt stats first.
13514         mkdir ${testdir} || error "mkdir failed"
13515         check_stats $SINGLEMDS "mkdir" 1
13516         touch ${testdir}/${tfile} || error "touch failed"
13517         check_stats $SINGLEMDS "open" 1
13518         check_stats $SINGLEMDS "close" 1
13519         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13520                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13521                 check_stats $SINGLEMDS "mknod" 2
13522         }
13523         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13524         check_stats $SINGLEMDS "unlink" 1
13525         rm -f ${testdir}/${tfile} || error "file remove failed"
13526         check_stats $SINGLEMDS "unlink" 2
13527
13528         # remove working dir and check mdt stats again.
13529         rmdir ${testdir} || error "rmdir failed"
13530         check_stats $SINGLEMDS "rmdir" 1
13531
13532         local testdir1=$DIR/${tdir}/stats_testdir1
13533         mkdir -p ${testdir}
13534         mkdir -p ${testdir1}
13535         touch ${testdir1}/test1
13536         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13537         check_stats $SINGLEMDS "crossdir_rename" 1
13538
13539         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13540         check_stats $SINGLEMDS "samedir_rename" 1
13541
13542         rm -rf $DIR/${tdir}
13543 }
13544 run_test 133a "Verifying MDT stats ========================================"
13545
13546 test_133b() {
13547         local res
13548
13549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13550         remote_ost_nodsh && skip "remote OST with nodsh"
13551         remote_mds_nodsh && skip "remote MDS with nodsh"
13552
13553         local testdir=$DIR/${tdir}/stats_testdir
13554
13555         mkdir -p ${testdir} || error "mkdir failed"
13556         touch ${testdir}/${tfile} || error "touch failed"
13557         cancel_lru_locks mdc
13558
13559         # clear stats.
13560         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13561         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13562
13563         # extra mdt stats verification.
13564         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13565         check_stats $SINGLEMDS "setattr" 1
13566         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13567         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13568         then            # LU-1740
13569                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13570                 check_stats $SINGLEMDS "getattr" 1
13571         fi
13572         rm -rf $DIR/${tdir}
13573
13574         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13575         # so the check below is not reliable
13576         [ $MDSCOUNT -eq 1 ] || return 0
13577
13578         # Sleep to avoid a cached response.
13579         #define OBD_STATFS_CACHE_SECONDS 1
13580         sleep 2
13581         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13582         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13583         $LFS df || error "lfs failed"
13584         check_stats $SINGLEMDS "statfs" 1
13585
13586         # check aggregated statfs (LU-10018)
13587         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13588                 return 0
13589         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13590                 return 0
13591         sleep 2
13592         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13593         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13594         df $DIR
13595         check_stats $SINGLEMDS "statfs" 1
13596
13597         # We want to check that the client didn't send OST_STATFS to
13598         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13599         # extra care is needed here.
13600         if remote_mds; then
13601                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13602                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13603
13604                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13605                 [ "$res" ] && error "OST got STATFS"
13606         fi
13607
13608         return 0
13609 }
13610 run_test 133b "Verifying extra MDT stats =================================="
13611
13612 test_133c() {
13613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13614         remote_ost_nodsh && skip "remote OST with nodsh"
13615         remote_mds_nodsh && skip "remote MDS with nodsh"
13616
13617         local testdir=$DIR/$tdir/stats_testdir
13618
13619         test_mkdir -p $testdir
13620
13621         # verify obdfilter stats.
13622         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13623         sync
13624         cancel_lru_locks osc
13625         wait_delete_completed
13626
13627         # clear stats.
13628         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13629         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13630
13631         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13632                 error "dd failed"
13633         sync
13634         cancel_lru_locks osc
13635         check_stats ost1 "write" 1
13636
13637         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13638         check_stats ost1 "read" 1
13639
13640         > $testdir/$tfile || error "truncate failed"
13641         check_stats ost1 "punch" 1
13642
13643         rm -f $testdir/$tfile || error "file remove failed"
13644         wait_delete_completed
13645         check_stats ost1 "destroy" 1
13646
13647         rm -rf $DIR/$tdir
13648 }
13649 run_test 133c "Verifying OST stats ========================================"
13650
13651 order_2() {
13652         local value=$1
13653         local orig=$value
13654         local order=1
13655
13656         while [ $value -ge 2 ]; do
13657                 order=$((order*2))
13658                 value=$((value/2))
13659         done
13660
13661         if [ $orig -gt $order ]; then
13662                 order=$((order*2))
13663         fi
13664         echo $order
13665 }
13666
13667 size_in_KMGT() {
13668     local value=$1
13669     local size=('K' 'M' 'G' 'T');
13670     local i=0
13671     local size_string=$value
13672
13673     while [ $value -ge 1024 ]; do
13674         if [ $i -gt 3 ]; then
13675             #T is the biggest unit we get here, if that is bigger,
13676             #just return XXXT
13677             size_string=${value}T
13678             break
13679         fi
13680         value=$((value >> 10))
13681         if [ $value -lt 1024 ]; then
13682             size_string=${value}${size[$i]}
13683             break
13684         fi
13685         i=$((i + 1))
13686     done
13687
13688     echo $size_string
13689 }
13690
13691 get_rename_size() {
13692         local size=$1
13693         local context=${2:-.}
13694         local sample=$(do_facet $SINGLEMDS $LCTL \
13695                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13696                 grep -A1 $context |
13697                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13698         echo $sample
13699 }
13700
13701 test_133d() {
13702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13703         remote_ost_nodsh && skip "remote OST with nodsh"
13704         remote_mds_nodsh && skip "remote MDS with nodsh"
13705         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13706                 skip_env "MDS doesn't support rename stats"
13707
13708         local testdir1=$DIR/${tdir}/stats_testdir1
13709         local testdir2=$DIR/${tdir}/stats_testdir2
13710         mkdir -p $DIR/${tdir}
13711
13712         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13713
13714         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13715         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13716
13717         createmany -o $testdir1/test 512 || error "createmany failed"
13718
13719         # check samedir rename size
13720         mv ${testdir1}/test0 ${testdir1}/test_0
13721
13722         local testdir1_size=$(ls -l $DIR/${tdir} |
13723                 awk '/stats_testdir1/ {print $5}')
13724         local testdir2_size=$(ls -l $DIR/${tdir} |
13725                 awk '/stats_testdir2/ {print $5}')
13726
13727         testdir1_size=$(order_2 $testdir1_size)
13728         testdir2_size=$(order_2 $testdir2_size)
13729
13730         testdir1_size=$(size_in_KMGT $testdir1_size)
13731         testdir2_size=$(size_in_KMGT $testdir2_size)
13732
13733         echo "source rename dir size: ${testdir1_size}"
13734         echo "target rename dir size: ${testdir2_size}"
13735
13736         local cmd="do_facet $SINGLEMDS $LCTL "
13737         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13738
13739         eval $cmd || error "$cmd failed"
13740         local samedir=$($cmd | grep 'same_dir')
13741         local same_sample=$(get_rename_size $testdir1_size)
13742         [ -z "$samedir" ] && error "samedir_rename_size count error"
13743         [[ $same_sample -eq 1 ]] ||
13744                 error "samedir_rename_size error $same_sample"
13745         echo "Check same dir rename stats success"
13746
13747         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13748
13749         # check crossdir rename size
13750         mv ${testdir1}/test_0 ${testdir2}/test_0
13751
13752         testdir1_size=$(ls -l $DIR/${tdir} |
13753                 awk '/stats_testdir1/ {print $5}')
13754         testdir2_size=$(ls -l $DIR/${tdir} |
13755                 awk '/stats_testdir2/ {print $5}')
13756
13757         testdir1_size=$(order_2 $testdir1_size)
13758         testdir2_size=$(order_2 $testdir2_size)
13759
13760         testdir1_size=$(size_in_KMGT $testdir1_size)
13761         testdir2_size=$(size_in_KMGT $testdir2_size)
13762
13763         echo "source rename dir size: ${testdir1_size}"
13764         echo "target rename dir size: ${testdir2_size}"
13765
13766         eval $cmd || error "$cmd failed"
13767         local crossdir=$($cmd | grep 'crossdir')
13768         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13769         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13770         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13771         [[ $src_sample -eq 1 ]] ||
13772                 error "crossdir_rename_size error $src_sample"
13773         [[ $tgt_sample -eq 1 ]] ||
13774                 error "crossdir_rename_size error $tgt_sample"
13775         echo "Check cross dir rename stats success"
13776         rm -rf $DIR/${tdir}
13777 }
13778 run_test 133d "Verifying rename_stats ========================================"
13779
13780 test_133e() {
13781         remote_mds_nodsh && skip "remote MDS with nodsh"
13782         remote_ost_nodsh && skip "remote OST with nodsh"
13783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13784
13785         local testdir=$DIR/${tdir}/stats_testdir
13786         local ctr f0 f1 bs=32768 count=42 sum
13787
13788         mkdir -p ${testdir} || error "mkdir failed"
13789
13790         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13791
13792         for ctr in {write,read}_bytes; do
13793                 sync
13794                 cancel_lru_locks osc
13795
13796                 do_facet ost1 $LCTL set_param -n \
13797                         "obdfilter.*.exports.clear=clear"
13798
13799                 if [ $ctr = write_bytes ]; then
13800                         f0=/dev/zero
13801                         f1=${testdir}/${tfile}
13802                 else
13803                         f0=${testdir}/${tfile}
13804                         f1=/dev/null
13805                 fi
13806
13807                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13808                         error "dd failed"
13809                 sync
13810                 cancel_lru_locks osc
13811
13812                 sum=$(do_facet ost1 $LCTL get_param \
13813                         "obdfilter.*.exports.*.stats" |
13814                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13815                                 $1 == ctr { sum += $7 }
13816                                 END { printf("%0.0f", sum) }')
13817
13818                 if ((sum != bs * count)); then
13819                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13820                 fi
13821         done
13822
13823         rm -rf $DIR/${tdir}
13824 }
13825 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13826
13827 test_133f() {
13828         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13829                 skip "too old lustre for get_param -R ($facet_ver)"
13830
13831         # verifying readability.
13832         $LCTL get_param -R '*' &> /dev/null
13833
13834         # Verifing writability with badarea_io.
13835         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13836                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13837                 error "client badarea_io failed"
13838
13839         # remount the FS in case writes/reads /proc break the FS
13840         cleanup || error "failed to unmount"
13841         setup || error "failed to setup"
13842 }
13843 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13844
13845 test_133g() {
13846         remote_mds_nodsh && skip "remote MDS with nodsh"
13847         remote_ost_nodsh && skip "remote OST with nodsh"
13848
13849         local facet
13850         for facet in mds1 ost1; do
13851                 local facet_ver=$(lustre_version_code $facet)
13852                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13853                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13854                 else
13855                         log "$facet: too old lustre for get_param -R"
13856                 fi
13857                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13858                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13859                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13860                                 xargs badarea_io" ||
13861                                         error "$facet badarea_io failed"
13862                 else
13863                         skip_noexit "$facet: too old lustre for get_param -R"
13864                 fi
13865         done
13866
13867         # remount the FS in case writes/reads /proc break the FS
13868         cleanup || error "failed to unmount"
13869         setup || error "failed to setup"
13870 }
13871 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13872
13873 test_133h() {
13874         remote_mds_nodsh && skip "remote MDS with nodsh"
13875         remote_ost_nodsh && skip "remote OST with nodsh"
13876         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13877                 skip "Need MDS version at least 2.9.54"
13878
13879         local facet
13880         for facet in client mds1 ost1; do
13881                 # Get the list of files that are missing the terminating newline
13882                 local plist=$(do_facet $facet
13883                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13884                 local ent
13885                 for ent in $plist; do
13886                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13887                                 awk -v FS='\v' -v RS='\v\v' \
13888                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13889                                         print FILENAME}'" 2>/dev/null)
13890                         [ -z $missing ] || {
13891                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13892                                 error "file does not end with newline: $facet-$ent"
13893                         }
13894                 done
13895         done
13896 }
13897 run_test 133h "Proc files should end with newlines"
13898
13899 test_134a() {
13900         remote_mds_nodsh && skip "remote MDS with nodsh"
13901         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13902                 skip "Need MDS version at least 2.7.54"
13903
13904         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13905         cancel_lru_locks mdc
13906
13907         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13908         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13909         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13910
13911         local nr=1000
13912         createmany -o $DIR/$tdir/f $nr ||
13913                 error "failed to create $nr files in $DIR/$tdir"
13914         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13915
13916         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13917         do_facet mds1 $LCTL set_param fail_loc=0x327
13918         do_facet mds1 $LCTL set_param fail_val=500
13919         touch $DIR/$tdir/m
13920
13921         echo "sleep 10 seconds ..."
13922         sleep 10
13923         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13924
13925         do_facet mds1 $LCTL set_param fail_loc=0
13926         do_facet mds1 $LCTL set_param fail_val=0
13927         [ $lck_cnt -lt $unused ] ||
13928                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13929
13930         rm $DIR/$tdir/m
13931         unlinkmany $DIR/$tdir/f $nr
13932 }
13933 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13934
13935 test_134b() {
13936         remote_mds_nodsh && skip "remote MDS with nodsh"
13937         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13938                 skip "Need MDS version at least 2.7.54"
13939
13940         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13941         cancel_lru_locks mdc
13942
13943         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13944                         ldlm.lock_reclaim_threshold_mb)
13945         # disable reclaim temporarily
13946         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13947
13948         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13949         do_facet mds1 $LCTL set_param fail_loc=0x328
13950         do_facet mds1 $LCTL set_param fail_val=500
13951
13952         $LCTL set_param debug=+trace
13953
13954         local nr=600
13955         createmany -o $DIR/$tdir/f $nr &
13956         local create_pid=$!
13957
13958         echo "Sleep $TIMEOUT seconds ..."
13959         sleep $TIMEOUT
13960         if ! ps -p $create_pid  > /dev/null 2>&1; then
13961                 do_facet mds1 $LCTL set_param fail_loc=0
13962                 do_facet mds1 $LCTL set_param fail_val=0
13963                 do_facet mds1 $LCTL set_param \
13964                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13965                 error "createmany finished incorrectly!"
13966         fi
13967         do_facet mds1 $LCTL set_param fail_loc=0
13968         do_facet mds1 $LCTL set_param fail_val=0
13969         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13970         wait $create_pid || return 1
13971
13972         unlinkmany $DIR/$tdir/f $nr
13973 }
13974 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13975
13976 test_135() {
13977         remote_mds_nodsh && skip "remote MDS with nodsh"
13978         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13979                 skip "Need MDS version at least 2.13.50"
13980         local fname
13981
13982         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13983
13984 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13985         #set only one record at plain llog
13986         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13987
13988         #fill already existed plain llog each 64767
13989         #wrapping whole catalog
13990         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13991
13992         createmany -o $DIR/$tdir/$tfile_ 64700
13993         for (( i = 0; i < 64700; i = i + 2 ))
13994         do
13995                 rm $DIR/$tdir/$tfile_$i &
13996                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13997                 local pid=$!
13998                 wait $pid
13999         done
14000
14001         #waiting osp synchronization
14002         wait_delete_completed
14003 }
14004 run_test 135 "Race catalog processing"
14005
14006 test_136() {
14007         remote_mds_nodsh && skip "remote MDS with nodsh"
14008         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14009                 skip "Need MDS version at least 2.13.50"
14010         local fname
14011
14012         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14013         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14014         #set only one record at plain llog
14015 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14016         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14017
14018         #fill already existed 2 plain llogs each 64767
14019         #wrapping whole catalog
14020         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14021         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14022         wait_delete_completed
14023
14024         createmany -o $DIR/$tdir/$tfile_ 10
14025         sleep 25
14026
14027         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14028         for (( i = 0; i < 10; i = i + 3 ))
14029         do
14030                 rm $DIR/$tdir/$tfile_$i &
14031                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14032                 local pid=$!
14033                 wait $pid
14034                 sleep 7
14035                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14036         done
14037
14038         #waiting osp synchronization
14039         wait_delete_completed
14040 }
14041 run_test 136 "Race catalog processing 2"
14042
14043 test_140() { #bug-17379
14044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14045
14046         test_mkdir $DIR/$tdir
14047         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14048         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14049
14050         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14051         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14052         local i=0
14053         while i=$((i + 1)); do
14054                 test_mkdir $i
14055                 cd $i || error "Changing to $i"
14056                 ln -s ../stat stat || error "Creating stat symlink"
14057                 # Read the symlink until ELOOP present,
14058                 # not LBUGing the system is considered success,
14059                 # we didn't overrun the stack.
14060                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14061                 if [ $ret -ne 0 ]; then
14062                         if [ $ret -eq 40 ]; then
14063                                 break  # -ELOOP
14064                         else
14065                                 error "Open stat symlink"
14066                                         return
14067                         fi
14068                 fi
14069         done
14070         i=$((i - 1))
14071         echo "The symlink depth = $i"
14072         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14073                 error "Invalid symlink depth"
14074
14075         # Test recursive symlink
14076         ln -s symlink_self symlink_self
14077         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14078         echo "open symlink_self returns $ret"
14079         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14080 }
14081 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14082
14083 test_150a() {
14084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14085
14086         local TF="$TMP/$tfile"
14087
14088         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14089         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14090         cp $TF $DIR/$tfile
14091         cancel_lru_locks $OSC
14092         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14093         remount_client $MOUNT
14094         df -P $MOUNT
14095         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14096
14097         $TRUNCATE $TF 6000
14098         $TRUNCATE $DIR/$tfile 6000
14099         cancel_lru_locks $OSC
14100         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14101
14102         echo "12345" >>$TF
14103         echo "12345" >>$DIR/$tfile
14104         cancel_lru_locks $OSC
14105         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14106
14107         echo "12345" >>$TF
14108         echo "12345" >>$DIR/$tfile
14109         cancel_lru_locks $OSC
14110         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14111 }
14112 run_test 150a "truncate/append tests"
14113
14114 test_150b() {
14115         check_set_fallocate_or_skip
14116
14117         touch $DIR/$tfile
14118         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14119         check_fallocate $DIR/$tfile || error "fallocate failed"
14120 }
14121 run_test 150b "Verify fallocate (prealloc) functionality"
14122
14123 test_150bb() {
14124         check_set_fallocate_or_skip
14125
14126         touch $DIR/$tfile
14127         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14128         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14129         > $DIR/$tfile
14130         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14131         # precomputed md5sum for 20MB of zeroes
14132         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14133         local sum=($(md5sum $DIR/$tfile))
14134
14135         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14136
14137         check_set_fallocate 1
14138
14139         > $DIR/$tfile
14140         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14141         sum=($(md5sum $DIR/$tfile))
14142
14143         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14144 }
14145 run_test 150bb "Verify fallocate modes both zero space"
14146
14147 test_150c() {
14148         check_set_fallocate_or_skip
14149
14150         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14151         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14152         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14153         sync; sync_all_data
14154         cancel_lru_locks $OSC
14155         sleep 5
14156         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14157         want=$((OSTCOUNT * 1048576))
14158
14159         # Must allocate all requested space, not more than 5% extra
14160         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14161                 error "bytes $bytes is not $want"
14162
14163         rm -f $DIR/$tfile
14164         # verify fallocate on PFL file
14165         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14166                 error "Create $DIR/$tfile failed"
14167         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14168                         error "fallocate failed"
14169         sync; sync_all_data
14170         cancel_lru_locks $OSC
14171         sleep 5
14172         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14173         local want=$((1024 * 1048576))
14174
14175         # Must allocate all requested space, not more than 5% extra
14176         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14177                 error "bytes $bytes is not $want"
14178 }
14179 run_test 150c "Verify fallocate Size and Blocks"
14180
14181 test_150d() {
14182         check_set_fallocate_or_skip
14183
14184         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14185         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14186         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14187         sync; sync_all_data
14188         cancel_lru_locks $OSC
14189         sleep 5
14190         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14191         local want=$((OSTCOUNT * 1048576))
14192
14193         # Must allocate all requested space, not more than 5% extra
14194         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14195                 error "bytes $bytes is not $want"
14196 }
14197 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14198
14199 test_150e() {
14200         check_set_fallocate_or_skip
14201
14202         echo "df before:"
14203         $LFS df
14204         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14205         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14206                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14207
14208         # Find OST with Minimum Size
14209         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14210                        sort -un | head -1)
14211
14212         # Get 100MB per OST of the available space to reduce run time
14213         # else 60% of the available space if we are running SLOW tests
14214         if [ $SLOW == "no" ]; then
14215                 local space=$((1024 * 100 * OSTCOUNT))
14216         else
14217                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14218         fi
14219
14220         fallocate -l${space}k $DIR/$tfile ||
14221                 error "fallocate ${space}k $DIR/$tfile failed"
14222         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14223
14224         # get size immediately after fallocate. This should be correctly
14225         # updated
14226         local size=$(stat -c '%s' $DIR/$tfile)
14227         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14228
14229         # Sleep for a while for statfs to get updated. And not pull from cache.
14230         sleep 2
14231
14232         echo "df after fallocate:"
14233         $LFS df
14234
14235         (( size / 1024 == space )) || error "size $size != requested $space"
14236         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14237                 error "used $used < space $space"
14238
14239         rm $DIR/$tfile || error "rm failed"
14240         sync
14241         wait_delete_completed
14242
14243         echo "df after unlink:"
14244         $LFS df
14245 }
14246 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14247
14248 test_150f() {
14249         local size
14250         local blocks
14251         local want_size_before=20480 # in bytes
14252         local want_blocks_before=40 # 512 sized blocks
14253         local want_blocks_after=24  # 512 sized blocks
14254         local length=$(((want_blocks_before - want_blocks_after) * 512))
14255
14256         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14257                 skip "need at least 2.14.0 for fallocate punch"
14258
14259         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14260                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14261         fi
14262
14263         check_set_fallocate_or_skip
14264         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14265
14266         echo "Verify fallocate punch: Range within the file range"
14267         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14268                 error "dd failed for bs 4096 and count 5"
14269
14270         # Call fallocate with punch range which is within the file range
14271         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14272                 error "fallocate failed: offset 4096 and length $length"
14273         # client must see changes immediately after fallocate
14274         size=$(stat -c '%s' $DIR/$tfile)
14275         blocks=$(stat -c '%b' $DIR/$tfile)
14276
14277         # Verify punch worked.
14278         (( blocks == want_blocks_after )) ||
14279                 error "punch failed: blocks $blocks != $want_blocks_after"
14280
14281         (( size == want_size_before )) ||
14282                 error "punch failed: size $size != $want_size_before"
14283
14284         # Verify there is hole in file
14285         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14286         # precomputed md5sum
14287         local expect="4a9a834a2db02452929c0a348273b4aa"
14288
14289         cksum=($(md5sum $DIR/$tfile))
14290         [[ "${cksum[0]}" == "$expect" ]] ||
14291                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14292
14293         # Start second sub-case for fallocate punch.
14294         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14295         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14296                 error "dd failed for bs 4096 and count 5"
14297
14298         # Punch range less than block size will have no change in block count
14299         want_blocks_after=40  # 512 sized blocks
14300
14301         # Punch overlaps two blocks and less than blocksize
14302         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14303                 error "fallocate failed: offset 4000 length 3000"
14304         size=$(stat -c '%s' $DIR/$tfile)
14305         blocks=$(stat -c '%b' $DIR/$tfile)
14306
14307         # Verify punch worked.
14308         (( blocks == want_blocks_after )) ||
14309                 error "punch failed: blocks $blocks != $want_blocks_after"
14310
14311         (( size == want_size_before )) ||
14312                 error "punch failed: size $size != $want_size_before"
14313
14314         # Verify if range is really zero'ed out. We expect Zeros.
14315         # precomputed md5sum
14316         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14317         cksum=($(md5sum $DIR/$tfile))
14318         [[ "${cksum[0]}" == "$expect" ]] ||
14319                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14320 }
14321 run_test 150f "Verify fallocate punch functionality"
14322
14323 test_150g() {
14324         local space
14325         local size
14326         local blocks
14327         local blocks_after
14328         local size_after
14329         local BS=4096 # Block size in bytes
14330
14331         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14332                 skip "need at least 2.14.0 for fallocate punch"
14333
14334         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14335                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14336         fi
14337
14338         check_set_fallocate_or_skip
14339         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14340
14341         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14342                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14343
14344         # Get 100MB per OST of the available space to reduce run time
14345         # else 60% of the available space if we are running SLOW tests
14346         if [ $SLOW == "no" ]; then
14347                 space=$((1024 * 100 * OSTCOUNT))
14348         else
14349                 # Find OST with Minimum Size
14350                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14351                         sort -un | head -1)
14352                 echo "min size OST: $space"
14353                 space=$(((space * 60)/100 * OSTCOUNT))
14354         fi
14355         # space in 1k units, round to 4k blocks
14356         local blkcount=$((space * 1024 / $BS))
14357
14358         echo "Verify fallocate punch: Very large Range"
14359         fallocate -l${space}k $DIR/$tfile ||
14360                 error "fallocate ${space}k $DIR/$tfile failed"
14361         # write 1M at the end, start and in the middle
14362         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14363                 error "dd failed: bs $BS count 256"
14364         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14365                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14366         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14367                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14368
14369         # Gather stats.
14370         size=$(stat -c '%s' $DIR/$tfile)
14371
14372         # gather punch length.
14373         local punch_size=$((size - (BS * 2)))
14374
14375         echo "punch_size = $punch_size"
14376         echo "size - punch_size: $((size - punch_size))"
14377         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14378
14379         # Call fallocate to punch all except 2 blocks. We leave the
14380         # first and the last block
14381         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14382         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14383                 error "fallocate failed: offset $BS length $punch_size"
14384
14385         size_after=$(stat -c '%s' $DIR/$tfile)
14386         blocks_after=$(stat -c '%b' $DIR/$tfile)
14387
14388         # Verify punch worked.
14389         # Size should be kept
14390         (( size == size_after )) ||
14391                 error "punch failed: size $size != $size_after"
14392
14393         # two 4k data blocks to remain plus possible 1 extra extent block
14394         (( blocks_after <= ((BS / 512) * 3) )) ||
14395                 error "too many blocks remains: $blocks_after"
14396
14397         # Verify that file has hole between the first and the last blocks
14398         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14399         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14400
14401         echo "Hole at [$hole_start, $hole_end)"
14402         (( hole_start == BS )) ||
14403                 error "no hole at offset $BS after punch"
14404
14405         (( hole_end == BS + punch_size )) ||
14406                 error "data at offset $hole_end < $((BS + punch_size))"
14407 }
14408 run_test 150g "Verify fallocate punch on large range"
14409
14410 #LU-2902 roc_hit was not able to read all values from lproc
14411 function roc_hit_init() {
14412         local list=$(comma_list $(osts_nodes))
14413         local dir=$DIR/$tdir-check
14414         local file=$dir/$tfile
14415         local BEFORE
14416         local AFTER
14417         local idx
14418
14419         test_mkdir $dir
14420         #use setstripe to do a write to every ost
14421         for i in $(seq 0 $((OSTCOUNT-1))); do
14422                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14423                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14424                 idx=$(printf %04x $i)
14425                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14426                         awk '$1 == "cache_access" {sum += $7}
14427                                 END { printf("%0.0f", sum) }')
14428
14429                 cancel_lru_locks osc
14430                 cat $file >/dev/null
14431
14432                 AFTER=$(get_osd_param $list *OST*$idx stats |
14433                         awk '$1 == "cache_access" {sum += $7}
14434                                 END { printf("%0.0f", sum) }')
14435
14436                 echo BEFORE:$BEFORE AFTER:$AFTER
14437                 if ! let "AFTER - BEFORE == 4"; then
14438                         rm -rf $dir
14439                         error "roc_hit is not safe to use"
14440                 fi
14441                 rm $file
14442         done
14443
14444         rm -rf $dir
14445 }
14446
14447 function roc_hit() {
14448         local list=$(comma_list $(osts_nodes))
14449         echo $(get_osd_param $list '' stats |
14450                 awk '$1 == "cache_hit" {sum += $7}
14451                         END { printf("%0.0f", sum) }')
14452 }
14453
14454 function set_cache() {
14455         local on=1
14456
14457         if [ "$2" == "off" ]; then
14458                 on=0;
14459         fi
14460         local list=$(comma_list $(osts_nodes))
14461         set_osd_param $list '' $1_cache_enable $on
14462
14463         cancel_lru_locks osc
14464 }
14465
14466 test_151() {
14467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14468         remote_ost_nodsh && skip "remote OST with nodsh"
14469
14470         local CPAGES=3
14471         local list=$(comma_list $(osts_nodes))
14472
14473         # check whether obdfilter is cache capable at all
14474         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14475                 skip "not cache-capable obdfilter"
14476         fi
14477
14478         # check cache is enabled on all obdfilters
14479         if get_osd_param $list '' read_cache_enable | grep 0; then
14480                 skip "oss cache is disabled"
14481         fi
14482
14483         set_osd_param $list '' writethrough_cache_enable 1
14484
14485         # check write cache is enabled on all obdfilters
14486         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14487                 skip "oss write cache is NOT enabled"
14488         fi
14489
14490         roc_hit_init
14491
14492         #define OBD_FAIL_OBD_NO_LRU  0x609
14493         do_nodes $list $LCTL set_param fail_loc=0x609
14494
14495         # pages should be in the case right after write
14496         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14497                 error "dd failed"
14498
14499         local BEFORE=$(roc_hit)
14500         cancel_lru_locks osc
14501         cat $DIR/$tfile >/dev/null
14502         local AFTER=$(roc_hit)
14503
14504         do_nodes $list $LCTL set_param fail_loc=0
14505
14506         if ! let "AFTER - BEFORE == CPAGES"; then
14507                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14508         fi
14509
14510         cancel_lru_locks osc
14511         # invalidates OST cache
14512         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14513         set_osd_param $list '' read_cache_enable 0
14514         cat $DIR/$tfile >/dev/null
14515
14516         # now data shouldn't be found in the cache
14517         BEFORE=$(roc_hit)
14518         cancel_lru_locks osc
14519         cat $DIR/$tfile >/dev/null
14520         AFTER=$(roc_hit)
14521         if let "AFTER - BEFORE != 0"; then
14522                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14523         fi
14524
14525         set_osd_param $list '' read_cache_enable 1
14526         rm -f $DIR/$tfile
14527 }
14528 run_test 151 "test cache on oss and controls ==============================="
14529
14530 test_152() {
14531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14532
14533         local TF="$TMP/$tfile"
14534
14535         # simulate ENOMEM during write
14536 #define OBD_FAIL_OST_NOMEM      0x226
14537         lctl set_param fail_loc=0x80000226
14538         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14539         cp $TF $DIR/$tfile
14540         sync || error "sync failed"
14541         lctl set_param fail_loc=0
14542
14543         # discard client's cache
14544         cancel_lru_locks osc
14545
14546         # simulate ENOMEM during read
14547         lctl set_param fail_loc=0x80000226
14548         cmp $TF $DIR/$tfile || error "cmp failed"
14549         lctl set_param fail_loc=0
14550
14551         rm -f $TF
14552 }
14553 run_test 152 "test read/write with enomem ============================"
14554
14555 test_153() {
14556         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14557 }
14558 run_test 153 "test if fdatasync does not crash ======================="
14559
14560 dot_lustre_fid_permission_check() {
14561         local fid=$1
14562         local ffid=$MOUNT/.lustre/fid/$fid
14563         local test_dir=$2
14564
14565         echo "stat fid $fid"
14566         stat $ffid > /dev/null || error "stat $ffid failed."
14567         echo "touch fid $fid"
14568         touch $ffid || error "touch $ffid failed."
14569         echo "write to fid $fid"
14570         cat /etc/hosts > $ffid || error "write $ffid failed."
14571         echo "read fid $fid"
14572         diff /etc/hosts $ffid || error "read $ffid failed."
14573         echo "append write to fid $fid"
14574         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14575         echo "rename fid $fid"
14576         mv $ffid $test_dir/$tfile.1 &&
14577                 error "rename $ffid to $tfile.1 should fail."
14578         touch $test_dir/$tfile.1
14579         mv $test_dir/$tfile.1 $ffid &&
14580                 error "rename $tfile.1 to $ffid should fail."
14581         rm -f $test_dir/$tfile.1
14582         echo "truncate fid $fid"
14583         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14584         echo "link fid $fid"
14585         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14586         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14587                 echo "setfacl fid $fid"
14588                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14589                 echo "getfacl fid $fid"
14590                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14591         fi
14592         echo "unlink fid $fid"
14593         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14594         echo "mknod fid $fid"
14595         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14596
14597         fid=[0xf00000400:0x1:0x0]
14598         ffid=$MOUNT/.lustre/fid/$fid
14599
14600         echo "stat non-exist fid $fid"
14601         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14602         echo "write to non-exist fid $fid"
14603         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14604         echo "link new fid $fid"
14605         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14606
14607         mkdir -p $test_dir/$tdir
14608         touch $test_dir/$tdir/$tfile
14609         fid=$($LFS path2fid $test_dir/$tdir)
14610         rc=$?
14611         [ $rc -ne 0 ] &&
14612                 error "error: could not get fid for $test_dir/$dir/$tfile."
14613
14614         ffid=$MOUNT/.lustre/fid/$fid
14615
14616         echo "ls $fid"
14617         ls $ffid > /dev/null || error "ls $ffid failed."
14618         echo "touch $fid/$tfile.1"
14619         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14620
14621         echo "touch $MOUNT/.lustre/fid/$tfile"
14622         touch $MOUNT/.lustre/fid/$tfile && \
14623                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14624
14625         echo "setxattr to $MOUNT/.lustre/fid"
14626         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14627
14628         echo "listxattr for $MOUNT/.lustre/fid"
14629         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14630
14631         echo "delxattr from $MOUNT/.lustre/fid"
14632         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14633
14634         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14635         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14636                 error "touch invalid fid should fail."
14637
14638         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14639         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14640                 error "touch non-normal fid should fail."
14641
14642         echo "rename $tdir to $MOUNT/.lustre/fid"
14643         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14644                 error "rename to $MOUNT/.lustre/fid should fail."
14645
14646         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14647         then            # LU-3547
14648                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14649                 local new_obf_mode=777
14650
14651                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14652                 chmod $new_obf_mode $DIR/.lustre/fid ||
14653                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14654
14655                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14656                 [ $obf_mode -eq $new_obf_mode ] ||
14657                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14658
14659                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14660                 chmod $old_obf_mode $DIR/.lustre/fid ||
14661                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14662         fi
14663
14664         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14665         fid=$($LFS path2fid $test_dir/$tfile-2)
14666
14667         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14668         then # LU-5424
14669                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14670                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14671                         error "create lov data thru .lustre failed"
14672         fi
14673         echo "cp /etc/passwd $test_dir/$tfile-2"
14674         cp /etc/passwd $test_dir/$tfile-2 ||
14675                 error "copy to $test_dir/$tfile-2 failed."
14676         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14677         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14678                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14679
14680         rm -rf $test_dir/tfile.lnk
14681         rm -rf $test_dir/$tfile-2
14682 }
14683
14684 test_154A() {
14685         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14686                 skip "Need MDS version at least 2.4.1"
14687
14688         local tf=$DIR/$tfile
14689         touch $tf
14690
14691         local fid=$($LFS path2fid $tf)
14692         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14693
14694         # check that we get the same pathname back
14695         local rootpath
14696         local found
14697         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14698                 echo "$rootpath $fid"
14699                 found=$($LFS fid2path $rootpath "$fid")
14700                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14701                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14702         done
14703
14704         # check wrong root path format
14705         rootpath=$MOUNT"_wrong"
14706         found=$($LFS fid2path $rootpath "$fid")
14707         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14708 }
14709 run_test 154A "lfs path2fid and fid2path basic checks"
14710
14711 test_154B() {
14712         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14713                 skip "Need MDS version at least 2.4.1"
14714
14715         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14716         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14717         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14718         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14719
14720         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14721         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14722
14723         # check that we get the same pathname
14724         echo "PFID: $PFID, name: $name"
14725         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14726         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14727         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14728                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14729
14730         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14731 }
14732 run_test 154B "verify the ll_decode_linkea tool"
14733
14734 test_154a() {
14735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14736         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14737         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14738                 skip "Need MDS version at least 2.2.51"
14739         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14740
14741         cp /etc/hosts $DIR/$tfile
14742
14743         fid=$($LFS path2fid $DIR/$tfile)
14744         rc=$?
14745         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14746
14747         dot_lustre_fid_permission_check "$fid" $DIR ||
14748                 error "dot lustre permission check $fid failed"
14749
14750         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14751
14752         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14753
14754         touch $MOUNT/.lustre/file &&
14755                 error "creation is not allowed under .lustre"
14756
14757         mkdir $MOUNT/.lustre/dir &&
14758                 error "mkdir is not allowed under .lustre"
14759
14760         rm -rf $DIR/$tfile
14761 }
14762 run_test 154a "Open-by-FID"
14763
14764 test_154b() {
14765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14766         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14768         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14769                 skip "Need MDS version at least 2.2.51"
14770
14771         local remote_dir=$DIR/$tdir/remote_dir
14772         local MDTIDX=1
14773         local rc=0
14774
14775         mkdir -p $DIR/$tdir
14776         $LFS mkdir -i $MDTIDX $remote_dir ||
14777                 error "create remote directory failed"
14778
14779         cp /etc/hosts $remote_dir/$tfile
14780
14781         fid=$($LFS path2fid $remote_dir/$tfile)
14782         rc=$?
14783         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14784
14785         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14786                 error "dot lustre permission check $fid failed"
14787         rm -rf $DIR/$tdir
14788 }
14789 run_test 154b "Open-by-FID for remote directory"
14790
14791 test_154c() {
14792         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14793                 skip "Need MDS version at least 2.4.1"
14794
14795         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14796         local FID1=$($LFS path2fid $DIR/$tfile.1)
14797         local FID2=$($LFS path2fid $DIR/$tfile.2)
14798         local FID3=$($LFS path2fid $DIR/$tfile.3)
14799
14800         local N=1
14801         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14802                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14803                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14804                 local want=FID$N
14805                 [ "$FID" = "${!want}" ] ||
14806                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14807                 N=$((N + 1))
14808         done
14809
14810         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14811         do
14812                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14813                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14814                 N=$((N + 1))
14815         done
14816 }
14817 run_test 154c "lfs path2fid and fid2path multiple arguments"
14818
14819 test_154d() {
14820         remote_mds_nodsh && skip "remote MDS with nodsh"
14821         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14822                 skip "Need MDS version at least 2.5.53"
14823
14824         if remote_mds; then
14825                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14826         else
14827                 nid="0@lo"
14828         fi
14829         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14830         local fd
14831         local cmd
14832
14833         rm -f $DIR/$tfile
14834         touch $DIR/$tfile
14835
14836         local fid=$($LFS path2fid $DIR/$tfile)
14837         # Open the file
14838         fd=$(free_fd)
14839         cmd="exec $fd<$DIR/$tfile"
14840         eval $cmd
14841         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14842         echo "$fid_list" | grep "$fid"
14843         rc=$?
14844
14845         cmd="exec $fd>/dev/null"
14846         eval $cmd
14847         if [ $rc -ne 0 ]; then
14848                 error "FID $fid not found in open files list $fid_list"
14849         fi
14850 }
14851 run_test 154d "Verify open file fid"
14852
14853 test_154e()
14854 {
14855         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14856                 skip "Need MDS version at least 2.6.50"
14857
14858         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14859                 error ".lustre returned by readdir"
14860         fi
14861 }
14862 run_test 154e ".lustre is not returned by readdir"
14863
14864 test_154f() {
14865         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14866
14867         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14868         test_mkdir -p -c1 $DIR/$tdir/d
14869         # test dirs inherit from its stripe
14870         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14871         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14872         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14873         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14874         touch $DIR/f
14875
14876         # get fid of parents
14877         local FID0=$($LFS path2fid $DIR/$tdir/d)
14878         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14879         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14880         local FID3=$($LFS path2fid $DIR)
14881
14882         # check that path2fid --parents returns expected <parent_fid>/name
14883         # 1) test for a directory (single parent)
14884         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14885         [ "$parent" == "$FID0/foo1" ] ||
14886                 error "expected parent: $FID0/foo1, got: $parent"
14887
14888         # 2) test for a file with nlink > 1 (multiple parents)
14889         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14890         echo "$parent" | grep -F "$FID1/$tfile" ||
14891                 error "$FID1/$tfile not returned in parent list"
14892         echo "$parent" | grep -F "$FID2/link" ||
14893                 error "$FID2/link not returned in parent list"
14894
14895         # 3) get parent by fid
14896         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14897         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14898         echo "$parent" | grep -F "$FID1/$tfile" ||
14899                 error "$FID1/$tfile not returned in parent list (by fid)"
14900         echo "$parent" | grep -F "$FID2/link" ||
14901                 error "$FID2/link not returned in parent list (by fid)"
14902
14903         # 4) test for entry in root directory
14904         parent=$($LFS path2fid --parents $DIR/f)
14905         echo "$parent" | grep -F "$FID3/f" ||
14906                 error "$FID3/f not returned in parent list"
14907
14908         # 5) test it on root directory
14909         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14910                 error "$MOUNT should not have parents"
14911
14912         # enable xattr caching and check that linkea is correctly updated
14913         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14914         save_lustre_params client "llite.*.xattr_cache" > $save
14915         lctl set_param llite.*.xattr_cache 1
14916
14917         # 6.1) linkea update on rename
14918         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14919
14920         # get parents by fid
14921         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14922         # foo1 should no longer be returned in parent list
14923         echo "$parent" | grep -F "$FID1" &&
14924                 error "$FID1 should no longer be in parent list"
14925         # the new path should appear
14926         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14927                 error "$FID2/$tfile.moved is not in parent list"
14928
14929         # 6.2) linkea update on unlink
14930         rm -f $DIR/$tdir/d/foo2/link
14931         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14932         # foo2/link should no longer be returned in parent list
14933         echo "$parent" | grep -F "$FID2/link" &&
14934                 error "$FID2/link should no longer be in parent list"
14935         true
14936
14937         rm -f $DIR/f
14938         restore_lustre_params < $save
14939         rm -f $save
14940 }
14941 run_test 154f "get parent fids by reading link ea"
14942
14943 test_154g()
14944 {
14945         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14946         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14947            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14948                 skip "Need MDS version at least 2.6.92"
14949
14950         mkdir -p $DIR/$tdir
14951         llapi_fid_test -d $DIR/$tdir
14952 }
14953 run_test 154g "various llapi FID tests"
14954
14955 test_155_small_load() {
14956     local temp=$TMP/$tfile
14957     local file=$DIR/$tfile
14958
14959     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14960         error "dd of=$temp bs=6096 count=1 failed"
14961     cp $temp $file
14962     cancel_lru_locks $OSC
14963     cmp $temp $file || error "$temp $file differ"
14964
14965     $TRUNCATE $temp 6000
14966     $TRUNCATE $file 6000
14967     cmp $temp $file || error "$temp $file differ (truncate1)"
14968
14969     echo "12345" >>$temp
14970     echo "12345" >>$file
14971     cmp $temp $file || error "$temp $file differ (append1)"
14972
14973     echo "12345" >>$temp
14974     echo "12345" >>$file
14975     cmp $temp $file || error "$temp $file differ (append2)"
14976
14977     rm -f $temp $file
14978     true
14979 }
14980
14981 test_155_big_load() {
14982         remote_ost_nodsh && skip "remote OST with nodsh"
14983
14984         local temp=$TMP/$tfile
14985         local file=$DIR/$tfile
14986
14987         free_min_max
14988         local cache_size=$(do_facet ost$((MAXI+1)) \
14989                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14990         local large_file_size=$((cache_size * 2))
14991
14992         echo "OSS cache size: $cache_size KB"
14993         echo "Large file size: $large_file_size KB"
14994
14995         [ $MAXV -le $large_file_size ] &&
14996                 skip_env "max available OST size needs > $large_file_size KB"
14997
14998         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14999
15000         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15001                 error "dd of=$temp bs=$large_file_size count=1k failed"
15002         cp $temp $file
15003         ls -lh $temp $file
15004         cancel_lru_locks osc
15005         cmp $temp $file || error "$temp $file differ"
15006
15007         rm -f $temp $file
15008         true
15009 }
15010
15011 save_writethrough() {
15012         local facets=$(get_facets OST)
15013
15014         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15015 }
15016
15017 test_155a() {
15018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15019
15020         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15021
15022         save_writethrough $p
15023
15024         set_cache read on
15025         set_cache writethrough on
15026         test_155_small_load
15027         restore_lustre_params < $p
15028         rm -f $p
15029 }
15030 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15031
15032 test_155b() {
15033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15034
15035         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15036
15037         save_writethrough $p
15038
15039         set_cache read on
15040         set_cache writethrough off
15041         test_155_small_load
15042         restore_lustre_params < $p
15043         rm -f $p
15044 }
15045 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15046
15047 test_155c() {
15048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15049
15050         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15051
15052         save_writethrough $p
15053
15054         set_cache read off
15055         set_cache writethrough on
15056         test_155_small_load
15057         restore_lustre_params < $p
15058         rm -f $p
15059 }
15060 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15061
15062 test_155d() {
15063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15064
15065         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15066
15067         save_writethrough $p
15068
15069         set_cache read off
15070         set_cache writethrough off
15071         test_155_small_load
15072         restore_lustre_params < $p
15073         rm -f $p
15074 }
15075 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15076
15077 test_155e() {
15078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15079
15080         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15081
15082         save_writethrough $p
15083
15084         set_cache read on
15085         set_cache writethrough on
15086         test_155_big_load
15087         restore_lustre_params < $p
15088         rm -f $p
15089 }
15090 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15091
15092 test_155f() {
15093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15094
15095         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15096
15097         save_writethrough $p
15098
15099         set_cache read on
15100         set_cache writethrough off
15101         test_155_big_load
15102         restore_lustre_params < $p
15103         rm -f $p
15104 }
15105 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15106
15107 test_155g() {
15108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15109
15110         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15111
15112         save_writethrough $p
15113
15114         set_cache read off
15115         set_cache writethrough on
15116         test_155_big_load
15117         restore_lustre_params < $p
15118         rm -f $p
15119 }
15120 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15121
15122 test_155h() {
15123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15124
15125         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15126
15127         save_writethrough $p
15128
15129         set_cache read off
15130         set_cache writethrough off
15131         test_155_big_load
15132         restore_lustre_params < $p
15133         rm -f $p
15134 }
15135 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15136
15137 test_156() {
15138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15139         remote_ost_nodsh && skip "remote OST with nodsh"
15140         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15141                 skip "stats not implemented on old servers"
15142         [ "$ost1_FSTYPE" = "zfs" ] &&
15143                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15144
15145         local CPAGES=3
15146         local BEFORE
15147         local AFTER
15148         local file="$DIR/$tfile"
15149         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15150
15151         save_writethrough $p
15152         roc_hit_init
15153
15154         log "Turn on read and write cache"
15155         set_cache read on
15156         set_cache writethrough on
15157
15158         log "Write data and read it back."
15159         log "Read should be satisfied from the cache."
15160         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15161         BEFORE=$(roc_hit)
15162         cancel_lru_locks osc
15163         cat $file >/dev/null
15164         AFTER=$(roc_hit)
15165         if ! let "AFTER - BEFORE == CPAGES"; then
15166                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15167         else
15168                 log "cache hits: before: $BEFORE, after: $AFTER"
15169         fi
15170
15171         log "Read again; it should be satisfied from the cache."
15172         BEFORE=$AFTER
15173         cancel_lru_locks osc
15174         cat $file >/dev/null
15175         AFTER=$(roc_hit)
15176         if ! let "AFTER - BEFORE == CPAGES"; then
15177                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15178         else
15179                 log "cache hits:: before: $BEFORE, after: $AFTER"
15180         fi
15181
15182         log "Turn off the read cache and turn on the write cache"
15183         set_cache read off
15184         set_cache writethrough on
15185
15186         log "Read again; it should be satisfied from the cache."
15187         BEFORE=$(roc_hit)
15188         cancel_lru_locks osc
15189         cat $file >/dev/null
15190         AFTER=$(roc_hit)
15191         if ! let "AFTER - BEFORE == CPAGES"; then
15192                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15193         else
15194                 log "cache hits:: before: $BEFORE, after: $AFTER"
15195         fi
15196
15197         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15198                 # > 2.12.56 uses pagecache if cached
15199                 log "Read again; it should not be satisfied from the cache."
15200                 BEFORE=$AFTER
15201                 cancel_lru_locks osc
15202                 cat $file >/dev/null
15203                 AFTER=$(roc_hit)
15204                 if ! let "AFTER - BEFORE == 0"; then
15205                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15206                 else
15207                         log "cache hits:: before: $BEFORE, after: $AFTER"
15208                 fi
15209         fi
15210
15211         log "Write data and read it back."
15212         log "Read should be satisfied from the cache."
15213         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15214         BEFORE=$(roc_hit)
15215         cancel_lru_locks osc
15216         cat $file >/dev/null
15217         AFTER=$(roc_hit)
15218         if ! let "AFTER - BEFORE == CPAGES"; then
15219                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15220         else
15221                 log "cache hits:: before: $BEFORE, after: $AFTER"
15222         fi
15223
15224         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15225                 # > 2.12.56 uses pagecache if cached
15226                 log "Read again; it should not be satisfied from the cache."
15227                 BEFORE=$AFTER
15228                 cancel_lru_locks osc
15229                 cat $file >/dev/null
15230                 AFTER=$(roc_hit)
15231                 if ! let "AFTER - BEFORE == 0"; then
15232                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15233                 else
15234                         log "cache hits:: before: $BEFORE, after: $AFTER"
15235                 fi
15236         fi
15237
15238         log "Turn off read and write cache"
15239         set_cache read off
15240         set_cache writethrough off
15241
15242         log "Write data and read it back"
15243         log "It should not be satisfied from the cache."
15244         rm -f $file
15245         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15246         cancel_lru_locks osc
15247         BEFORE=$(roc_hit)
15248         cat $file >/dev/null
15249         AFTER=$(roc_hit)
15250         if ! let "AFTER - BEFORE == 0"; then
15251                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15252         else
15253                 log "cache hits:: before: $BEFORE, after: $AFTER"
15254         fi
15255
15256         log "Turn on the read cache and turn off the write cache"
15257         set_cache read on
15258         set_cache writethrough off
15259
15260         log "Write data and read it back"
15261         log "It should not be satisfied from the cache."
15262         rm -f $file
15263         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15264         BEFORE=$(roc_hit)
15265         cancel_lru_locks osc
15266         cat $file >/dev/null
15267         AFTER=$(roc_hit)
15268         if ! let "AFTER - BEFORE == 0"; then
15269                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15270         else
15271                 log "cache hits:: before: $BEFORE, after: $AFTER"
15272         fi
15273
15274         log "Read again; it should be satisfied from the cache."
15275         BEFORE=$(roc_hit)
15276         cancel_lru_locks osc
15277         cat $file >/dev/null
15278         AFTER=$(roc_hit)
15279         if ! let "AFTER - BEFORE == CPAGES"; then
15280                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15281         else
15282                 log "cache hits:: before: $BEFORE, after: $AFTER"
15283         fi
15284
15285         restore_lustre_params < $p
15286         rm -f $p $file
15287 }
15288 run_test 156 "Verification of tunables"
15289
15290 test_160a() {
15291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15292         remote_mds_nodsh && skip "remote MDS with nodsh"
15293         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15294                 skip "Need MDS version at least 2.2.0"
15295
15296         changelog_register || error "changelog_register failed"
15297         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15298         changelog_users $SINGLEMDS | grep -q $cl_user ||
15299                 error "User $cl_user not found in changelog_users"
15300
15301         mkdir_on_mdt0 $DIR/$tdir
15302
15303         # change something
15304         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15305         changelog_clear 0 || error "changelog_clear failed"
15306         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15307         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15308         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15309         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15310         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15311         rm $DIR/$tdir/pics/desktop.jpg
15312
15313         echo "verifying changelog mask"
15314         changelog_chmask "-MKDIR"
15315         changelog_chmask "-CLOSE"
15316
15317         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15318         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15319
15320         changelog_chmask "+MKDIR"
15321         changelog_chmask "+CLOSE"
15322
15323         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15324         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15325
15326         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15327         CLOSES=$(changelog_dump | grep -c "CLOSE")
15328         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15329         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15330
15331         # verify contents
15332         echo "verifying target fid"
15333         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15334         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15335         [ "$fidc" == "$fidf" ] ||
15336                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15337         echo "verifying parent fid"
15338         # The FID returned from the Changelog may be the directory shard on
15339         # a different MDT, and not the FID returned by path2fid on the parent.
15340         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15341         # since this is what will matter when recreating this file in the tree.
15342         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15343         local pathp=$($LFS fid2path $MOUNT "$fidp")
15344         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15345                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15346
15347         echo "getting records for $cl_user"
15348         changelog_users $SINGLEMDS
15349         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15350         local nclr=3
15351         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15352                 error "changelog_clear failed"
15353         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15354         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15355         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15356                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15357
15358         local min0_rec=$(changelog_users $SINGLEMDS |
15359                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15360         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15361                           awk '{ print $1; exit; }')
15362
15363         changelog_dump | tail -n 5
15364         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15365         [ $first_rec == $((min0_rec + 1)) ] ||
15366                 error "first index should be $min0_rec + 1 not $first_rec"
15367
15368         # LU-3446 changelog index reset on MDT restart
15369         local cur_rec1=$(changelog_users $SINGLEMDS |
15370                          awk '/^current.index:/ { print $NF }')
15371         changelog_clear 0 ||
15372                 error "clear all changelog records for $cl_user failed"
15373         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15374         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15375                 error "Fail to start $SINGLEMDS"
15376         local cur_rec2=$(changelog_users $SINGLEMDS |
15377                          awk '/^current.index:/ { print $NF }')
15378         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15379         [ $cur_rec1 == $cur_rec2 ] ||
15380                 error "current index should be $cur_rec1 not $cur_rec2"
15381
15382         echo "verifying users from this test are deregistered"
15383         changelog_deregister || error "changelog_deregister failed"
15384         changelog_users $SINGLEMDS | grep -q $cl_user &&
15385                 error "User '$cl_user' still in changelog_users"
15386
15387         # lctl get_param -n mdd.*.changelog_users
15388         # current_index: 144
15389         # ID    index (idle seconds)
15390         # cl3   144   (2) mask=<list>
15391         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15392                 # this is the normal case where all users were deregistered
15393                 # make sure no new records are added when no users are present
15394                 local last_rec1=$(changelog_users $SINGLEMDS |
15395                                   awk '/^current.index:/ { print $NF }')
15396                 touch $DIR/$tdir/chloe
15397                 local last_rec2=$(changelog_users $SINGLEMDS |
15398                                   awk '/^current.index:/ { print $NF }')
15399                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15400                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15401         else
15402                 # any changelog users must be leftovers from a previous test
15403                 changelog_users $SINGLEMDS
15404                 echo "other changelog users; can't verify off"
15405         fi
15406 }
15407 run_test 160a "changelog sanity"
15408
15409 test_160b() { # LU-3587
15410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15411         remote_mds_nodsh && skip "remote MDS with nodsh"
15412         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15413                 skip "Need MDS version at least 2.2.0"
15414
15415         changelog_register || error "changelog_register failed"
15416         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15417         changelog_users $SINGLEMDS | grep -q $cl_user ||
15418                 error "User '$cl_user' not found in changelog_users"
15419
15420         local longname1=$(str_repeat a 255)
15421         local longname2=$(str_repeat b 255)
15422
15423         cd $DIR
15424         echo "creating very long named file"
15425         touch $longname1 || error "create of '$longname1' failed"
15426         echo "renaming very long named file"
15427         mv $longname1 $longname2
15428
15429         changelog_dump | grep RENME | tail -n 5
15430         rm -f $longname2
15431 }
15432 run_test 160b "Verify that very long rename doesn't crash in changelog"
15433
15434 test_160c() {
15435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15436         remote_mds_nodsh && skip "remote MDS with nodsh"
15437
15438         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15439                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15440                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15441                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15442
15443         local rc=0
15444
15445         # Registration step
15446         changelog_register || error "changelog_register failed"
15447
15448         rm -rf $DIR/$tdir
15449         mkdir -p $DIR/$tdir
15450         $MCREATE $DIR/$tdir/foo_160c
15451         changelog_chmask "-TRUNC"
15452         $TRUNCATE $DIR/$tdir/foo_160c 200
15453         changelog_chmask "+TRUNC"
15454         $TRUNCATE $DIR/$tdir/foo_160c 199
15455         changelog_dump | tail -n 5
15456         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15457         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15458 }
15459 run_test 160c "verify that changelog log catch the truncate event"
15460
15461 test_160d() {
15462         remote_mds_nodsh && skip "remote MDS with nodsh"
15463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15465         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15466                 skip "Need MDS version at least 2.7.60"
15467
15468         # Registration step
15469         changelog_register || error "changelog_register failed"
15470
15471         mkdir -p $DIR/$tdir/migrate_dir
15472         changelog_clear 0 || error "changelog_clear failed"
15473
15474         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15475         changelog_dump | tail -n 5
15476         local migrates=$(changelog_dump | grep -c "MIGRT")
15477         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15478 }
15479 run_test 160d "verify that changelog log catch the migrate event"
15480
15481 test_160e() {
15482         remote_mds_nodsh && skip "remote MDS with nodsh"
15483
15484         # Create a user
15485         changelog_register || error "changelog_register failed"
15486
15487         # Delete a future user (expect fail)
15488         local MDT0=$(facet_svc $SINGLEMDS)
15489         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15490         local rc=$?
15491
15492         if [ $rc -eq 0 ]; then
15493                 error "Deleted non-existant user cl77"
15494         elif [ $rc -ne 2 ]; then
15495                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15496         fi
15497
15498         # Clear to a bad index (1 billion should be safe)
15499         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15500         rc=$?
15501
15502         if [ $rc -eq 0 ]; then
15503                 error "Successfully cleared to invalid CL index"
15504         elif [ $rc -ne 22 ]; then
15505                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15506         fi
15507 }
15508 run_test 160e "changelog negative testing (should return errors)"
15509
15510 test_160f() {
15511         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15512         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15513                 skip "Need MDS version at least 2.10.56"
15514
15515         local mdts=$(comma_list $(mdts_nodes))
15516
15517         # Create a user
15518         changelog_register || error "first changelog_register failed"
15519         changelog_register || error "second changelog_register failed"
15520         local cl_users
15521         declare -A cl_user1
15522         declare -A cl_user2
15523         local user_rec1
15524         local user_rec2
15525         local i
15526
15527         # generate some changelog records to accumulate on each MDT
15528         # use all_char because created files should be evenly distributed
15529         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15530                 error "test_mkdir $tdir failed"
15531         log "$(date +%s): creating first files"
15532         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15533                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15534                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15535         done
15536
15537         # check changelogs have been generated
15538         local start=$SECONDS
15539         local idle_time=$((MDSCOUNT * 5 + 5))
15540         local nbcl=$(changelog_dump | wc -l)
15541         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15542
15543         for param in "changelog_max_idle_time=$idle_time" \
15544                      "changelog_gc=1" \
15545                      "changelog_min_gc_interval=2" \
15546                      "changelog_min_free_cat_entries=3"; do
15547                 local MDT0=$(facet_svc $SINGLEMDS)
15548                 local var="${param%=*}"
15549                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15550
15551                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15552                 do_nodes $mdts $LCTL set_param mdd.*.$param
15553         done
15554
15555         # force cl_user2 to be idle (1st part), but also cancel the
15556         # cl_user1 records so that it is not evicted later in the test.
15557         local sleep1=$((idle_time / 2))
15558         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15559         sleep $sleep1
15560
15561         # simulate changelog catalog almost full
15562         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15563         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15564
15565         for i in $(seq $MDSCOUNT); do
15566                 cl_users=(${CL_USERS[mds$i]})
15567                 cl_user1[mds$i]="${cl_users[0]}"
15568                 cl_user2[mds$i]="${cl_users[1]}"
15569
15570                 [ -n "${cl_user1[mds$i]}" ] ||
15571                         error "mds$i: no user registered"
15572                 [ -n "${cl_user2[mds$i]}" ] ||
15573                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15574
15575                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15576                 [ -n "$user_rec1" ] ||
15577                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15578                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15579                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15580                 [ -n "$user_rec2" ] ||
15581                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15582                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15583                      "$user_rec1 + 2 == $user_rec2"
15584                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15585                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15586                               "$user_rec1 + 2, but is $user_rec2"
15587                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15588                 [ -n "$user_rec2" ] ||
15589                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15590                 [ $user_rec1 == $user_rec2 ] ||
15591                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15592                               "$user_rec1, but is $user_rec2"
15593         done
15594
15595         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15596         local sleep2=$((idle_time - (SECONDS - start) + 1))
15597         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15598         sleep $sleep2
15599
15600         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15601         # cl_user1 should be OK because it recently processed records.
15602         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15603         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15604                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15605                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15606         done
15607
15608         # ensure gc thread is done
15609         for i in $(mdts_nodes); do
15610                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15611                         error "$i: GC-thread not done"
15612         done
15613
15614         local first_rec
15615         for (( i = 1; i <= MDSCOUNT; i++ )); do
15616                 # check cl_user1 still registered
15617                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15618                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15619                 # check cl_user2 unregistered
15620                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15621                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15622
15623                 # check changelogs are present and starting at $user_rec1 + 1
15624                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15625                 [ -n "$user_rec1" ] ||
15626                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15627                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15628                             awk '{ print $1; exit; }')
15629
15630                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15631                 [ $((user_rec1 + 1)) == $first_rec ] ||
15632                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15633         done
15634 }
15635 run_test 160f "changelog garbage collect (timestamped users)"
15636
15637 test_160g() {
15638         remote_mds_nodsh && skip "remote MDS with nodsh"
15639         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15640                 skip "Need MDS version at least 2.10.56"
15641
15642         local mdts=$(comma_list $(mdts_nodes))
15643
15644         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15645         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15646
15647         # Create a user
15648         changelog_register || error "first changelog_register failed"
15649         changelog_register || error "second changelog_register failed"
15650         local cl_users
15651         declare -A cl_user1
15652         declare -A cl_user2
15653         local user_rec1
15654         local user_rec2
15655         local i
15656
15657         # generate some changelog records to accumulate on each MDT
15658         # use all_char because created files should be evenly distributed
15659         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15660                 error "test_mkdir $tdir failed"
15661         for ((i = 0; i < MDSCOUNT; i++)); do
15662                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15663                         error "create $DIR/$tdir/d$i.1 failed"
15664         done
15665
15666         # check changelogs have been generated
15667         local nbcl=$(changelog_dump | wc -l)
15668         (( $nbcl > 0 )) || error "no changelogs found"
15669
15670         # reduce the max_idle_indexes value to make sure we exceed it
15671         for param in "changelog_max_idle_indexes=1" \
15672                      "changelog_gc=1" \
15673                      "changelog_min_gc_interval=2" \
15674                      "changelog_min_free_cat_entries=3"; do
15675                 local MDT0=$(facet_svc $SINGLEMDS)
15676                 local var="${param%=*}"
15677                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15678
15679                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15680                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15681                         error "unable to set mdd.*.$param"
15682         done
15683
15684         # simulate changelog catalog almost full
15685         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15686         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15687
15688         local start=$SECONDS
15689         for i in $(seq $MDSCOUNT); do
15690                 cl_users=(${CL_USERS[mds$i]})
15691                 cl_user1[mds$i]="${cl_users[0]}"
15692                 cl_user2[mds$i]="${cl_users[1]}"
15693
15694                 [ -n "${cl_user1[mds$i]}" ] ||
15695                         error "mds$i: no user registered"
15696                 [ -n "${cl_user2[mds$i]}" ] ||
15697                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15698
15699                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15700                 [ -n "$user_rec1" ] ||
15701                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15702                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15703                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15704                 [ -n "$user_rec2" ] ||
15705                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15706                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15707                      "$user_rec1 + 2 == $user_rec2"
15708                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15709                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15710                               "$user_rec1 + 2, but is $user_rec2"
15711                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15712                 [ -n "$user_rec2" ] ||
15713                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15714                 [ $user_rec1 == $user_rec2 ] ||
15715                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15716                               "$user_rec1, but is $user_rec2"
15717         done
15718
15719         # ensure we are past the previous changelog_min_gc_interval set above
15720         local sleep2=$((start + 2 - SECONDS))
15721         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15722
15723         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15724         # cl_user1 should be OK because it recently processed records.
15725         for ((i = 0; i < MDSCOUNT; i++)); do
15726                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15727                         error "create $DIR/$tdir/d$i.3 failed"
15728         done
15729
15730         # ensure gc thread is done
15731         for i in $(mdts_nodes); do
15732                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15733                         error "$i: GC-thread not done"
15734         done
15735
15736         local first_rec
15737         for (( i = 1; i <= MDSCOUNT; i++ )); do
15738                 # check cl_user1 still registered
15739                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15740                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15741                 # check cl_user2 unregistered
15742                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15743                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15744
15745                 # check changelogs are present and starting at $user_rec1 + 1
15746                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15747                 [ -n "$user_rec1" ] ||
15748                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15749                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15750                             awk '{ print $1; exit; }')
15751
15752                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15753                 [ $((user_rec1 + 1)) == $first_rec ] ||
15754                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15755         done
15756 }
15757 run_test 160g "changelog garbage collect (old users)"
15758
15759 test_160h() {
15760         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15761         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15762                 skip "Need MDS version at least 2.10.56"
15763
15764         local mdts=$(comma_list $(mdts_nodes))
15765
15766         # Create a user
15767         changelog_register || error "first changelog_register failed"
15768         changelog_register || error "second changelog_register failed"
15769         local cl_users
15770         declare -A cl_user1
15771         declare -A cl_user2
15772         local user_rec1
15773         local user_rec2
15774         local i
15775
15776         # generate some changelog records to accumulate on each MDT
15777         # use all_char because created files should be evenly distributed
15778         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15779                 error "test_mkdir $tdir failed"
15780         for ((i = 0; i < MDSCOUNT; i++)); do
15781                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15782                         error "create $DIR/$tdir/d$i.1 failed"
15783         done
15784
15785         # check changelogs have been generated
15786         local nbcl=$(changelog_dump | wc -l)
15787         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15788
15789         for param in "changelog_max_idle_time=10" \
15790                      "changelog_gc=1" \
15791                      "changelog_min_gc_interval=2"; do
15792                 local MDT0=$(facet_svc $SINGLEMDS)
15793                 local var="${param%=*}"
15794                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15795
15796                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15797                 do_nodes $mdts $LCTL set_param mdd.*.$param
15798         done
15799
15800         # force cl_user2 to be idle (1st part)
15801         sleep 9
15802
15803         for i in $(seq $MDSCOUNT); do
15804                 cl_users=(${CL_USERS[mds$i]})
15805                 cl_user1[mds$i]="${cl_users[0]}"
15806                 cl_user2[mds$i]="${cl_users[1]}"
15807
15808                 [ -n "${cl_user1[mds$i]}" ] ||
15809                         error "mds$i: no user registered"
15810                 [ -n "${cl_user2[mds$i]}" ] ||
15811                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15812
15813                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15814                 [ -n "$user_rec1" ] ||
15815                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15816                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15817                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15818                 [ -n "$user_rec2" ] ||
15819                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15820                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15821                      "$user_rec1 + 2 == $user_rec2"
15822                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15823                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15824                               "$user_rec1 + 2, but is $user_rec2"
15825                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15826                 [ -n "$user_rec2" ] ||
15827                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15828                 [ $user_rec1 == $user_rec2 ] ||
15829                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15830                               "$user_rec1, but is $user_rec2"
15831         done
15832
15833         # force cl_user2 to be idle (2nd part) and to reach
15834         # changelog_max_idle_time
15835         sleep 2
15836
15837         # force each GC-thread start and block then
15838         # one per MDT/MDD, set fail_val accordingly
15839         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15840         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15841
15842         # generate more changelogs to trigger fail_loc
15843         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15844                 error "create $DIR/$tdir/${tfile}bis failed"
15845
15846         # stop MDT to stop GC-thread, should be done in back-ground as it will
15847         # block waiting for the thread to be released and exit
15848         declare -A stop_pids
15849         for i in $(seq $MDSCOUNT); do
15850                 stop mds$i &
15851                 stop_pids[mds$i]=$!
15852         done
15853
15854         for i in $(mdts_nodes); do
15855                 local facet
15856                 local nb=0
15857                 local facets=$(facets_up_on_host $i)
15858
15859                 for facet in ${facets//,/ }; do
15860                         if [[ $facet == mds* ]]; then
15861                                 nb=$((nb + 1))
15862                         fi
15863                 done
15864                 # ensure each MDS's gc threads are still present and all in "R"
15865                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15866                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15867                         error "$i: expected $nb GC-thread"
15868                 wait_update $i \
15869                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15870                         "R" 20 ||
15871                         error "$i: GC-thread not found in R-state"
15872                 # check umounts of each MDT on MDS have reached kthread_stop()
15873                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15874                         error "$i: expected $nb umount"
15875                 wait_update $i \
15876                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15877                         error "$i: umount not found in D-state"
15878         done
15879
15880         # release all GC-threads
15881         do_nodes $mdts $LCTL set_param fail_loc=0
15882
15883         # wait for MDT stop to complete
15884         for i in $(seq $MDSCOUNT); do
15885                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15886         done
15887
15888         # XXX
15889         # may try to check if any orphan changelog records are present
15890         # via ldiskfs/zfs and llog_reader...
15891
15892         # re-start/mount MDTs
15893         for i in $(seq $MDSCOUNT); do
15894                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15895                         error "Fail to start mds$i"
15896         done
15897
15898         local first_rec
15899         for i in $(seq $MDSCOUNT); do
15900                 # check cl_user1 still registered
15901                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15902                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15903                 # check cl_user2 unregistered
15904                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15905                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15906
15907                 # check changelogs are present and starting at $user_rec1 + 1
15908                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15909                 [ -n "$user_rec1" ] ||
15910                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15911                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15912                             awk '{ print $1; exit; }')
15913
15914                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15915                 [ $((user_rec1 + 1)) == $first_rec ] ||
15916                         error "mds$i: first index should be $user_rec1 + 1, " \
15917                               "but is $first_rec"
15918         done
15919 }
15920 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15921               "during mount"
15922
15923 test_160i() {
15924
15925         local mdts=$(comma_list $(mdts_nodes))
15926
15927         changelog_register || error "first changelog_register failed"
15928
15929         # generate some changelog records to accumulate on each MDT
15930         # use all_char because created files should be evenly distributed
15931         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15932                 error "test_mkdir $tdir failed"
15933         for ((i = 0; i < MDSCOUNT; i++)); do
15934                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15935                         error "create $DIR/$tdir/d$i.1 failed"
15936         done
15937
15938         # check changelogs have been generated
15939         local nbcl=$(changelog_dump | wc -l)
15940         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15941
15942         # simulate race between register and unregister
15943         # XXX as fail_loc is set per-MDS, with DNE configs the race
15944         # simulation will only occur for one MDT per MDS and for the
15945         # others the normal race scenario will take place
15946         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15947         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15948         do_nodes $mdts $LCTL set_param fail_val=1
15949
15950         # unregister 1st user
15951         changelog_deregister &
15952         local pid1=$!
15953         # wait some time for deregister work to reach race rdv
15954         sleep 2
15955         # register 2nd user
15956         changelog_register || error "2nd user register failed"
15957
15958         wait $pid1 || error "1st user deregister failed"
15959
15960         local i
15961         local last_rec
15962         declare -A LAST_REC
15963         for i in $(seq $MDSCOUNT); do
15964                 if changelog_users mds$i | grep "^cl"; then
15965                         # make sure new records are added with one user present
15966                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15967                                           awk '/^current.index:/ { print $NF }')
15968                 else
15969                         error "mds$i has no user registered"
15970                 fi
15971         done
15972
15973         # generate more changelog records to accumulate on each MDT
15974         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15975                 error "create $DIR/$tdir/${tfile}bis failed"
15976
15977         for i in $(seq $MDSCOUNT); do
15978                 last_rec=$(changelog_users $SINGLEMDS |
15979                            awk '/^current.index:/ { print $NF }')
15980                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15981                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15982                         error "changelogs are off on mds$i"
15983         done
15984 }
15985 run_test 160i "changelog user register/unregister race"
15986
15987 test_160j() {
15988         remote_mds_nodsh && skip "remote MDS with nodsh"
15989         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15990                 skip "Need MDS version at least 2.12.56"
15991
15992         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15993         stack_trap "umount $MOUNT2" EXIT
15994
15995         changelog_register || error "first changelog_register failed"
15996         stack_trap "changelog_deregister" EXIT
15997
15998         # generate some changelog
15999         # use all_char because created files should be evenly distributed
16000         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16001                 error "mkdir $tdir failed"
16002         for ((i = 0; i < MDSCOUNT; i++)); do
16003                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16004                         error "create $DIR/$tdir/d$i.1 failed"
16005         done
16006
16007         # open the changelog device
16008         exec 3>/dev/changelog-$FSNAME-MDT0000
16009         stack_trap "exec 3>&-" EXIT
16010         exec 4</dev/changelog-$FSNAME-MDT0000
16011         stack_trap "exec 4<&-" EXIT
16012
16013         # umount the first lustre mount
16014         umount $MOUNT
16015         stack_trap "mount_client $MOUNT" EXIT
16016
16017         # read changelog, which may or may not fail, but should not crash
16018         cat <&4 >/dev/null
16019
16020         # clear changelog
16021         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16022         changelog_users $SINGLEMDS | grep -q $cl_user ||
16023                 error "User $cl_user not found in changelog_users"
16024
16025         printf 'clear:'$cl_user':0' >&3
16026 }
16027 run_test 160j "client can be umounted while its chanangelog is being used"
16028
16029 test_160k() {
16030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16031         remote_mds_nodsh && skip "remote MDS with nodsh"
16032
16033         mkdir -p $DIR/$tdir/1/1
16034
16035         changelog_register || error "changelog_register failed"
16036         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16037
16038         changelog_users $SINGLEMDS | grep -q $cl_user ||
16039                 error "User '$cl_user' not found in changelog_users"
16040 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16041         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16042         rmdir $DIR/$tdir/1/1 & sleep 1
16043         mkdir $DIR/$tdir/2
16044         touch $DIR/$tdir/2/2
16045         rm -rf $DIR/$tdir/2
16046
16047         wait
16048         sleep 4
16049
16050         changelog_dump | grep rmdir || error "rmdir not recorded"
16051 }
16052 run_test 160k "Verify that changelog records are not lost"
16053
16054 # Verifies that a file passed as a parameter has recently had an operation
16055 # performed on it that has generated an MTIME changelog which contains the
16056 # correct parent FID. As files might reside on a different MDT from the
16057 # parent directory in DNE configurations, the FIDs are translated to paths
16058 # before being compared, which should be identical
16059 compare_mtime_changelog() {
16060         local file="${1}"
16061         local mdtidx
16062         local mtime
16063         local cl_fid
16064         local pdir
16065         local dir
16066
16067         mdtidx=$($LFS getstripe --mdt-index $file)
16068         mdtidx=$(printf "%04x" $mdtidx)
16069
16070         # Obtain the parent FID from the MTIME changelog
16071         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16072         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16073
16074         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16075         [ -z "$cl_fid" ] && error "parent FID not present"
16076
16077         # Verify that the path for the parent FID is the same as the path for
16078         # the test directory
16079         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16080
16081         dir=$(dirname $1)
16082
16083         [[ "${pdir%/}" == "$dir" ]] ||
16084                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16085 }
16086
16087 test_160l() {
16088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16089
16090         remote_mds_nodsh && skip "remote MDS with nodsh"
16091         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16092                 skip "Need MDS version at least 2.13.55"
16093
16094         local cl_user
16095
16096         changelog_register || error "changelog_register failed"
16097         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16098
16099         changelog_users $SINGLEMDS | grep -q $cl_user ||
16100                 error "User '$cl_user' not found in changelog_users"
16101
16102         # Clear some types so that MTIME changelogs are generated
16103         changelog_chmask "-CREAT"
16104         changelog_chmask "-CLOSE"
16105
16106         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16107
16108         # Test CL_MTIME during setattr
16109         touch $DIR/$tdir/$tfile
16110         compare_mtime_changelog $DIR/$tdir/$tfile
16111
16112         # Test CL_MTIME during close
16113         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16114         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16115 }
16116 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16117
16118 test_160m() {
16119         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16120         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16121                 skip "Need MDS version at least 2.14.51"
16122         local cl_users
16123         local cl_user1
16124         local cl_user2
16125         local pid1
16126
16127         # Create a user
16128         changelog_register || error "first changelog_register failed"
16129         changelog_register || error "second changelog_register failed"
16130
16131         cl_users=(${CL_USERS[mds1]})
16132         cl_user1="${cl_users[0]}"
16133         cl_user2="${cl_users[1]}"
16134         # generate some changelog records to accumulate on MDT0
16135         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16136         createmany -m $DIR/$tdir/$tfile 50 ||
16137                 error "create $DIR/$tdir/$tfile failed"
16138         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16139         rm -f $DIR/$tdir
16140
16141         # check changelogs have been generated
16142         local nbcl=$(changelog_dump | wc -l)
16143         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16144
16145 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16146         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16147
16148         __changelog_clear mds1 $cl_user1 +10
16149         __changelog_clear mds1 $cl_user2 0 &
16150         pid1=$!
16151         sleep 2
16152         __changelog_clear mds1 $cl_user1 0 ||
16153                 error "fail to cancel record for $cl_user1"
16154         wait $pid1
16155         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16156 }
16157 run_test 160m "Changelog clear race"
16158
16159 test_160n() {
16160         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16161         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16162                 skip "Need MDS version at least 2.14.51"
16163         local cl_users
16164         local cl_user1
16165         local cl_user2
16166         local pid1
16167         local first_rec
16168         local last_rec=0
16169
16170         # Create a user
16171         changelog_register || error "first changelog_register failed"
16172
16173         cl_users=(${CL_USERS[mds1]})
16174         cl_user1="${cl_users[0]}"
16175
16176         # generate some changelog records to accumulate on MDT0
16177         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16178         first_rec=$(changelog_users $SINGLEMDS |
16179                         awk '/^current.index:/ { print $NF }')
16180         while (( last_rec < (( first_rec + 65000)) )); do
16181                 createmany -m $DIR/$tdir/$tfile 10000 ||
16182                         error "create $DIR/$tdir/$tfile failed"
16183
16184                 for i in $(seq 0 10000); do
16185                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16186                                 > /dev/null
16187                 done
16188
16189                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16190                         error "unlinkmany failed unlink"
16191                 last_rec=$(changelog_users $SINGLEMDS |
16192                         awk '/^current.index:/ { print $NF }')
16193                 echo last record $last_rec
16194                 (( last_rec == 0 )) && error "no changelog found"
16195         done
16196
16197 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16198         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16199
16200         __changelog_clear mds1 $cl_user1 0 &
16201         pid1=$!
16202         sleep 2
16203         __changelog_clear mds1 $cl_user1 0 ||
16204                 error "fail to cancel record for $cl_user1"
16205         wait $pid1
16206         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16207 }
16208 run_test 160n "Changelog destroy race"
16209
16210 test_160o() {
16211         local mdt="$(facet_svc $SINGLEMDS)"
16212
16213         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16214         remote_mds_nodsh && skip "remote MDS with nodsh"
16215         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16216                 skip "Need MDS version at least 2.14.52"
16217
16218         changelog_register --user test_160o -m unlnk+close+open ||
16219                 error "changelog_register failed"
16220         # drop server mask so it doesn't interfere
16221         do_facet $SINGLEMDS $LCTL --device $mdt \
16222                                 changelog_register -u "Tt3_-#" &&
16223                 error "bad symbols in name should fail"
16224
16225         do_facet $SINGLEMDS $LCTL --device $mdt \
16226                                 changelog_register -u test_160o &&
16227                 error "the same name registration should fail"
16228
16229         do_facet $SINGLEMDS $LCTL --device $mdt \
16230                         changelog_register -u test_160toolongname &&
16231                 error "too long name registration should fail"
16232
16233         changelog_chmask "MARK+HSM"
16234         lctl get_param mdd.*.changelog*mask
16235         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16236         changelog_users $SINGLEMDS | grep -q $cl_user ||
16237                 error "User $cl_user not found in changelog_users"
16238         #verify username
16239         echo $cl_user | grep -q test_160o ||
16240                 error "User $cl_user has no specific name 'test160o'"
16241
16242         # change something
16243         changelog_clear 0 || error "changelog_clear failed"
16244         # generate some changelog records to accumulate on MDT0
16245         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16246         touch $DIR/$tdir/$tfile                 # open 1
16247
16248         OPENS=$(changelog_dump | grep -c "OPEN")
16249         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16250
16251         # must be no MKDIR it wasn't set as user mask
16252         MKDIR=$(changelog_dump | grep -c "MKDIR")
16253         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16254
16255         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16256                                 mdd.$mdt.changelog_current_mask -n)
16257         # register maskless user
16258         changelog_register || error "changelog_register failed"
16259         # effective mask should be not changed because it is not minimal
16260         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16261                                 mdd.$mdt.changelog_current_mask -n)
16262         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16263         # set server mask to minimal value
16264         changelog_chmask "MARK"
16265         # check effective mask again, should be treated as DEFMASK now
16266         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16267                                 mdd.$mdt.changelog_current_mask -n)
16268         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16269
16270         do_facet $SINGLEMDS $LCTL --device $mdt \
16271                                 changelog_deregister -u test_160o ||
16272                 error "cannot deregister by name"
16273 }
16274 run_test 160o "changelog user name and mask"
16275
16276 test_160p() {
16277         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16278         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16279                 skip "Need MDS version at least 2.14.51"
16280         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16281         local cl_users
16282         local cl_user1
16283         local entry_count
16284
16285         # Create a user
16286         changelog_register || error "first changelog_register failed"
16287
16288         cl_users=(${CL_USERS[mds1]})
16289         cl_user1="${cl_users[0]}"
16290
16291         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16292         createmany -m $DIR/$tdir/$tfile 50 ||
16293                 error "create $DIR/$tdir/$tfile failed"
16294         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16295         rm -rf $DIR/$tdir
16296
16297         # check changelogs have been generated
16298         entry_count=$(changelog_dump | wc -l)
16299         ((entry_count != 0)) || error "no changelog entries found"
16300
16301         # remove changelog_users and check that orphan entries are removed
16302         stop mds1
16303         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16304         start mds1 || error "cannot start mdt"
16305         entry_count=$(changelog_dump | wc -l)
16306         ((entry_count == 0)) ||
16307                 error "found $entry_count changelog entries, expected none"
16308 }
16309 run_test 160p "Changelog orphan cleanup with no users"
16310
16311 test_161a() {
16312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16313
16314         test_mkdir -c1 $DIR/$tdir
16315         cp /etc/hosts $DIR/$tdir/$tfile
16316         test_mkdir -c1 $DIR/$tdir/foo1
16317         test_mkdir -c1 $DIR/$tdir/foo2
16318         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16319         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16320         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16321         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16322         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16323         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16324                 $LFS fid2path $DIR $FID
16325                 error "bad link ea"
16326         fi
16327         # middle
16328         rm $DIR/$tdir/foo2/zachary
16329         # last
16330         rm $DIR/$tdir/foo2/thor
16331         # first
16332         rm $DIR/$tdir/$tfile
16333         # rename
16334         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16335         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16336                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16337         rm $DIR/$tdir/foo2/maggie
16338
16339         # overflow the EA
16340         local longname=$tfile.avg_len_is_thirty_two_
16341         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16342                 error_noexit 'failed to unlink many hardlinks'" EXIT
16343         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16344                 error "failed to hardlink many files"
16345         links=$($LFS fid2path $DIR $FID | wc -l)
16346         echo -n "${links}/1000 links in link EA"
16347         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16348 }
16349 run_test 161a "link ea sanity"
16350
16351 test_161b() {
16352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16353         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16354
16355         local MDTIDX=1
16356         local remote_dir=$DIR/$tdir/remote_dir
16357
16358         mkdir -p $DIR/$tdir
16359         $LFS mkdir -i $MDTIDX $remote_dir ||
16360                 error "create remote directory failed"
16361
16362         cp /etc/hosts $remote_dir/$tfile
16363         mkdir -p $remote_dir/foo1
16364         mkdir -p $remote_dir/foo2
16365         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16366         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16367         ln $remote_dir/$tfile $remote_dir/foo1/luna
16368         ln $remote_dir/$tfile $remote_dir/foo2/thor
16369
16370         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16371                      tr -d ']')
16372         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16373                 $LFS fid2path $DIR $FID
16374                 error "bad link ea"
16375         fi
16376         # middle
16377         rm $remote_dir/foo2/zachary
16378         # last
16379         rm $remote_dir/foo2/thor
16380         # first
16381         rm $remote_dir/$tfile
16382         # rename
16383         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16384         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16385         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16386                 $LFS fid2path $DIR $FID
16387                 error "bad link rename"
16388         fi
16389         rm $remote_dir/foo2/maggie
16390
16391         # overflow the EA
16392         local longname=filename_avg_len_is_thirty_two_
16393         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16394                 error "failed to hardlink many files"
16395         links=$($LFS fid2path $DIR $FID | wc -l)
16396         echo -n "${links}/1000 links in link EA"
16397         [[ ${links} -gt 60 ]] ||
16398                 error "expected at least 60 links in link EA"
16399         unlinkmany $remote_dir/foo2/$longname 1000 ||
16400         error "failed to unlink many hardlinks"
16401 }
16402 run_test 161b "link ea sanity under remote directory"
16403
16404 test_161c() {
16405         remote_mds_nodsh && skip "remote MDS with nodsh"
16406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16407         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16408                 skip "Need MDS version at least 2.1.5"
16409
16410         # define CLF_RENAME_LAST 0x0001
16411         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16412         changelog_register || error "changelog_register failed"
16413
16414         rm -rf $DIR/$tdir
16415         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16416         touch $DIR/$tdir/foo_161c
16417         touch $DIR/$tdir/bar_161c
16418         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16419         changelog_dump | grep RENME | tail -n 5
16420         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16421         changelog_clear 0 || error "changelog_clear failed"
16422         if [ x$flags != "x0x1" ]; then
16423                 error "flag $flags is not 0x1"
16424         fi
16425
16426         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16427         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16428         touch $DIR/$tdir/foo_161c
16429         touch $DIR/$tdir/bar_161c
16430         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16431         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16432         changelog_dump | grep RENME | tail -n 5
16433         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16434         changelog_clear 0 || error "changelog_clear failed"
16435         if [ x$flags != "x0x0" ]; then
16436                 error "flag $flags is not 0x0"
16437         fi
16438         echo "rename overwrite a target having nlink > 1," \
16439                 "changelog record has flags of $flags"
16440
16441         # rename doesn't overwrite a target (changelog flag 0x0)
16442         touch $DIR/$tdir/foo_161c
16443         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16444         changelog_dump | grep RENME | tail -n 5
16445         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16446         changelog_clear 0 || error "changelog_clear failed"
16447         if [ x$flags != "x0x0" ]; then
16448                 error "flag $flags is not 0x0"
16449         fi
16450         echo "rename doesn't overwrite a target," \
16451                 "changelog record has flags of $flags"
16452
16453         # define CLF_UNLINK_LAST 0x0001
16454         # unlink a file having nlink = 1 (changelog flag 0x1)
16455         rm -f $DIR/$tdir/foo2_161c
16456         changelog_dump | grep UNLNK | tail -n 5
16457         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16458         changelog_clear 0 || error "changelog_clear failed"
16459         if [ x$flags != "x0x1" ]; then
16460                 error "flag $flags is not 0x1"
16461         fi
16462         echo "unlink a file having nlink = 1," \
16463                 "changelog record has flags of $flags"
16464
16465         # unlink a file having nlink > 1 (changelog flag 0x0)
16466         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16467         rm -f $DIR/$tdir/foobar_161c
16468         changelog_dump | grep UNLNK | tail -n 5
16469         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16470         changelog_clear 0 || error "changelog_clear failed"
16471         if [ x$flags != "x0x0" ]; then
16472                 error "flag $flags is not 0x0"
16473         fi
16474         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16475 }
16476 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16477
16478 test_161d() {
16479         remote_mds_nodsh && skip "remote MDS with nodsh"
16480         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16481
16482         local pid
16483         local fid
16484
16485         changelog_register || error "changelog_register failed"
16486
16487         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16488         # interfer with $MOUNT/.lustre/fid/ access
16489         mkdir $DIR/$tdir
16490         [[ $? -eq 0 ]] || error "mkdir failed"
16491
16492         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16493         $LCTL set_param fail_loc=0x8000140c
16494         # 5s pause
16495         $LCTL set_param fail_val=5
16496
16497         # create file
16498         echo foofoo > $DIR/$tdir/$tfile &
16499         pid=$!
16500
16501         # wait for create to be delayed
16502         sleep 2
16503
16504         ps -p $pid
16505         [[ $? -eq 0 ]] || error "create should be blocked"
16506
16507         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16508         stack_trap "rm -f $tempfile"
16509         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16510         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16511         # some delay may occur during ChangeLog publishing and file read just
16512         # above, that could allow file write to happen finally
16513         [[ -s $tempfile ]] && echo "file should be empty"
16514
16515         $LCTL set_param fail_loc=0
16516
16517         wait $pid
16518         [[ $? -eq 0 ]] || error "create failed"
16519 }
16520 run_test 161d "create with concurrent .lustre/fid access"
16521
16522 check_path() {
16523         local expected="$1"
16524         shift
16525         local fid="$2"
16526
16527         local path
16528         path=$($LFS fid2path "$@")
16529         local rc=$?
16530
16531         if [ $rc -ne 0 ]; then
16532                 error "path looked up of '$expected' failed: rc=$rc"
16533         elif [ "$path" != "$expected" ]; then
16534                 error "path looked up '$path' instead of '$expected'"
16535         else
16536                 echo "FID '$fid' resolves to path '$path' as expected"
16537         fi
16538 }
16539
16540 test_162a() { # was test_162
16541         test_mkdir -p -c1 $DIR/$tdir/d2
16542         touch $DIR/$tdir/d2/$tfile
16543         touch $DIR/$tdir/d2/x1
16544         touch $DIR/$tdir/d2/x2
16545         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16546         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16547         # regular file
16548         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16549         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16550
16551         # softlink
16552         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16553         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16554         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16555
16556         # softlink to wrong file
16557         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16558         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16559         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16560
16561         # hardlink
16562         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16563         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16564         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16565         # fid2path dir/fsname should both work
16566         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16567         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16568
16569         # hardlink count: check that there are 2 links
16570         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16571         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16572
16573         # hardlink indexing: remove the first link
16574         rm $DIR/$tdir/d2/p/q/r/hlink
16575         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16576 }
16577 run_test 162a "path lookup sanity"
16578
16579 test_162b() {
16580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16582
16583         mkdir $DIR/$tdir
16584         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16585                                 error "create striped dir failed"
16586
16587         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16588                                         tail -n 1 | awk '{print $2}')
16589         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16590
16591         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16592         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16593
16594         # regular file
16595         for ((i=0;i<5;i++)); do
16596                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16597                         error "get fid for f$i failed"
16598                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16599
16600                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16601                         error "get fid for d$i failed"
16602                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16603         done
16604
16605         return 0
16606 }
16607 run_test 162b "striped directory path lookup sanity"
16608
16609 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16610 test_162c() {
16611         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16612                 skip "Need MDS version at least 2.7.51"
16613
16614         local lpath=$tdir.local
16615         local rpath=$tdir.remote
16616
16617         test_mkdir $DIR/$lpath
16618         test_mkdir $DIR/$rpath
16619
16620         for ((i = 0; i <= 101; i++)); do
16621                 lpath="$lpath/$i"
16622                 mkdir $DIR/$lpath
16623                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16624                         error "get fid for local directory $DIR/$lpath failed"
16625                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16626
16627                 rpath="$rpath/$i"
16628                 test_mkdir $DIR/$rpath
16629                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16630                         error "get fid for remote directory $DIR/$rpath failed"
16631                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16632         done
16633
16634         return 0
16635 }
16636 run_test 162c "fid2path works with paths 100 or more directories deep"
16637
16638 oalr_event_count() {
16639         local event="${1}"
16640         local trace="${2}"
16641
16642         awk -v name="${FSNAME}-OST0000" \
16643             -v event="${event}" \
16644             '$1 == "TRACE" && $2 == event && $3 == name' \
16645             "${trace}" |
16646         wc -l
16647 }
16648
16649 oalr_expect_event_count() {
16650         local event="${1}"
16651         local trace="${2}"
16652         local expect="${3}"
16653         local count
16654
16655         count=$(oalr_event_count "${event}" "${trace}")
16656         if ((count == expect)); then
16657                 return 0
16658         fi
16659
16660         error_noexit "${event} event count was '${count}', expected ${expect}"
16661         cat "${trace}" >&2
16662         exit 1
16663 }
16664
16665 cleanup_165() {
16666         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16667         stop ost1
16668         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16669 }
16670
16671 setup_165() {
16672         sync # Flush previous IOs so we can count log entries.
16673         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16674         stack_trap cleanup_165 EXIT
16675 }
16676
16677 test_165a() {
16678         local trace="/tmp/${tfile}.trace"
16679         local rc
16680         local count
16681
16682         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16683                 skip "OFD access log unsupported"
16684
16685         setup_165
16686         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16687         sleep 5
16688
16689         do_facet ost1 ofd_access_log_reader --list
16690         stop ost1
16691
16692         do_facet ost1 killall -TERM ofd_access_log_reader
16693         wait
16694         rc=$?
16695
16696         if ((rc != 0)); then
16697                 error "ofd_access_log_reader exited with rc = '${rc}'"
16698         fi
16699
16700         # Parse trace file for discovery events:
16701         oalr_expect_event_count alr_log_add "${trace}" 1
16702         oalr_expect_event_count alr_log_eof "${trace}" 1
16703         oalr_expect_event_count alr_log_free "${trace}" 1
16704 }
16705 run_test 165a "ofd access log discovery"
16706
16707 test_165b() {
16708         local trace="/tmp/${tfile}.trace"
16709         local file="${DIR}/${tfile}"
16710         local pfid1
16711         local pfid2
16712         local -a entry
16713         local rc
16714         local count
16715         local size
16716         local flags
16717
16718         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16719                 skip "OFD access log unsupported"
16720
16721         setup_165
16722         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16723         sleep 5
16724
16725         do_facet ost1 ofd_access_log_reader --list
16726
16727         lfs setstripe -c 1 -i 0 "${file}"
16728         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16729                 error "cannot create '${file}'"
16730
16731         sleep 5
16732         do_facet ost1 killall -TERM ofd_access_log_reader
16733         wait
16734         rc=$?
16735
16736         if ((rc != 0)); then
16737                 error "ofd_access_log_reader exited with rc = '${rc}'"
16738         fi
16739
16740         oalr_expect_event_count alr_log_entry "${trace}" 1
16741
16742         pfid1=$($LFS path2fid "${file}")
16743
16744         # 1     2             3   4    5     6   7    8    9     10
16745         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16746         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16747
16748         echo "entry = '${entry[*]}'" >&2
16749
16750         pfid2=${entry[4]}
16751         if [[ "${pfid1}" != "${pfid2}" ]]; then
16752                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16753         fi
16754
16755         size=${entry[8]}
16756         if ((size != 1048576)); then
16757                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16758         fi
16759
16760         flags=${entry[10]}
16761         if [[ "${flags}" != "w" ]]; then
16762                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16763         fi
16764
16765         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16766         sleep 5
16767
16768         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16769                 error "cannot read '${file}'"
16770         sleep 5
16771
16772         do_facet ost1 killall -TERM ofd_access_log_reader
16773         wait
16774         rc=$?
16775
16776         if ((rc != 0)); then
16777                 error "ofd_access_log_reader exited with rc = '${rc}'"
16778         fi
16779
16780         oalr_expect_event_count alr_log_entry "${trace}" 1
16781
16782         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16783         echo "entry = '${entry[*]}'" >&2
16784
16785         pfid2=${entry[4]}
16786         if [[ "${pfid1}" != "${pfid2}" ]]; then
16787                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16788         fi
16789
16790         size=${entry[8]}
16791         if ((size != 524288)); then
16792                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16793         fi
16794
16795         flags=${entry[10]}
16796         if [[ "${flags}" != "r" ]]; then
16797                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16798         fi
16799 }
16800 run_test 165b "ofd access log entries are produced and consumed"
16801
16802 test_165c() {
16803         local trace="/tmp/${tfile}.trace"
16804         local file="${DIR}/${tdir}/${tfile}"
16805
16806         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16807                 skip "OFD access log unsupported"
16808
16809         test_mkdir "${DIR}/${tdir}"
16810
16811         setup_165
16812         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16813         sleep 5
16814
16815         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16816
16817         # 4096 / 64 = 64. Create twice as many entries.
16818         for ((i = 0; i < 128; i++)); do
16819                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16820                         error "cannot create file"
16821         done
16822
16823         sync
16824
16825         do_facet ost1 killall -TERM ofd_access_log_reader
16826         wait
16827         rc=$?
16828         if ((rc != 0)); then
16829                 error "ofd_access_log_reader exited with rc = '${rc}'"
16830         fi
16831
16832         unlinkmany  "${file}-%d" 128
16833 }
16834 run_test 165c "full ofd access logs do not block IOs"
16835
16836 oal_get_read_count() {
16837         local stats="$1"
16838
16839         # STATS lustre-OST0001 alr_read_count 1
16840
16841         do_facet ost1 cat "${stats}" |
16842         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16843              END { print count; }'
16844 }
16845
16846 oal_expect_read_count() {
16847         local stats="$1"
16848         local count
16849         local expect="$2"
16850
16851         # Ask ofd_access_log_reader to write stats.
16852         do_facet ost1 killall -USR1 ofd_access_log_reader
16853
16854         # Allow some time for things to happen.
16855         sleep 1
16856
16857         count=$(oal_get_read_count "${stats}")
16858         if ((count == expect)); then
16859                 return 0
16860         fi
16861
16862         error_noexit "bad read count, got ${count}, expected ${expect}"
16863         do_facet ost1 cat "${stats}" >&2
16864         exit 1
16865 }
16866
16867 test_165d() {
16868         local stats="/tmp/${tfile}.stats"
16869         local file="${DIR}/${tdir}/${tfile}"
16870         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16871
16872         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16873                 skip "OFD access log unsupported"
16874
16875         test_mkdir "${DIR}/${tdir}"
16876
16877         setup_165
16878         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16879         sleep 5
16880
16881         lfs setstripe -c 1 -i 0 "${file}"
16882
16883         do_facet ost1 lctl set_param "${param}=rw"
16884         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16885                 error "cannot create '${file}'"
16886         oal_expect_read_count "${stats}" 1
16887
16888         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16889                 error "cannot read '${file}'"
16890         oal_expect_read_count "${stats}" 2
16891
16892         do_facet ost1 lctl set_param "${param}=r"
16893         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16894                 error "cannot create '${file}'"
16895         oal_expect_read_count "${stats}" 2
16896
16897         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16898                 error "cannot read '${file}'"
16899         oal_expect_read_count "${stats}" 3
16900
16901         do_facet ost1 lctl set_param "${param}=w"
16902         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16903                 error "cannot create '${file}'"
16904         oal_expect_read_count "${stats}" 4
16905
16906         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16907                 error "cannot read '${file}'"
16908         oal_expect_read_count "${stats}" 4
16909
16910         do_facet ost1 lctl set_param "${param}=0"
16911         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16912                 error "cannot create '${file}'"
16913         oal_expect_read_count "${stats}" 4
16914
16915         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16916                 error "cannot read '${file}'"
16917         oal_expect_read_count "${stats}" 4
16918
16919         do_facet ost1 killall -TERM ofd_access_log_reader
16920         wait
16921         rc=$?
16922         if ((rc != 0)); then
16923                 error "ofd_access_log_reader exited with rc = '${rc}'"
16924         fi
16925 }
16926 run_test 165d "ofd_access_log mask works"
16927
16928 test_165e() {
16929         local stats="/tmp/${tfile}.stats"
16930         local file0="${DIR}/${tdir}-0/${tfile}"
16931         local file1="${DIR}/${tdir}-1/${tfile}"
16932
16933         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16934                 skip "OFD access log unsupported"
16935
16936         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16937
16938         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16939         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16940
16941         lfs setstripe -c 1 -i 0 "${file0}"
16942         lfs setstripe -c 1 -i 0 "${file1}"
16943
16944         setup_165
16945         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16946         sleep 5
16947
16948         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16949                 error "cannot create '${file0}'"
16950         sync
16951         oal_expect_read_count "${stats}" 0
16952
16953         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16954                 error "cannot create '${file1}'"
16955         sync
16956         oal_expect_read_count "${stats}" 1
16957
16958         do_facet ost1 killall -TERM ofd_access_log_reader
16959         wait
16960         rc=$?
16961         if ((rc != 0)); then
16962                 error "ofd_access_log_reader exited with rc = '${rc}'"
16963         fi
16964 }
16965 run_test 165e "ofd_access_log MDT index filter works"
16966
16967 test_165f() {
16968         local trace="/tmp/${tfile}.trace"
16969         local rc
16970         local count
16971
16972         setup_165
16973         do_facet ost1 timeout 60 ofd_access_log_reader \
16974                 --exit-on-close --debug=- --trace=- > "${trace}" &
16975         sleep 5
16976         stop ost1
16977
16978         wait
16979         rc=$?
16980
16981         if ((rc != 0)); then
16982                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16983                 cat "${trace}"
16984                 exit 1
16985         fi
16986 }
16987 run_test 165f "ofd_access_log_reader --exit-on-close works"
16988
16989 test_169() {
16990         # do directio so as not to populate the page cache
16991         log "creating a 10 Mb file"
16992         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16993                 error "multiop failed while creating a file"
16994         log "starting reads"
16995         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16996         log "truncating the file"
16997         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16998                 error "multiop failed while truncating the file"
16999         log "killing dd"
17000         kill %+ || true # reads might have finished
17001         echo "wait until dd is finished"
17002         wait
17003         log "removing the temporary file"
17004         rm -rf $DIR/$tfile || error "tmp file removal failed"
17005 }
17006 run_test 169 "parallel read and truncate should not deadlock"
17007
17008 test_170() {
17009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17010
17011         $LCTL clear     # bug 18514
17012         $LCTL debug_daemon start $TMP/${tfile}_log_good
17013         touch $DIR/$tfile
17014         $LCTL debug_daemon stop
17015         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17016                 error "sed failed to read log_good"
17017
17018         $LCTL debug_daemon start $TMP/${tfile}_log_good
17019         rm -rf $DIR/$tfile
17020         $LCTL debug_daemon stop
17021
17022         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17023                error "lctl df log_bad failed"
17024
17025         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17026         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17027
17028         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17029         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17030
17031         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17032                 error "bad_line good_line1 good_line2 are empty"
17033
17034         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17035         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17036         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17037
17038         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17039         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17040         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17041
17042         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17043                 error "bad_line_new good_line_new are empty"
17044
17045         local expected_good=$((good_line1 + good_line2*2))
17046
17047         rm -f $TMP/${tfile}*
17048         # LU-231, short malformed line may not be counted into bad lines
17049         if [ $bad_line -ne $bad_line_new ] &&
17050                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17051                 error "expected $bad_line bad lines, but got $bad_line_new"
17052                 return 1
17053         fi
17054
17055         if [ $expected_good -ne $good_line_new ]; then
17056                 error "expected $expected_good good lines, but got $good_line_new"
17057                 return 2
17058         fi
17059         true
17060 }
17061 run_test 170 "test lctl df to handle corrupted log ====================="
17062
17063 test_171() { # bug20592
17064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17065
17066         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17067         $LCTL set_param fail_loc=0x50e
17068         $LCTL set_param fail_val=3000
17069         multiop_bg_pause $DIR/$tfile O_s || true
17070         local MULTIPID=$!
17071         kill -USR1 $MULTIPID
17072         # cause log dump
17073         sleep 3
17074         wait $MULTIPID
17075         if dmesg | grep "recursive fault"; then
17076                 error "caught a recursive fault"
17077         fi
17078         $LCTL set_param fail_loc=0
17079         true
17080 }
17081 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17082
17083 # it would be good to share it with obdfilter-survey/iokit-libecho code
17084 setup_obdecho_osc () {
17085         local rc=0
17086         local ost_nid=$1
17087         local obdfilter_name=$2
17088         echo "Creating new osc for $obdfilter_name on $ost_nid"
17089         # make sure we can find loopback nid
17090         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17091
17092         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17093                            ${obdfilter_name}_osc_UUID || rc=2; }
17094         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17095                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17096         return $rc
17097 }
17098
17099 cleanup_obdecho_osc () {
17100         local obdfilter_name=$1
17101         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17102         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17103         return 0
17104 }
17105
17106 obdecho_test() {
17107         local OBD=$1
17108         local node=$2
17109         local pages=${3:-64}
17110         local rc=0
17111         local id
17112
17113         local count=10
17114         local obd_size=$(get_obd_size $node $OBD)
17115         local page_size=$(get_page_size $node)
17116         if [[ -n "$obd_size" ]]; then
17117                 local new_count=$((obd_size / (pages * page_size / 1024)))
17118                 [[ $new_count -ge $count ]] || count=$new_count
17119         fi
17120
17121         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17122         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17123                            rc=2; }
17124         if [ $rc -eq 0 ]; then
17125             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17126             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17127         fi
17128         echo "New object id is $id"
17129         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17130                            rc=4; }
17131         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17132                            "test_brw $count w v $pages $id" || rc=4; }
17133         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17134                            rc=4; }
17135         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17136                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17137         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17138                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17139         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17140         return $rc
17141 }
17142
17143 test_180a() {
17144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17145
17146         if ! [ -d /sys/fs/lustre/echo_client ] &&
17147            ! module_loaded obdecho; then
17148                 load_module obdecho/obdecho &&
17149                         stack_trap "rmmod obdecho" EXIT ||
17150                         error "unable to load obdecho on client"
17151         fi
17152
17153         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17154         local host=$($LCTL get_param -n osc.$osc.import |
17155                      awk '/current_connection:/ { print $2 }' )
17156         local target=$($LCTL get_param -n osc.$osc.import |
17157                        awk '/target:/ { print $2 }' )
17158         target=${target%_UUID}
17159
17160         if [ -n "$target" ]; then
17161                 setup_obdecho_osc $host $target &&
17162                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17163                         { error "obdecho setup failed with $?"; return; }
17164
17165                 obdecho_test ${target}_osc client ||
17166                         error "obdecho_test failed on ${target}_osc"
17167         else
17168                 $LCTL get_param osc.$osc.import
17169                 error "there is no osc.$osc.import target"
17170         fi
17171 }
17172 run_test 180a "test obdecho on osc"
17173
17174 test_180b() {
17175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17176         remote_ost_nodsh && skip "remote OST with nodsh"
17177
17178         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17179                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17180                 error "failed to load module obdecho"
17181
17182         local target=$(do_facet ost1 $LCTL dl |
17183                        awk '/obdfilter/ { print $4; exit; }')
17184
17185         if [ -n "$target" ]; then
17186                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17187         else
17188                 do_facet ost1 $LCTL dl
17189                 error "there is no obdfilter target on ost1"
17190         fi
17191 }
17192 run_test 180b "test obdecho directly on obdfilter"
17193
17194 test_180c() { # LU-2598
17195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17196         remote_ost_nodsh && skip "remote OST with nodsh"
17197         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17198                 skip "Need MDS version at least 2.4.0"
17199
17200         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17201                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17202                 error "failed to load module obdecho"
17203
17204         local target=$(do_facet ost1 $LCTL dl |
17205                        awk '/obdfilter/ { print $4; exit; }')
17206
17207         if [ -n "$target" ]; then
17208                 local pages=16384 # 64MB bulk I/O RPC size
17209
17210                 obdecho_test "$target" ost1 "$pages" ||
17211                         error "obdecho_test with pages=$pages failed with $?"
17212         else
17213                 do_facet ost1 $LCTL dl
17214                 error "there is no obdfilter target on ost1"
17215         fi
17216 }
17217 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17218
17219 test_181() { # bug 22177
17220         test_mkdir $DIR/$tdir
17221         # create enough files to index the directory
17222         createmany -o $DIR/$tdir/foobar 4000
17223         # print attributes for debug purpose
17224         lsattr -d .
17225         # open dir
17226         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17227         MULTIPID=$!
17228         # remove the files & current working dir
17229         unlinkmany $DIR/$tdir/foobar 4000
17230         rmdir $DIR/$tdir
17231         kill -USR1 $MULTIPID
17232         wait $MULTIPID
17233         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17234         return 0
17235 }
17236 run_test 181 "Test open-unlinked dir ========================"
17237
17238 test_182() {
17239         local fcount=1000
17240         local tcount=10
17241
17242         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17243
17244         $LCTL set_param mdc.*.rpc_stats=clear
17245
17246         for (( i = 0; i < $tcount; i++ )) ; do
17247                 mkdir $DIR/$tdir/$i
17248         done
17249
17250         for (( i = 0; i < $tcount; i++ )) ; do
17251                 createmany -o $DIR/$tdir/$i/f- $fcount &
17252         done
17253         wait
17254
17255         for (( i = 0; i < $tcount; i++ )) ; do
17256                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17257         done
17258         wait
17259
17260         $LCTL get_param mdc.*.rpc_stats
17261
17262         rm -rf $DIR/$tdir
17263 }
17264 run_test 182 "Test parallel modify metadata operations ================"
17265
17266 test_183() { # LU-2275
17267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17268         remote_mds_nodsh && skip "remote MDS with nodsh"
17269         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17270                 skip "Need MDS version at least 2.3.56"
17271
17272         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17273         echo aaa > $DIR/$tdir/$tfile
17274
17275 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17276         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17277
17278         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17279         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17280
17281         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17282
17283         # Flush negative dentry cache
17284         touch $DIR/$tdir/$tfile
17285
17286         # We are not checking for any leaked references here, they'll
17287         # become evident next time we do cleanup with module unload.
17288         rm -rf $DIR/$tdir
17289 }
17290 run_test 183 "No crash or request leak in case of strange dispositions ========"
17291
17292 # test suite 184 is for LU-2016, LU-2017
17293 test_184a() {
17294         check_swap_layouts_support
17295
17296         dir0=$DIR/$tdir/$testnum
17297         test_mkdir -p -c1 $dir0
17298         ref1=/etc/passwd
17299         ref2=/etc/group
17300         file1=$dir0/f1
17301         file2=$dir0/f2
17302         $LFS setstripe -c1 $file1
17303         cp $ref1 $file1
17304         $LFS setstripe -c2 $file2
17305         cp $ref2 $file2
17306         gen1=$($LFS getstripe -g $file1)
17307         gen2=$($LFS getstripe -g $file2)
17308
17309         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17310         gen=$($LFS getstripe -g $file1)
17311         [[ $gen1 != $gen ]] ||
17312                 "Layout generation on $file1 does not change"
17313         gen=$($LFS getstripe -g $file2)
17314         [[ $gen2 != $gen ]] ||
17315                 "Layout generation on $file2 does not change"
17316
17317         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17318         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17319
17320         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17321 }
17322 run_test 184a "Basic layout swap"
17323
17324 test_184b() {
17325         check_swap_layouts_support
17326
17327         dir0=$DIR/$tdir/$testnum
17328         mkdir -p $dir0 || error "creating dir $dir0"
17329         file1=$dir0/f1
17330         file2=$dir0/f2
17331         file3=$dir0/f3
17332         dir1=$dir0/d1
17333         dir2=$dir0/d2
17334         mkdir $dir1 $dir2
17335         $LFS setstripe -c1 $file1
17336         $LFS setstripe -c2 $file2
17337         $LFS setstripe -c1 $file3
17338         chown $RUNAS_ID $file3
17339         gen1=$($LFS getstripe -g $file1)
17340         gen2=$($LFS getstripe -g $file2)
17341
17342         $LFS swap_layouts $dir1 $dir2 &&
17343                 error "swap of directories layouts should fail"
17344         $LFS swap_layouts $dir1 $file1 &&
17345                 error "swap of directory and file layouts should fail"
17346         $RUNAS $LFS swap_layouts $file1 $file2 &&
17347                 error "swap of file we cannot write should fail"
17348         $LFS swap_layouts $file1 $file3 &&
17349                 error "swap of file with different owner should fail"
17350         /bin/true # to clear error code
17351 }
17352 run_test 184b "Forbidden layout swap (will generate errors)"
17353
17354 test_184c() {
17355         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17356         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17357         check_swap_layouts_support
17358         check_swap_layout_no_dom $DIR
17359
17360         local dir0=$DIR/$tdir/$testnum
17361         mkdir -p $dir0 || error "creating dir $dir0"
17362
17363         local ref1=$dir0/ref1
17364         local ref2=$dir0/ref2
17365         local file1=$dir0/file1
17366         local file2=$dir0/file2
17367         # create a file large enough for the concurrent test
17368         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17369         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17370         echo "ref file size: ref1($(stat -c %s $ref1))," \
17371              "ref2($(stat -c %s $ref2))"
17372
17373         cp $ref2 $file2
17374         dd if=$ref1 of=$file1 bs=16k &
17375         local DD_PID=$!
17376
17377         # Make sure dd starts to copy file, but wait at most 5 seconds
17378         local loops=0
17379         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17380
17381         $LFS swap_layouts $file1 $file2
17382         local rc=$?
17383         wait $DD_PID
17384         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17385         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17386
17387         # how many bytes copied before swapping layout
17388         local copied=$(stat -c %s $file2)
17389         local remaining=$(stat -c %s $ref1)
17390         remaining=$((remaining - copied))
17391         echo "Copied $copied bytes before swapping layout..."
17392
17393         cmp -n $copied $file1 $ref2 | grep differ &&
17394                 error "Content mismatch [0, $copied) of ref2 and file1"
17395         cmp -n $copied $file2 $ref1 ||
17396                 error "Content mismatch [0, $copied) of ref1 and file2"
17397         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17398                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17399
17400         # clean up
17401         rm -f $ref1 $ref2 $file1 $file2
17402 }
17403 run_test 184c "Concurrent write and layout swap"
17404
17405 test_184d() {
17406         check_swap_layouts_support
17407         check_swap_layout_no_dom $DIR
17408         [ -z "$(which getfattr 2>/dev/null)" ] &&
17409                 skip_env "no getfattr command"
17410
17411         local file1=$DIR/$tdir/$tfile-1
17412         local file2=$DIR/$tdir/$tfile-2
17413         local file3=$DIR/$tdir/$tfile-3
17414         local lovea1
17415         local lovea2
17416
17417         mkdir -p $DIR/$tdir
17418         touch $file1 || error "create $file1 failed"
17419         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17420                 error "create $file2 failed"
17421         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17422                 error "create $file3 failed"
17423         lovea1=$(get_layout_param $file1)
17424
17425         $LFS swap_layouts $file2 $file3 ||
17426                 error "swap $file2 $file3 layouts failed"
17427         $LFS swap_layouts $file1 $file2 ||
17428                 error "swap $file1 $file2 layouts failed"
17429
17430         lovea2=$(get_layout_param $file2)
17431         echo "$lovea1"
17432         echo "$lovea2"
17433         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17434
17435         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17436         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17437 }
17438 run_test 184d "allow stripeless layouts swap"
17439
17440 test_184e() {
17441         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17442                 skip "Need MDS version at least 2.6.94"
17443         check_swap_layouts_support
17444         check_swap_layout_no_dom $DIR
17445         [ -z "$(which getfattr 2>/dev/null)" ] &&
17446                 skip_env "no getfattr command"
17447
17448         local file1=$DIR/$tdir/$tfile-1
17449         local file2=$DIR/$tdir/$tfile-2
17450         local file3=$DIR/$tdir/$tfile-3
17451         local lovea
17452
17453         mkdir -p $DIR/$tdir
17454         touch $file1 || error "create $file1 failed"
17455         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17456                 error "create $file2 failed"
17457         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17458                 error "create $file3 failed"
17459
17460         $LFS swap_layouts $file1 $file2 ||
17461                 error "swap $file1 $file2 layouts failed"
17462
17463         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17464         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17465
17466         echo 123 > $file1 || error "Should be able to write into $file1"
17467
17468         $LFS swap_layouts $file1 $file3 ||
17469                 error "swap $file1 $file3 layouts failed"
17470
17471         echo 123 > $file1 || error "Should be able to write into $file1"
17472
17473         rm -rf $file1 $file2 $file3
17474 }
17475 run_test 184e "Recreate layout after stripeless layout swaps"
17476
17477 test_184f() {
17478         # Create a file with name longer than sizeof(struct stat) ==
17479         # 144 to see if we can get chars from the file name to appear
17480         # in the returned striping. Note that 'f' == 0x66.
17481         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17482
17483         mkdir -p $DIR/$tdir
17484         mcreate $DIR/$tdir/$file
17485         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17486                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17487         fi
17488 }
17489 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17490
17491 test_185() { # LU-2441
17492         # LU-3553 - no volatile file support in old servers
17493         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17494                 skip "Need MDS version at least 2.3.60"
17495
17496         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17497         touch $DIR/$tdir/spoo
17498         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17499         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17500                 error "cannot create/write a volatile file"
17501         [ "$FILESET" == "" ] &&
17502         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17503                 error "FID is still valid after close"
17504
17505         multiop_bg_pause $DIR/$tdir vVw4096_c
17506         local multi_pid=$!
17507
17508         local OLD_IFS=$IFS
17509         IFS=":"
17510         local fidv=($fid)
17511         IFS=$OLD_IFS
17512         # assume that the next FID for this client is sequential, since stdout
17513         # is unfortunately eaten by multiop_bg_pause
17514         local n=$((${fidv[1]} + 1))
17515         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17516         if [ "$FILESET" == "" ]; then
17517                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17518                         error "FID is missing before close"
17519         fi
17520         kill -USR1 $multi_pid
17521         # 1 second delay, so if mtime change we will see it
17522         sleep 1
17523         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17524         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17525 }
17526 run_test 185 "Volatile file support"
17527
17528 function create_check_volatile() {
17529         local idx=$1
17530         local tgt
17531
17532         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17533         local PID=$!
17534         sleep 1
17535         local FID=$(cat /tmp/${tfile}.fid)
17536         [ "$FID" == "" ] && error "can't get FID for volatile"
17537         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17538         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17539         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17540         kill -USR1 $PID
17541         wait
17542         sleep 1
17543         cancel_lru_locks mdc # flush opencache
17544         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17545         return 0
17546 }
17547
17548 test_185a(){
17549         # LU-12516 - volatile creation via .lustre
17550         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17551                 skip "Need MDS version at least 2.3.55"
17552
17553         create_check_volatile 0
17554         [ $MDSCOUNT -lt 2 ] && return 0
17555
17556         # DNE case
17557         create_check_volatile 1
17558
17559         return 0
17560 }
17561 run_test 185a "Volatile file creation in .lustre/fid/"
17562
17563 test_187a() {
17564         remote_mds_nodsh && skip "remote MDS with nodsh"
17565         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17566                 skip "Need MDS version at least 2.3.0"
17567
17568         local dir0=$DIR/$tdir/$testnum
17569         mkdir -p $dir0 || error "creating dir $dir0"
17570
17571         local file=$dir0/file1
17572         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17573         local dv1=$($LFS data_version $file)
17574         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17575         local dv2=$($LFS data_version $file)
17576         [[ $dv1 != $dv2 ]] ||
17577                 error "data version did not change on write $dv1 == $dv2"
17578
17579         # clean up
17580         rm -f $file1
17581 }
17582 run_test 187a "Test data version change"
17583
17584 test_187b() {
17585         remote_mds_nodsh && skip "remote MDS with nodsh"
17586         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17587                 skip "Need MDS version at least 2.3.0"
17588
17589         local dir0=$DIR/$tdir/$testnum
17590         mkdir -p $dir0 || error "creating dir $dir0"
17591
17592         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17593         [[ ${DV[0]} != ${DV[1]} ]] ||
17594                 error "data version did not change on write"\
17595                       " ${DV[0]} == ${DV[1]}"
17596
17597         # clean up
17598         rm -f $file1
17599 }
17600 run_test 187b "Test data version change on volatile file"
17601
17602 test_200() {
17603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17604         remote_mgs_nodsh && skip "remote MGS with nodsh"
17605         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17606
17607         local POOL=${POOL:-cea1}
17608         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17609         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17610         # Pool OST targets
17611         local first_ost=0
17612         local last_ost=$(($OSTCOUNT - 1))
17613         local ost_step=2
17614         local ost_list=$(seq $first_ost $ost_step $last_ost)
17615         local ost_range="$first_ost $last_ost $ost_step"
17616         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17617         local file_dir=$POOL_ROOT/file_tst
17618         local subdir=$test_path/subdir
17619         local rc=0
17620
17621         while : ; do
17622                 # former test_200a test_200b
17623                 pool_add $POOL                          || { rc=$? ; break; }
17624                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17625                 # former test_200c test_200d
17626                 mkdir -p $test_path
17627                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17628                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17629                 mkdir -p $subdir
17630                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17631                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17632                                                         || { rc=$? ; break; }
17633                 # former test_200e test_200f
17634                 local files=$((OSTCOUNT*3))
17635                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17636                                                         || { rc=$? ; break; }
17637                 pool_create_files $POOL $file_dir $files "$ost_list" \
17638                                                         || { rc=$? ; break; }
17639                 # former test_200g test_200h
17640                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17641                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17642
17643                 # former test_201a test_201b test_201c
17644                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17645
17646                 local f=$test_path/$tfile
17647                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17648                 pool_remove $POOL $f                    || { rc=$? ; break; }
17649                 break
17650         done
17651
17652         destroy_test_pools
17653
17654         return $rc
17655 }
17656 run_test 200 "OST pools"
17657
17658 # usage: default_attr <count | size | offset>
17659 default_attr() {
17660         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17661 }
17662
17663 # usage: check_default_stripe_attr
17664 check_default_stripe_attr() {
17665         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17666         case $1 in
17667         --stripe-count|-c)
17668                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17669         --stripe-size|-S)
17670                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17671         --stripe-index|-i)
17672                 EXPECTED=-1;;
17673         *)
17674                 error "unknown getstripe attr '$1'"
17675         esac
17676
17677         [ $ACTUAL == $EXPECTED ] ||
17678                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17679 }
17680
17681 test_204a() {
17682         test_mkdir $DIR/$tdir
17683         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17684
17685         check_default_stripe_attr --stripe-count
17686         check_default_stripe_attr --stripe-size
17687         check_default_stripe_attr --stripe-index
17688 }
17689 run_test 204a "Print default stripe attributes"
17690
17691 test_204b() {
17692         test_mkdir $DIR/$tdir
17693         $LFS setstripe --stripe-count 1 $DIR/$tdir
17694
17695         check_default_stripe_attr --stripe-size
17696         check_default_stripe_attr --stripe-index
17697 }
17698 run_test 204b "Print default stripe size and offset"
17699
17700 test_204c() {
17701         test_mkdir $DIR/$tdir
17702         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17703
17704         check_default_stripe_attr --stripe-count
17705         check_default_stripe_attr --stripe-index
17706 }
17707 run_test 204c "Print default stripe count and offset"
17708
17709 test_204d() {
17710         test_mkdir $DIR/$tdir
17711         $LFS setstripe --stripe-index 0 $DIR/$tdir
17712
17713         check_default_stripe_attr --stripe-count
17714         check_default_stripe_attr --stripe-size
17715 }
17716 run_test 204d "Print default stripe count and size"
17717
17718 test_204e() {
17719         test_mkdir $DIR/$tdir
17720         $LFS setstripe -d $DIR/$tdir
17721
17722         check_default_stripe_attr --stripe-count --raw
17723         check_default_stripe_attr --stripe-size --raw
17724         check_default_stripe_attr --stripe-index --raw
17725 }
17726 run_test 204e "Print raw stripe attributes"
17727
17728 test_204f() {
17729         test_mkdir $DIR/$tdir
17730         $LFS setstripe --stripe-count 1 $DIR/$tdir
17731
17732         check_default_stripe_attr --stripe-size --raw
17733         check_default_stripe_attr --stripe-index --raw
17734 }
17735 run_test 204f "Print raw stripe size and offset"
17736
17737 test_204g() {
17738         test_mkdir $DIR/$tdir
17739         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17740
17741         check_default_stripe_attr --stripe-count --raw
17742         check_default_stripe_attr --stripe-index --raw
17743 }
17744 run_test 204g "Print raw stripe count and offset"
17745
17746 test_204h() {
17747         test_mkdir $DIR/$tdir
17748         $LFS setstripe --stripe-index 0 $DIR/$tdir
17749
17750         check_default_stripe_attr --stripe-count --raw
17751         check_default_stripe_attr --stripe-size --raw
17752 }
17753 run_test 204h "Print raw stripe count and size"
17754
17755 # Figure out which job scheduler is being used, if any,
17756 # or use a fake one
17757 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17758         JOBENV=SLURM_JOB_ID
17759 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17760         JOBENV=LSB_JOBID
17761 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17762         JOBENV=PBS_JOBID
17763 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17764         JOBENV=LOADL_STEP_ID
17765 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17766         JOBENV=JOB_ID
17767 else
17768         $LCTL list_param jobid_name > /dev/null 2>&1
17769         if [ $? -eq 0 ]; then
17770                 JOBENV=nodelocal
17771         else
17772                 JOBENV=FAKE_JOBID
17773         fi
17774 fi
17775 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17776
17777 verify_jobstats() {
17778         local cmd=($1)
17779         shift
17780         local facets="$@"
17781
17782 # we don't really need to clear the stats for this test to work, since each
17783 # command has a unique jobid, but it makes debugging easier if needed.
17784 #       for facet in $facets; do
17785 #               local dev=$(convert_facet2label $facet)
17786 #               # clear old jobstats
17787 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17788 #       done
17789
17790         # use a new JobID for each test, or we might see an old one
17791         [ "$JOBENV" = "FAKE_JOBID" ] &&
17792                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17793
17794         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17795
17796         [ "$JOBENV" = "nodelocal" ] && {
17797                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17798                 $LCTL set_param jobid_name=$FAKE_JOBID
17799                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17800         }
17801
17802         log "Test: ${cmd[*]}"
17803         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17804
17805         if [ $JOBENV = "FAKE_JOBID" ]; then
17806                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17807         else
17808                 ${cmd[*]}
17809         fi
17810
17811         # all files are created on OST0000
17812         for facet in $facets; do
17813                 local stats="*.$(convert_facet2label $facet).job_stats"
17814
17815                 # strip out libtool wrappers for in-tree executables
17816                 if [ $(do_facet $facet lctl get_param $stats |
17817                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17818                         do_facet $facet lctl get_param $stats
17819                         error "No jobstats for $JOBVAL found on $facet::$stats"
17820                 fi
17821         done
17822 }
17823
17824 jobstats_set() {
17825         local new_jobenv=$1
17826
17827         set_persistent_param_and_check client "jobid_var" \
17828                 "$FSNAME.sys.jobid_var" $new_jobenv
17829 }
17830
17831 test_205a() { # Job stats
17832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17833         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17834                 skip "Need MDS version with at least 2.7.1"
17835         remote_mgs_nodsh && skip "remote MGS with nodsh"
17836         remote_mds_nodsh && skip "remote MDS with nodsh"
17837         remote_ost_nodsh && skip "remote OST with nodsh"
17838         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17839                 skip "Server doesn't support jobstats"
17840         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17841
17842         local old_jobenv=$($LCTL get_param -n jobid_var)
17843         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17844
17845         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17846                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17847         else
17848                 stack_trap "do_facet mgs $PERM_CMD \
17849                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17850         fi
17851         changelog_register
17852
17853         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17854                                 mdt.*.job_cleanup_interval | head -n 1)
17855         local new_interval=5
17856         do_facet $SINGLEMDS \
17857                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17858         stack_trap "do_facet $SINGLEMDS \
17859                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17860         local start=$SECONDS
17861
17862         local cmd
17863         # mkdir
17864         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17865         verify_jobstats "$cmd" "$SINGLEMDS"
17866         # rmdir
17867         cmd="rmdir $DIR/$tdir"
17868         verify_jobstats "$cmd" "$SINGLEMDS"
17869         # mkdir on secondary MDT
17870         if [ $MDSCOUNT -gt 1 ]; then
17871                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17872                 verify_jobstats "$cmd" "mds2"
17873         fi
17874         # mknod
17875         cmd="mknod $DIR/$tfile c 1 3"
17876         verify_jobstats "$cmd" "$SINGLEMDS"
17877         # unlink
17878         cmd="rm -f $DIR/$tfile"
17879         verify_jobstats "$cmd" "$SINGLEMDS"
17880         # create all files on OST0000 so verify_jobstats can find OST stats
17881         # open & close
17882         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17883         verify_jobstats "$cmd" "$SINGLEMDS"
17884         # setattr
17885         cmd="touch $DIR/$tfile"
17886         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17887         # write
17888         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17889         verify_jobstats "$cmd" "ost1"
17890         # read
17891         cancel_lru_locks osc
17892         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17893         verify_jobstats "$cmd" "ost1"
17894         # truncate
17895         cmd="$TRUNCATE $DIR/$tfile 0"
17896         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17897         # rename
17898         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17899         verify_jobstats "$cmd" "$SINGLEMDS"
17900         # jobstats expiry - sleep until old stats should be expired
17901         local left=$((new_interval + 5 - (SECONDS - start)))
17902         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17903                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17904                         "0" $left
17905         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17906         verify_jobstats "$cmd" "$SINGLEMDS"
17907         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17908             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17909
17910         # Ensure that jobid are present in changelog (if supported by MDS)
17911         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17912                 changelog_dump | tail -10
17913                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17914                 [ $jobids -eq 9 ] ||
17915                         error "Wrong changelog jobid count $jobids != 9"
17916
17917                 # LU-5862
17918                 JOBENV="disable"
17919                 jobstats_set $JOBENV
17920                 touch $DIR/$tfile
17921                 changelog_dump | grep $tfile
17922                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17923                 [ $jobids -eq 0 ] ||
17924                         error "Unexpected jobids when jobid_var=$JOBENV"
17925         fi
17926
17927         # test '%j' access to environment variable - if supported
17928         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17929                 JOBENV="JOBCOMPLEX"
17930                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17931
17932                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17933         fi
17934
17935         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17936                 JOBENV="JOBCOMPLEX"
17937                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17938
17939                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17940         fi
17941
17942         # test '%j' access to per-session jobid - if supported
17943         if lctl list_param jobid_this_session > /dev/null 2>&1
17944         then
17945                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17946                 lctl set_param jobid_this_session=$USER
17947
17948                 JOBENV="JOBCOMPLEX"
17949                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17950
17951                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17952         fi
17953 }
17954 run_test 205a "Verify job stats"
17955
17956 # LU-13117, LU-13597
17957 test_205b() {
17958         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
17959                 skip "Need MDS version at least 2.13.54.91"
17960
17961         job_stats="mdt.*.job_stats"
17962         $LCTL set_param $job_stats=clear
17963         # Setting jobid_var to USER might not be supported
17964         $LCTL set_param jobid_var=USER || true
17965         $LCTL set_param jobid_name="%e.%u"
17966         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17967         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17968                 grep "job_id:.*foolish" &&
17969                         error "Unexpected jobid found"
17970         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17971                 grep "open:.*min.*max.*sum" ||
17972                         error "wrong job_stats format found"
17973 }
17974 run_test 205b "Verify job stats jobid and output format"
17975
17976 # LU-13733
17977 test_205c() {
17978         $LCTL set_param llite.*.stats=0
17979         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17980         $LCTL get_param llite.*.stats
17981         $LCTL get_param llite.*.stats | grep \
17982                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17983                         error "wrong client stats format found"
17984 }
17985 run_test 205c "Verify client stats format"
17986
17987 # LU-1480, LU-1773 and LU-1657
17988 test_206() {
17989         mkdir -p $DIR/$tdir
17990         $LFS setstripe -c -1 $DIR/$tdir
17991 #define OBD_FAIL_LOV_INIT 0x1403
17992         $LCTL set_param fail_loc=0xa0001403
17993         $LCTL set_param fail_val=1
17994         touch $DIR/$tdir/$tfile || true
17995 }
17996 run_test 206 "fail lov_init_raid0() doesn't lbug"
17997
17998 test_207a() {
17999         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18000         local fsz=`stat -c %s $DIR/$tfile`
18001         cancel_lru_locks mdc
18002
18003         # do not return layout in getattr intent
18004 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18005         $LCTL set_param fail_loc=0x170
18006         local sz=`stat -c %s $DIR/$tfile`
18007
18008         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18009
18010         rm -rf $DIR/$tfile
18011 }
18012 run_test 207a "can refresh layout at glimpse"
18013
18014 test_207b() {
18015         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18016         local cksum=`md5sum $DIR/$tfile`
18017         local fsz=`stat -c %s $DIR/$tfile`
18018         cancel_lru_locks mdc
18019         cancel_lru_locks osc
18020
18021         # do not return layout in getattr intent
18022 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18023         $LCTL set_param fail_loc=0x171
18024
18025         # it will refresh layout after the file is opened but before read issues
18026         echo checksum is "$cksum"
18027         echo "$cksum" |md5sum -c --quiet || error "file differs"
18028
18029         rm -rf $DIR/$tfile
18030 }
18031 run_test 207b "can refresh layout at open"
18032
18033 test_208() {
18034         # FIXME: in this test suite, only RD lease is used. This is okay
18035         # for now as only exclusive open is supported. After generic lease
18036         # is done, this test suite should be revised. - Jinshan
18037
18038         remote_mds_nodsh && skip "remote MDS with nodsh"
18039         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18040                 skip "Need MDS version at least 2.4.52"
18041
18042         echo "==== test 1: verify get lease work"
18043         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18044
18045         echo "==== test 2: verify lease can be broken by upcoming open"
18046         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18047         local PID=$!
18048         sleep 1
18049
18050         $MULTIOP $DIR/$tfile oO_RDONLY:c
18051         kill -USR1 $PID && wait $PID || error "break lease error"
18052
18053         echo "==== test 3: verify lease can't be granted if an open already exists"
18054         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
18055         local PID=$!
18056         sleep 1
18057
18058         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
18059         kill -USR1 $PID && wait $PID || error "open file error"
18060
18061         echo "==== test 4: lease can sustain over recovery"
18062         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18063         PID=$!
18064         sleep 1
18065
18066         fail mds1
18067
18068         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18069
18070         echo "==== test 5: lease broken can't be regained by replay"
18071         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18072         PID=$!
18073         sleep 1
18074
18075         # open file to break lease and then recovery
18076         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18077         fail mds1
18078
18079         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18080
18081         rm -f $DIR/$tfile
18082 }
18083 run_test 208 "Exclusive open"
18084
18085 test_209() {
18086         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18087                 skip_env "must have disp_stripe"
18088
18089         touch $DIR/$tfile
18090         sync; sleep 5; sync;
18091
18092         echo 3 > /proc/sys/vm/drop_caches
18093         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18094                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18095         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18096
18097         # open/close 500 times
18098         for i in $(seq 500); do
18099                 cat $DIR/$tfile
18100         done
18101
18102         echo 3 > /proc/sys/vm/drop_caches
18103         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18104                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18105         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18106
18107         echo "before: $req_before, after: $req_after"
18108         [ $((req_after - req_before)) -ge 300 ] &&
18109                 error "open/close requests are not freed"
18110         return 0
18111 }
18112 run_test 209 "read-only open/close requests should be freed promptly"
18113
18114 test_210() {
18115         local pid
18116
18117         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18118         pid=$!
18119         sleep 1
18120
18121         $LFS getstripe $DIR/$tfile
18122         kill -USR1 $pid
18123         wait $pid || error "multiop failed"
18124
18125         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18126         pid=$!
18127         sleep 1
18128
18129         $LFS getstripe $DIR/$tfile
18130         kill -USR1 $pid
18131         wait $pid || error "multiop failed"
18132 }
18133 run_test 210 "lfs getstripe does not break leases"
18134
18135 test_212() {
18136         size=`date +%s`
18137         size=$((size % 8192 + 1))
18138         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18139         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18140         rm -f $DIR/f212 $DIR/f212.xyz
18141 }
18142 run_test 212 "Sendfile test ============================================"
18143
18144 test_213() {
18145         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18146         cancel_lru_locks osc
18147         lctl set_param fail_loc=0x8000040f
18148         # generate a read lock
18149         cat $DIR/$tfile > /dev/null
18150         # write to the file, it will try to cancel the above read lock.
18151         cat /etc/hosts >> $DIR/$tfile
18152 }
18153 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18154
18155 test_214() { # for bug 20133
18156         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18157         for (( i=0; i < 340; i++ )) ; do
18158                 touch $DIR/$tdir/d214c/a$i
18159         done
18160
18161         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18162         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18163         ls $DIR/d214c || error "ls $DIR/d214c failed"
18164         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18165         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18166 }
18167 run_test 214 "hash-indexed directory test - bug 20133"
18168
18169 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18170 create_lnet_proc_files() {
18171         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18172 }
18173
18174 # counterpart of create_lnet_proc_files
18175 remove_lnet_proc_files() {
18176         rm -f $TMP/lnet_$1.sys
18177 }
18178
18179 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18180 # 3rd arg as regexp for body
18181 check_lnet_proc_stats() {
18182         local l=$(cat "$TMP/lnet_$1" |wc -l)
18183         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18184
18185         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18186 }
18187
18188 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18189 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18190 # optional and can be regexp for 2nd line (lnet.routes case)
18191 check_lnet_proc_entry() {
18192         local blp=2          # blp stands for 'position of 1st line of body'
18193         [ -z "$5" ] || blp=3 # lnet.routes case
18194
18195         local l=$(cat "$TMP/lnet_$1" |wc -l)
18196         # subtracting one from $blp because the body can be empty
18197         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18198
18199         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18200                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18201
18202         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18203                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18204
18205         # bail out if any unexpected line happened
18206         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18207         [ "$?" != 0 ] || error "$2 misformatted"
18208 }
18209
18210 test_215() { # for bugs 18102, 21079, 21517
18211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18212
18213         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18214         local P='[1-9][0-9]*'           # positive numeric
18215         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18216         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18217         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18218         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18219
18220         local L1 # regexp for 1st line
18221         local L2 # regexp for 2nd line (optional)
18222         local BR # regexp for the rest (body)
18223
18224         # lnet.stats should look as 11 space-separated non-negative numerics
18225         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18226         create_lnet_proc_files "stats"
18227         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18228         remove_lnet_proc_files "stats"
18229
18230         # lnet.routes should look like this:
18231         # Routing disabled/enabled
18232         # net hops priority state router
18233         # where net is a string like tcp0, hops > 0, priority >= 0,
18234         # state is up/down,
18235         # router is a string like 192.168.1.1@tcp2
18236         L1="^Routing (disabled|enabled)$"
18237         L2="^net +hops +priority +state +router$"
18238         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18239         create_lnet_proc_files "routes"
18240         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18241         remove_lnet_proc_files "routes"
18242
18243         # lnet.routers should look like this:
18244         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18245         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18246         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18247         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18248         L1="^ref +rtr_ref +alive +router$"
18249         BR="^$P +$P +(up|down) +$NID$"
18250         create_lnet_proc_files "routers"
18251         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18252         remove_lnet_proc_files "routers"
18253
18254         # lnet.peers should look like this:
18255         # nid refs state last max rtr min tx min queue
18256         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18257         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18258         # numeric (0 or >0 or <0), queue >= 0.
18259         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18260         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18261         create_lnet_proc_files "peers"
18262         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18263         remove_lnet_proc_files "peers"
18264
18265         # lnet.buffers  should look like this:
18266         # pages count credits min
18267         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18268         L1="^pages +count +credits +min$"
18269         BR="^ +$N +$N +$I +$I$"
18270         create_lnet_proc_files "buffers"
18271         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18272         remove_lnet_proc_files "buffers"
18273
18274         # lnet.nis should look like this:
18275         # nid status alive refs peer rtr max tx min
18276         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18277         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18278         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18279         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18280         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18281         create_lnet_proc_files "nis"
18282         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18283         remove_lnet_proc_files "nis"
18284
18285         # can we successfully write to lnet.stats?
18286         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18287 }
18288 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18289
18290 test_216() { # bug 20317
18291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18292         remote_ost_nodsh && skip "remote OST with nodsh"
18293
18294         local node
18295         local facets=$(get_facets OST)
18296         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18297
18298         save_lustre_params client "osc.*.contention_seconds" > $p
18299         save_lustre_params $facets \
18300                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18301         save_lustre_params $facets \
18302                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18303         save_lustre_params $facets \
18304                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18305         clear_stats osc.*.osc_stats
18306
18307         # agressive lockless i/o settings
18308         do_nodes $(comma_list $(osts_nodes)) \
18309                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18310                         ldlm.namespaces.filter-*.contended_locks=0 \
18311                         ldlm.namespaces.filter-*.contention_seconds=60"
18312         lctl set_param -n osc.*.contention_seconds=60
18313
18314         $DIRECTIO write $DIR/$tfile 0 10 4096
18315         $CHECKSTAT -s 40960 $DIR/$tfile
18316
18317         # disable lockless i/o
18318         do_nodes $(comma_list $(osts_nodes)) \
18319                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18320                         ldlm.namespaces.filter-*.contended_locks=32 \
18321                         ldlm.namespaces.filter-*.contention_seconds=0"
18322         lctl set_param -n osc.*.contention_seconds=0
18323         clear_stats osc.*.osc_stats
18324
18325         dd if=/dev/zero of=$DIR/$tfile count=0
18326         $CHECKSTAT -s 0 $DIR/$tfile
18327
18328         restore_lustre_params <$p
18329         rm -f $p
18330         rm $DIR/$tfile
18331 }
18332 run_test 216 "check lockless direct write updates file size and kms correctly"
18333
18334 test_217() { # bug 22430
18335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18336
18337         local node
18338         local nid
18339
18340         for node in $(nodes_list); do
18341                 nid=$(host_nids_address $node $NETTYPE)
18342                 if [[ $nid = *-* ]] ; then
18343                         echo "lctl ping $(h2nettype $nid)"
18344                         lctl ping $(h2nettype $nid)
18345                 else
18346                         echo "skipping $node (no hyphen detected)"
18347                 fi
18348         done
18349 }
18350 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18351
18352 test_218() {
18353        # do directio so as not to populate the page cache
18354        log "creating a 10 Mb file"
18355        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18356        log "starting reads"
18357        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18358        log "truncating the file"
18359        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18360        log "killing dd"
18361        kill %+ || true # reads might have finished
18362        echo "wait until dd is finished"
18363        wait
18364        log "removing the temporary file"
18365        rm -rf $DIR/$tfile || error "tmp file removal failed"
18366 }
18367 run_test 218 "parallel read and truncate should not deadlock"
18368
18369 test_219() {
18370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18371
18372         # write one partial page
18373         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18374         # set no grant so vvp_io_commit_write will do sync write
18375         $LCTL set_param fail_loc=0x411
18376         # write a full page at the end of file
18377         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18378
18379         $LCTL set_param fail_loc=0
18380         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18381         $LCTL set_param fail_loc=0x411
18382         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18383
18384         # LU-4201
18385         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18386         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18387 }
18388 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18389
18390 test_220() { #LU-325
18391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18392         remote_ost_nodsh && skip "remote OST with nodsh"
18393         remote_mds_nodsh && skip "remote MDS with nodsh"
18394         remote_mgs_nodsh && skip "remote MGS with nodsh"
18395
18396         local OSTIDX=0
18397
18398         # create on MDT0000 so the last_id and next_id are correct
18399         mkdir_on_mdt0 $DIR/$tdir
18400         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18401         OST=${OST%_UUID}
18402
18403         # on the mdt's osc
18404         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18405         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18406                         osp.$mdtosc_proc1.prealloc_last_id)
18407         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18408                         osp.$mdtosc_proc1.prealloc_next_id)
18409
18410         $LFS df -i
18411
18412         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18413         #define OBD_FAIL_OST_ENOINO              0x229
18414         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18415         create_pool $FSNAME.$TESTNAME || return 1
18416         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18417
18418         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18419
18420         MDSOBJS=$((last_id - next_id))
18421         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18422
18423         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18424         echo "OST still has $count kbytes free"
18425
18426         echo "create $MDSOBJS files @next_id..."
18427         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18428
18429         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18430                         osp.$mdtosc_proc1.prealloc_last_id)
18431         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18432                         osp.$mdtosc_proc1.prealloc_next_id)
18433
18434         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18435         $LFS df -i
18436
18437         echo "cleanup..."
18438
18439         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18440         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18441
18442         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18443                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18444         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18445                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18446         echo "unlink $MDSOBJS files @$next_id..."
18447         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18448 }
18449 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18450
18451 test_221() {
18452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18453
18454         dd if=`which date` of=$MOUNT/date oflag=sync
18455         chmod +x $MOUNT/date
18456
18457         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18458         $LCTL set_param fail_loc=0x80001401
18459
18460         $MOUNT/date > /dev/null
18461         rm -f $MOUNT/date
18462 }
18463 run_test 221 "make sure fault and truncate race to not cause OOM"
18464
18465 test_222a () {
18466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18467
18468         rm -rf $DIR/$tdir
18469         test_mkdir $DIR/$tdir
18470         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18471         createmany -o $DIR/$tdir/$tfile 10
18472         cancel_lru_locks mdc
18473         cancel_lru_locks osc
18474         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18475         $LCTL set_param fail_loc=0x31a
18476         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18477         $LCTL set_param fail_loc=0
18478         rm -r $DIR/$tdir
18479 }
18480 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18481
18482 test_222b () {
18483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18484
18485         rm -rf $DIR/$tdir
18486         test_mkdir $DIR/$tdir
18487         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18488         createmany -o $DIR/$tdir/$tfile 10
18489         cancel_lru_locks mdc
18490         cancel_lru_locks osc
18491         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18492         $LCTL set_param fail_loc=0x31a
18493         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18494         $LCTL set_param fail_loc=0
18495 }
18496 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18497
18498 test_223 () {
18499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18500
18501         rm -rf $DIR/$tdir
18502         test_mkdir $DIR/$tdir
18503         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18504         createmany -o $DIR/$tdir/$tfile 10
18505         cancel_lru_locks mdc
18506         cancel_lru_locks osc
18507         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18508         $LCTL set_param fail_loc=0x31b
18509         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18510         $LCTL set_param fail_loc=0
18511         rm -r $DIR/$tdir
18512 }
18513 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18514
18515 test_224a() { # LU-1039, MRP-303
18516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18517
18518         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18519         $LCTL set_param fail_loc=0x508
18520         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18521         $LCTL set_param fail_loc=0
18522         df $DIR
18523 }
18524 run_test 224a "Don't panic on bulk IO failure"
18525
18526 test_224b() { # LU-1039, MRP-303
18527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18528
18529         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18530         cancel_lru_locks osc
18531         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18532         $LCTL set_param fail_loc=0x515
18533         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18534         $LCTL set_param fail_loc=0
18535         df $DIR
18536 }
18537 run_test 224b "Don't panic on bulk IO failure"
18538
18539 test_224c() { # LU-6441
18540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18541         remote_mds_nodsh && skip "remote MDS with nodsh"
18542
18543         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18544         save_writethrough $p
18545         set_cache writethrough on
18546
18547         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18548         local at_max=$($LCTL get_param -n at_max)
18549         local timeout=$($LCTL get_param -n timeout)
18550         local test_at="at_max"
18551         local param_at="$FSNAME.sys.at_max"
18552         local test_timeout="timeout"
18553         local param_timeout="$FSNAME.sys.timeout"
18554
18555         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18556
18557         set_persistent_param_and_check client "$test_at" "$param_at" 0
18558         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18559
18560         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18561         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18562         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18563         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18564         sync
18565         do_facet ost1 "$LCTL set_param fail_loc=0"
18566
18567         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18568         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18569                 $timeout
18570
18571         $LCTL set_param -n $pages_per_rpc
18572         restore_lustre_params < $p
18573         rm -f $p
18574 }
18575 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18576
18577 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18578 test_225a () {
18579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18580         if [ -z ${MDSSURVEY} ]; then
18581                 skip_env "mds-survey not found"
18582         fi
18583         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18584                 skip "Need MDS version at least 2.2.51"
18585
18586         local mds=$(facet_host $SINGLEMDS)
18587         local target=$(do_nodes $mds 'lctl dl' |
18588                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18589
18590         local cmd1="file_count=1000 thrhi=4"
18591         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18592         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18593         local cmd="$cmd1 $cmd2 $cmd3"
18594
18595         rm -f ${TMP}/mds_survey*
18596         echo + $cmd
18597         eval $cmd || error "mds-survey with zero-stripe failed"
18598         cat ${TMP}/mds_survey*
18599         rm -f ${TMP}/mds_survey*
18600 }
18601 run_test 225a "Metadata survey sanity with zero-stripe"
18602
18603 test_225b () {
18604         if [ -z ${MDSSURVEY} ]; then
18605                 skip_env "mds-survey not found"
18606         fi
18607         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18608                 skip "Need MDS version at least 2.2.51"
18609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18610         remote_mds_nodsh && skip "remote MDS with nodsh"
18611         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18612                 skip_env "Need to mount OST to test"
18613         fi
18614
18615         local mds=$(facet_host $SINGLEMDS)
18616         local target=$(do_nodes $mds 'lctl dl' |
18617                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18618
18619         local cmd1="file_count=1000 thrhi=4"
18620         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18621         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18622         local cmd="$cmd1 $cmd2 $cmd3"
18623
18624         rm -f ${TMP}/mds_survey*
18625         echo + $cmd
18626         eval $cmd || error "mds-survey with stripe_count failed"
18627         cat ${TMP}/mds_survey*
18628         rm -f ${TMP}/mds_survey*
18629 }
18630 run_test 225b "Metadata survey sanity with stripe_count = 1"
18631
18632 mcreate_path2fid () {
18633         local mode=$1
18634         local major=$2
18635         local minor=$3
18636         local name=$4
18637         local desc=$5
18638         local path=$DIR/$tdir/$name
18639         local fid
18640         local rc
18641         local fid_path
18642
18643         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18644                 error "cannot create $desc"
18645
18646         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18647         rc=$?
18648         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18649
18650         fid_path=$($LFS fid2path $MOUNT $fid)
18651         rc=$?
18652         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18653
18654         [ "$path" == "$fid_path" ] ||
18655                 error "fid2path returned $fid_path, expected $path"
18656
18657         echo "pass with $path and $fid"
18658 }
18659
18660 test_226a () {
18661         rm -rf $DIR/$tdir
18662         mkdir -p $DIR/$tdir
18663
18664         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18665         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18666         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18667         mcreate_path2fid 0040666 0 0 dir "directory"
18668         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18669         mcreate_path2fid 0100666 0 0 file "regular file"
18670         mcreate_path2fid 0120666 0 0 link "symbolic link"
18671         mcreate_path2fid 0140666 0 0 sock "socket"
18672 }
18673 run_test 226a "call path2fid and fid2path on files of all type"
18674
18675 test_226b () {
18676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18677
18678         local MDTIDX=1
18679
18680         rm -rf $DIR/$tdir
18681         mkdir -p $DIR/$tdir
18682         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18683                 error "create remote directory failed"
18684         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18685         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18686                                 "character special file (null)"
18687         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18688                                 "character special file (no device)"
18689         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18690         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18691                                 "block special file (loop)"
18692         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18693         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18694         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18695 }
18696 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18697
18698 test_226c () {
18699         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18700         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18701                 skip "Need MDS version at least 2.13.55"
18702
18703         local submnt=/mnt/submnt
18704         local srcfile=/etc/passwd
18705         local dstfile=$submnt/passwd
18706         local path
18707         local fid
18708
18709         rm -rf $DIR/$tdir
18710         rm -rf $submnt
18711         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18712                 error "create remote directory failed"
18713         mkdir -p $submnt || error "create $submnt failed"
18714         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18715                 error "mount $submnt failed"
18716         stack_trap "umount $submnt" EXIT
18717
18718         cp $srcfile $dstfile
18719         fid=$($LFS path2fid $dstfile)
18720         path=$($LFS fid2path $submnt "$fid")
18721         [ "$path" = "$dstfile" ] ||
18722                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18723 }
18724 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18725
18726 # LU-1299 Executing or running ldd on a truncated executable does not
18727 # cause an out-of-memory condition.
18728 test_227() {
18729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18730         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18731
18732         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18733         chmod +x $MOUNT/date
18734
18735         $MOUNT/date > /dev/null
18736         ldd $MOUNT/date > /dev/null
18737         rm -f $MOUNT/date
18738 }
18739 run_test 227 "running truncated executable does not cause OOM"
18740
18741 # LU-1512 try to reuse idle OI blocks
18742 test_228a() {
18743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18744         remote_mds_nodsh && skip "remote MDS with nodsh"
18745         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18746
18747         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18748         local myDIR=$DIR/$tdir
18749
18750         mkdir -p $myDIR
18751         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18752         $LCTL set_param fail_loc=0x80001002
18753         createmany -o $myDIR/t- 10000
18754         $LCTL set_param fail_loc=0
18755         # The guard is current the largest FID holder
18756         touch $myDIR/guard
18757         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18758                     tr -d '[')
18759         local IDX=$(($SEQ % 64))
18760
18761         do_facet $SINGLEMDS sync
18762         # Make sure journal flushed.
18763         sleep 6
18764         local blk1=$(do_facet $SINGLEMDS \
18765                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18766                      grep Blockcount | awk '{print $4}')
18767
18768         # Remove old files, some OI blocks will become idle.
18769         unlinkmany $myDIR/t- 10000
18770         # Create new files, idle OI blocks should be reused.
18771         createmany -o $myDIR/t- 2000
18772         do_facet $SINGLEMDS sync
18773         # Make sure journal flushed.
18774         sleep 6
18775         local blk2=$(do_facet $SINGLEMDS \
18776                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18777                      grep Blockcount | awk '{print $4}')
18778
18779         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18780 }
18781 run_test 228a "try to reuse idle OI blocks"
18782
18783 test_228b() {
18784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18785         remote_mds_nodsh && skip "remote MDS with nodsh"
18786         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18787
18788         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18789         local myDIR=$DIR/$tdir
18790
18791         mkdir -p $myDIR
18792         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18793         $LCTL set_param fail_loc=0x80001002
18794         createmany -o $myDIR/t- 10000
18795         $LCTL set_param fail_loc=0
18796         # The guard is current the largest FID holder
18797         touch $myDIR/guard
18798         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18799                     tr -d '[')
18800         local IDX=$(($SEQ % 64))
18801
18802         do_facet $SINGLEMDS sync
18803         # Make sure journal flushed.
18804         sleep 6
18805         local blk1=$(do_facet $SINGLEMDS \
18806                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18807                      grep Blockcount | awk '{print $4}')
18808
18809         # Remove old files, some OI blocks will become idle.
18810         unlinkmany $myDIR/t- 10000
18811
18812         # stop the MDT
18813         stop $SINGLEMDS || error "Fail to stop MDT."
18814         # remount the MDT
18815         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18816
18817         df $MOUNT || error "Fail to df."
18818         # Create new files, idle OI blocks should be reused.
18819         createmany -o $myDIR/t- 2000
18820         do_facet $SINGLEMDS sync
18821         # Make sure journal flushed.
18822         sleep 6
18823         local blk2=$(do_facet $SINGLEMDS \
18824                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18825                      grep Blockcount | awk '{print $4}')
18826
18827         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18828 }
18829 run_test 228b "idle OI blocks can be reused after MDT restart"
18830
18831 #LU-1881
18832 test_228c() {
18833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18834         remote_mds_nodsh && skip "remote MDS with nodsh"
18835         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18836
18837         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18838         local myDIR=$DIR/$tdir
18839
18840         mkdir -p $myDIR
18841         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18842         $LCTL set_param fail_loc=0x80001002
18843         # 20000 files can guarantee there are index nodes in the OI file
18844         createmany -o $myDIR/t- 20000
18845         $LCTL set_param fail_loc=0
18846         # The guard is current the largest FID holder
18847         touch $myDIR/guard
18848         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18849                     tr -d '[')
18850         local IDX=$(($SEQ % 64))
18851
18852         do_facet $SINGLEMDS sync
18853         # Make sure journal flushed.
18854         sleep 6
18855         local blk1=$(do_facet $SINGLEMDS \
18856                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18857                      grep Blockcount | awk '{print $4}')
18858
18859         # Remove old files, some OI blocks will become idle.
18860         unlinkmany $myDIR/t- 20000
18861         rm -f $myDIR/guard
18862         # The OI file should become empty now
18863
18864         # Create new files, idle OI blocks should be reused.
18865         createmany -o $myDIR/t- 2000
18866         do_facet $SINGLEMDS sync
18867         # Make sure journal flushed.
18868         sleep 6
18869         local blk2=$(do_facet $SINGLEMDS \
18870                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18871                      grep Blockcount | awk '{print $4}')
18872
18873         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18874 }
18875 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18876
18877 test_229() { # LU-2482, LU-3448
18878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18879         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18880         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18881                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18882
18883         rm -f $DIR/$tfile
18884
18885         # Create a file with a released layout and stripe count 2.
18886         $MULTIOP $DIR/$tfile H2c ||
18887                 error "failed to create file with released layout"
18888
18889         $LFS getstripe -v $DIR/$tfile
18890
18891         local pattern=$($LFS getstripe -L $DIR/$tfile)
18892         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18893
18894         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18895                 error "getstripe"
18896         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18897         stat $DIR/$tfile || error "failed to stat released file"
18898
18899         chown $RUNAS_ID $DIR/$tfile ||
18900                 error "chown $RUNAS_ID $DIR/$tfile failed"
18901
18902         chgrp $RUNAS_ID $DIR/$tfile ||
18903                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18904
18905         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18906         rm $DIR/$tfile || error "failed to remove released file"
18907 }
18908 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18909
18910 test_230a() {
18911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18913         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18914                 skip "Need MDS version at least 2.11.52"
18915
18916         local MDTIDX=1
18917
18918         test_mkdir $DIR/$tdir
18919         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18920         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18921         [ $mdt_idx -ne 0 ] &&
18922                 error "create local directory on wrong MDT $mdt_idx"
18923
18924         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18925                         error "create remote directory failed"
18926         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18927         [ $mdt_idx -ne $MDTIDX ] &&
18928                 error "create remote directory on wrong MDT $mdt_idx"
18929
18930         createmany -o $DIR/$tdir/test_230/t- 10 ||
18931                 error "create files on remote directory failed"
18932         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18933         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18934         rm -r $DIR/$tdir || error "unlink remote directory failed"
18935 }
18936 run_test 230a "Create remote directory and files under the remote directory"
18937
18938 test_230b() {
18939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18940         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18941         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18942                 skip "Need MDS version at least 2.11.52"
18943
18944         local MDTIDX=1
18945         local mdt_index
18946         local i
18947         local file
18948         local pid
18949         local stripe_count
18950         local migrate_dir=$DIR/$tdir/migrate_dir
18951         local other_dir=$DIR/$tdir/other_dir
18952
18953         test_mkdir $DIR/$tdir
18954         test_mkdir -i0 -c1 $migrate_dir
18955         test_mkdir -i0 -c1 $other_dir
18956         for ((i=0; i<10; i++)); do
18957                 mkdir -p $migrate_dir/dir_${i}
18958                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18959                         error "create files under remote dir failed $i"
18960         done
18961
18962         cp /etc/passwd $migrate_dir/$tfile
18963         cp /etc/passwd $other_dir/$tfile
18964         chattr +SAD $migrate_dir
18965         chattr +SAD $migrate_dir/$tfile
18966
18967         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18968         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18969         local old_dir_mode=$(stat -c%f $migrate_dir)
18970         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18971
18972         mkdir -p $migrate_dir/dir_default_stripe2
18973         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18974         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18975
18976         mkdir -p $other_dir
18977         ln $migrate_dir/$tfile $other_dir/luna
18978         ln $migrate_dir/$tfile $migrate_dir/sofia
18979         ln $other_dir/$tfile $migrate_dir/david
18980         ln -s $migrate_dir/$tfile $other_dir/zachary
18981         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18982         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18983
18984         local len
18985         local lnktgt
18986
18987         # inline symlink
18988         for len in 58 59 60; do
18989                 lnktgt=$(str_repeat 'l' $len)
18990                 touch $migrate_dir/$lnktgt
18991                 ln -s $lnktgt $migrate_dir/${len}char_ln
18992         done
18993
18994         # PATH_MAX
18995         for len in 4094 4095; do
18996                 lnktgt=$(str_repeat 'l' $len)
18997                 ln -s $lnktgt $migrate_dir/${len}char_ln
18998         done
18999
19000         # NAME_MAX
19001         for len in 254 255; do
19002                 touch $migrate_dir/$(str_repeat 'l' $len)
19003         done
19004
19005         $LFS migrate -m $MDTIDX $migrate_dir ||
19006                 error "fails on migrating remote dir to MDT1"
19007
19008         echo "migratate to MDT1, then checking.."
19009         for ((i = 0; i < 10; i++)); do
19010                 for file in $(find $migrate_dir/dir_${i}); do
19011                         mdt_index=$($LFS getstripe -m $file)
19012                         # broken symlink getstripe will fail
19013                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19014                                 error "$file is not on MDT${MDTIDX}"
19015                 done
19016         done
19017
19018         # the multiple link file should still in MDT0
19019         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19020         [ $mdt_index == 0 ] ||
19021                 error "$file is not on MDT${MDTIDX}"
19022
19023         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19024         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19025                 error " expect $old_dir_flag get $new_dir_flag"
19026
19027         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19028         [ "$old_file_flag" = "$new_file_flag" ] ||
19029                 error " expect $old_file_flag get $new_file_flag"
19030
19031         local new_dir_mode=$(stat -c%f $migrate_dir)
19032         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19033                 error "expect mode $old_dir_mode get $new_dir_mode"
19034
19035         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19036         [ "$old_file_mode" = "$new_file_mode" ] ||
19037                 error "expect mode $old_file_mode get $new_file_mode"
19038
19039         diff /etc/passwd $migrate_dir/$tfile ||
19040                 error "$tfile different after migration"
19041
19042         diff /etc/passwd $other_dir/luna ||
19043                 error "luna different after migration"
19044
19045         diff /etc/passwd $migrate_dir/sofia ||
19046                 error "sofia different after migration"
19047
19048         diff /etc/passwd $migrate_dir/david ||
19049                 error "david different after migration"
19050
19051         diff /etc/passwd $other_dir/zachary ||
19052                 error "zachary different after migration"
19053
19054         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19055                 error "${tfile}_ln different after migration"
19056
19057         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19058                 error "${tfile}_ln_other different after migration"
19059
19060         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19061         [ $stripe_count = 2 ] ||
19062                 error "dir strpe_count $d != 2 after migration."
19063
19064         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19065         [ $stripe_count = 2 ] ||
19066                 error "file strpe_count $d != 2 after migration."
19067
19068         #migrate back to MDT0
19069         MDTIDX=0
19070
19071         $LFS migrate -m $MDTIDX $migrate_dir ||
19072                 error "fails on migrating remote dir to MDT0"
19073
19074         echo "migrate back to MDT0, checking.."
19075         for file in $(find $migrate_dir); do
19076                 mdt_index=$($LFS getstripe -m $file)
19077                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19078                         error "$file is not on MDT${MDTIDX}"
19079         done
19080
19081         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19082         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19083                 error " expect $old_dir_flag get $new_dir_flag"
19084
19085         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19086         [ "$old_file_flag" = "$new_file_flag" ] ||
19087                 error " expect $old_file_flag get $new_file_flag"
19088
19089         local new_dir_mode=$(stat -c%f $migrate_dir)
19090         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19091                 error "expect mode $old_dir_mode get $new_dir_mode"
19092
19093         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19094         [ "$old_file_mode" = "$new_file_mode" ] ||
19095                 error "expect mode $old_file_mode get $new_file_mode"
19096
19097         diff /etc/passwd ${migrate_dir}/$tfile ||
19098                 error "$tfile different after migration"
19099
19100         diff /etc/passwd ${other_dir}/luna ||
19101                 error "luna different after migration"
19102
19103         diff /etc/passwd ${migrate_dir}/sofia ||
19104                 error "sofia different after migration"
19105
19106         diff /etc/passwd ${other_dir}/zachary ||
19107                 error "zachary different after migration"
19108
19109         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19110                 error "${tfile}_ln different after migration"
19111
19112         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19113                 error "${tfile}_ln_other different after migration"
19114
19115         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19116         [ $stripe_count = 2 ] ||
19117                 error "dir strpe_count $d != 2 after migration."
19118
19119         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19120         [ $stripe_count = 2 ] ||
19121                 error "file strpe_count $d != 2 after migration."
19122
19123         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19124 }
19125 run_test 230b "migrate directory"
19126
19127 test_230c() {
19128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19129         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19130         remote_mds_nodsh && skip "remote MDS with nodsh"
19131         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19132                 skip "Need MDS version at least 2.11.52"
19133
19134         local MDTIDX=1
19135         local total=3
19136         local mdt_index
19137         local file
19138         local migrate_dir=$DIR/$tdir/migrate_dir
19139
19140         #If migrating directory fails in the middle, all entries of
19141         #the directory is still accessiable.
19142         test_mkdir $DIR/$tdir
19143         test_mkdir -i0 -c1 $migrate_dir
19144         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19145         stat $migrate_dir
19146         createmany -o $migrate_dir/f $total ||
19147                 error "create files under ${migrate_dir} failed"
19148
19149         # fail after migrating top dir, and this will fail only once, so the
19150         # first sub file migration will fail (currently f3), others succeed.
19151         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19152         do_facet mds1 lctl set_param fail_loc=0x1801
19153         local t=$(ls $migrate_dir | wc -l)
19154         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19155                 error "migrate should fail"
19156         local u=$(ls $migrate_dir | wc -l)
19157         [ "$u" == "$t" ] || error "$u != $t during migration"
19158
19159         # add new dir/file should succeed
19160         mkdir $migrate_dir/dir ||
19161                 error "mkdir failed under migrating directory"
19162         touch $migrate_dir/file ||
19163                 error "create file failed under migrating directory"
19164
19165         # add file with existing name should fail
19166         for file in $migrate_dir/f*; do
19167                 stat $file > /dev/null || error "stat $file failed"
19168                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19169                         error "open(O_CREAT|O_EXCL) $file should fail"
19170                 $MULTIOP $file m && error "create $file should fail"
19171                 touch $DIR/$tdir/remote_dir/$tfile ||
19172                         error "touch $tfile failed"
19173                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19174                         error "link $file should fail"
19175                 mdt_index=$($LFS getstripe -m $file)
19176                 if [ $mdt_index == 0 ]; then
19177                         # file failed to migrate is not allowed to rename to
19178                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19179                                 error "rename to $file should fail"
19180                 else
19181                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19182                                 error "rename to $file failed"
19183                 fi
19184                 echo hello >> $file || error "write $file failed"
19185         done
19186
19187         # resume migration with different options should fail
19188         $LFS migrate -m 0 $migrate_dir &&
19189                 error "migrate -m 0 $migrate_dir should fail"
19190
19191         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19192                 error "migrate -c 2 $migrate_dir should fail"
19193
19194         # resume migration should succeed
19195         $LFS migrate -m $MDTIDX $migrate_dir ||
19196                 error "migrate $migrate_dir failed"
19197
19198         echo "Finish migration, then checking.."
19199         for file in $(find $migrate_dir); do
19200                 mdt_index=$($LFS getstripe -m $file)
19201                 [ $mdt_index == $MDTIDX ] ||
19202                         error "$file is not on MDT${MDTIDX}"
19203         done
19204
19205         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19206 }
19207 run_test 230c "check directory accessiblity if migration failed"
19208
19209 test_230d() {
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19212         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19213                 skip "Need MDS version at least 2.11.52"
19214         # LU-11235
19215         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19216
19217         local migrate_dir=$DIR/$tdir/migrate_dir
19218         local old_index
19219         local new_index
19220         local old_count
19221         local new_count
19222         local new_hash
19223         local mdt_index
19224         local i
19225         local j
19226
19227         old_index=$((RANDOM % MDSCOUNT))
19228         old_count=$((MDSCOUNT - old_index))
19229         new_index=$((RANDOM % MDSCOUNT))
19230         new_count=$((MDSCOUNT - new_index))
19231         new_hash=1 # for all_char
19232
19233         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19234         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19235
19236         test_mkdir $DIR/$tdir
19237         test_mkdir -i $old_index -c $old_count $migrate_dir
19238
19239         for ((i=0; i<100; i++)); do
19240                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19241                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19242                         error "create files under remote dir failed $i"
19243         done
19244
19245         echo -n "Migrate from MDT$old_index "
19246         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19247         echo -n "to MDT$new_index"
19248         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19249         echo
19250
19251         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19252         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19253                 error "migrate remote dir error"
19254
19255         echo "Finish migration, then checking.."
19256         for file in $(find $migrate_dir); do
19257                 mdt_index=$($LFS getstripe -m $file)
19258                 if [ $mdt_index -lt $new_index ] ||
19259                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19260                         error "$file is on MDT$mdt_index"
19261                 fi
19262         done
19263
19264         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19265 }
19266 run_test 230d "check migrate big directory"
19267
19268 test_230e() {
19269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19270         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19271         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19272                 skip "Need MDS version at least 2.11.52"
19273
19274         local i
19275         local j
19276         local a_fid
19277         local b_fid
19278
19279         mkdir_on_mdt0 $DIR/$tdir
19280         mkdir $DIR/$tdir/migrate_dir
19281         mkdir $DIR/$tdir/other_dir
19282         touch $DIR/$tdir/migrate_dir/a
19283         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19284         ls $DIR/$tdir/other_dir
19285
19286         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19287                 error "migrate dir fails"
19288
19289         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19290         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19291
19292         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19293         [ $mdt_index == 0 ] || error "a is not on MDT0"
19294
19295         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19296                 error "migrate dir fails"
19297
19298         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19299         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19300
19301         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19302         [ $mdt_index == 1 ] || error "a is not on MDT1"
19303
19304         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19305         [ $mdt_index == 1 ] || error "b is not on MDT1"
19306
19307         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19308         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19309
19310         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19311
19312         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19313 }
19314 run_test 230e "migrate mulitple local link files"
19315
19316 test_230f() {
19317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19319         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19320                 skip "Need MDS version at least 2.11.52"
19321
19322         local a_fid
19323         local ln_fid
19324
19325         mkdir -p $DIR/$tdir
19326         mkdir $DIR/$tdir/migrate_dir
19327         $LFS mkdir -i1 $DIR/$tdir/other_dir
19328         touch $DIR/$tdir/migrate_dir/a
19329         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19330         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19331         ls $DIR/$tdir/other_dir
19332
19333         # a should be migrated to MDT1, since no other links on MDT0
19334         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19335                 error "#1 migrate dir fails"
19336         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19337         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19338         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19339         [ $mdt_index == 1 ] || error "a is not on MDT1"
19340
19341         # a should stay on MDT1, because it is a mulitple link file
19342         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19343                 error "#2 migrate dir fails"
19344         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19345         [ $mdt_index == 1 ] || error "a is not on MDT1"
19346
19347         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19348                 error "#3 migrate dir fails"
19349
19350         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19351         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19352         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19353
19354         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19355         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19356
19357         # a should be migrated to MDT0, since no other links on MDT1
19358         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19359                 error "#4 migrate dir fails"
19360         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19361         [ $mdt_index == 0 ] || error "a is not on MDT0"
19362
19363         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19364 }
19365 run_test 230f "migrate mulitple remote link files"
19366
19367 test_230g() {
19368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19370         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19371                 skip "Need MDS version at least 2.11.52"
19372
19373         mkdir -p $DIR/$tdir/migrate_dir
19374
19375         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19376                 error "migrating dir to non-exist MDT succeeds"
19377         true
19378 }
19379 run_test 230g "migrate dir to non-exist MDT"
19380
19381 test_230h() {
19382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19384         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19385                 skip "Need MDS version at least 2.11.52"
19386
19387         local mdt_index
19388
19389         mkdir -p $DIR/$tdir/migrate_dir
19390
19391         $LFS migrate -m1 $DIR &&
19392                 error "migrating mountpoint1 should fail"
19393
19394         $LFS migrate -m1 $DIR/$tdir/.. &&
19395                 error "migrating mountpoint2 should fail"
19396
19397         # same as mv
19398         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19399                 error "migrating $tdir/migrate_dir/.. should fail"
19400
19401         true
19402 }
19403 run_test 230h "migrate .. and root"
19404
19405 test_230i() {
19406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19408         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19409                 skip "Need MDS version at least 2.11.52"
19410
19411         mkdir -p $DIR/$tdir/migrate_dir
19412
19413         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19414                 error "migration fails with a tailing slash"
19415
19416         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19417                 error "migration fails with two tailing slashes"
19418 }
19419 run_test 230i "lfs migrate -m tolerates trailing slashes"
19420
19421 test_230j() {
19422         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19423         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19424                 skip "Need MDS version at least 2.11.52"
19425
19426         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19427         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19428                 error "create $tfile failed"
19429         cat /etc/passwd > $DIR/$tdir/$tfile
19430
19431         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19432
19433         cmp /etc/passwd $DIR/$tdir/$tfile ||
19434                 error "DoM file mismatch after migration"
19435 }
19436 run_test 230j "DoM file data not changed after dir migration"
19437
19438 test_230k() {
19439         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19440         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19441                 skip "Need MDS version at least 2.11.56"
19442
19443         local total=20
19444         local files_on_starting_mdt=0
19445
19446         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19447         $LFS getdirstripe $DIR/$tdir
19448         for i in $(seq $total); do
19449                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19450                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19451                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19452         done
19453
19454         echo "$files_on_starting_mdt files on MDT0"
19455
19456         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19457         $LFS getdirstripe $DIR/$tdir
19458
19459         files_on_starting_mdt=0
19460         for i in $(seq $total); do
19461                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19462                         error "file $tfile.$i mismatch after migration"
19463                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19464                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19465         done
19466
19467         echo "$files_on_starting_mdt files on MDT1 after migration"
19468         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19469
19470         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19471         $LFS getdirstripe $DIR/$tdir
19472
19473         files_on_starting_mdt=0
19474         for i in $(seq $total); do
19475                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19476                         error "file $tfile.$i mismatch after 2nd migration"
19477                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19478                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19479         done
19480
19481         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19482         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19483
19484         true
19485 }
19486 run_test 230k "file data not changed after dir migration"
19487
19488 test_230l() {
19489         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19490         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19491                 skip "Need MDS version at least 2.11.56"
19492
19493         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19494         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19495                 error "create files under remote dir failed $i"
19496         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19497 }
19498 run_test 230l "readdir between MDTs won't crash"
19499
19500 test_230m() {
19501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19502         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19503                 skip "Need MDS version at least 2.11.56"
19504
19505         local MDTIDX=1
19506         local mig_dir=$DIR/$tdir/migrate_dir
19507         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19508         local shortstr="b"
19509         local val
19510
19511         echo "Creating files and dirs with xattrs"
19512         test_mkdir $DIR/$tdir
19513         test_mkdir -i0 -c1 $mig_dir
19514         mkdir $mig_dir/dir
19515         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19516                 error "cannot set xattr attr1 on dir"
19517         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19518                 error "cannot set xattr attr2 on dir"
19519         touch $mig_dir/dir/f0
19520         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19521                 error "cannot set xattr attr1 on file"
19522         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19523                 error "cannot set xattr attr2 on file"
19524         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19525         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19526         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19527         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19528         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19529         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19530         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19531         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19532         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19533
19534         echo "Migrating to MDT1"
19535         $LFS migrate -m $MDTIDX $mig_dir ||
19536                 error "fails on migrating dir to MDT1"
19537
19538         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19539         echo "Checking xattrs"
19540         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19541         [ "$val" = $longstr ] ||
19542                 error "expecting xattr1 $longstr on dir, found $val"
19543         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19544         [ "$val" = $shortstr ] ||
19545                 error "expecting xattr2 $shortstr on dir, found $val"
19546         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19547         [ "$val" = $longstr ] ||
19548                 error "expecting xattr1 $longstr on file, found $val"
19549         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19550         [ "$val" = $shortstr ] ||
19551                 error "expecting xattr2 $shortstr on file, found $val"
19552 }
19553 run_test 230m "xattrs not changed after dir migration"
19554
19555 test_230n() {
19556         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19557         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19558                 skip "Need MDS version at least 2.13.53"
19559
19560         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19561         cat /etc/hosts > $DIR/$tdir/$tfile
19562         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19563         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19564
19565         cmp /etc/hosts $DIR/$tdir/$tfile ||
19566                 error "File data mismatch after migration"
19567 }
19568 run_test 230n "Dir migration with mirrored file"
19569
19570 test_230o() {
19571         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19572         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19573                 skip "Need MDS version at least 2.13.52"
19574
19575         local mdts=$(comma_list $(mdts_nodes))
19576         local timeout=100
19577         local restripe_status
19578         local delta
19579         local i
19580
19581         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19582
19583         # in case "crush" hash type is not set
19584         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19585
19586         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19587                            mdt.*MDT0000.enable_dir_restripe)
19588         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19589         stack_trap "do_nodes $mdts $LCTL set_param \
19590                     mdt.*.enable_dir_restripe=$restripe_status"
19591
19592         mkdir $DIR/$tdir
19593         createmany -m $DIR/$tdir/f 100 ||
19594                 error "create files under remote dir failed $i"
19595         createmany -d $DIR/$tdir/d 100 ||
19596                 error "create dirs under remote dir failed $i"
19597
19598         for i in $(seq 2 $MDSCOUNT); do
19599                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19600                 $LFS setdirstripe -c $i $DIR/$tdir ||
19601                         error "split -c $i $tdir failed"
19602                 wait_update $HOSTNAME \
19603                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19604                         error "dir split not finished"
19605                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19606                         awk '/migrate/ {sum += $2} END { print sum }')
19607                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19608                 # delta is around total_files/stripe_count
19609                 (( $delta < 200 / (i - 1) + 4 )) ||
19610                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19611         done
19612 }
19613 run_test 230o "dir split"
19614
19615 test_230p() {
19616         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19617         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19618                 skip "Need MDS version at least 2.13.52"
19619
19620         local mdts=$(comma_list $(mdts_nodes))
19621         local timeout=100
19622         local restripe_status
19623         local delta
19624         local i
19625
19626         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19627
19628         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19629
19630         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19631                            mdt.*MDT0000.enable_dir_restripe)
19632         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19633         stack_trap "do_nodes $mdts $LCTL set_param \
19634                     mdt.*.enable_dir_restripe=$restripe_status"
19635
19636         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19637         createmany -m $DIR/$tdir/f 100 ||
19638                 error "create files under remote dir failed $i"
19639         createmany -d $DIR/$tdir/d 100 ||
19640                 error "create dirs under remote dir failed $i"
19641
19642         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19643                 local mdt_hash="crush"
19644
19645                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19646                 $LFS setdirstripe -c $i $DIR/$tdir ||
19647                         error "split -c $i $tdir failed"
19648                 [ $i -eq 1 ] && mdt_hash="none"
19649                 wait_update $HOSTNAME \
19650                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19651                         error "dir merge not finished"
19652                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19653                         awk '/migrate/ {sum += $2} END { print sum }')
19654                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19655                 # delta is around total_files/stripe_count
19656                 (( $delta < 200 / i + 4 )) ||
19657                         error "$delta files migrated >= $((200 / i + 4))"
19658         done
19659 }
19660 run_test 230p "dir merge"
19661
19662 test_230q() {
19663         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19664         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19665                 skip "Need MDS version at least 2.13.52"
19666
19667         local mdts=$(comma_list $(mdts_nodes))
19668         local saved_threshold=$(do_facet mds1 \
19669                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19670         local saved_delta=$(do_facet mds1 \
19671                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19672         local threshold=100
19673         local delta=2
19674         local total=0
19675         local stripe_count=0
19676         local stripe_index
19677         local nr_files
19678         local create
19679
19680         # test with fewer files on ZFS
19681         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19682
19683         stack_trap "do_nodes $mdts $LCTL set_param \
19684                     mdt.*.dir_split_count=$saved_threshold"
19685         stack_trap "do_nodes $mdts $LCTL set_param \
19686                     mdt.*.dir_split_delta=$saved_delta"
19687         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19688         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19689         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19690         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19691         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19692         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19693
19694         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19695         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19696
19697         create=$((threshold * 3 / 2))
19698         while [ $stripe_count -lt $MDSCOUNT ]; do
19699                 createmany -m $DIR/$tdir/f $total $create ||
19700                         error "create sub files failed"
19701                 stat $DIR/$tdir > /dev/null
19702                 total=$((total + create))
19703                 stripe_count=$((stripe_count + delta))
19704                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19705
19706                 wait_update $HOSTNAME \
19707                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19708                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19709
19710                 wait_update $HOSTNAME \
19711                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19712                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19713
19714                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19715                 echo "$nr_files/$total files on MDT$stripe_index after split"
19716                 # allow 10% margin of imbalance with crush hash
19717                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19718                         error "$nr_files files on MDT$stripe_index after split"
19719
19720                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19721                 [ $nr_files -eq $total ] ||
19722                         error "total sub files $nr_files != $total"
19723         done
19724 }
19725 run_test 230q "dir auto split"
19726
19727 test_230r() {
19728         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19729         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19730         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19731                 skip "Need MDS version at least 2.13.54"
19732
19733         # maximum amount of local locks:
19734         # parent striped dir - 2 locks
19735         # new stripe in parent to migrate to - 1 lock
19736         # source and target - 2 locks
19737         # Total 5 locks for regular file
19738         mkdir -p $DIR/$tdir
19739         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19740         touch $DIR/$tdir/dir1/eee
19741
19742         # create 4 hardlink for 4 more locks
19743         # Total: 9 locks > RS_MAX_LOCKS (8)
19744         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19745         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19746         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19747         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19748         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19749         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19750         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19751         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19752
19753         cancel_lru_locks mdc
19754
19755         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19756                 error "migrate dir fails"
19757
19758         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19759 }
19760 run_test 230r "migrate with too many local locks"
19761
19762 test_230s() {
19763         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19764                 skip "Need MDS version at least 2.13.57"
19765
19766         local mdts=$(comma_list $(mdts_nodes))
19767         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19768                                 mdt.*MDT0000.enable_dir_restripe)
19769
19770         stack_trap "do_nodes $mdts $LCTL set_param \
19771                     mdt.*.enable_dir_restripe=$restripe_status"
19772
19773         local st
19774         for st in 0 1; do
19775                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19776                 test_mkdir $DIR/$tdir
19777                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19778                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19779                 rmdir $DIR/$tdir
19780         done
19781 }
19782 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19783
19784 test_230t()
19785 {
19786         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19787         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19788                 skip "Need MDS version at least 2.14.50"
19789
19790         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19791         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19792         $LFS project -p 1 -s $DIR/$tdir ||
19793                 error "set $tdir project id failed"
19794         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19795                 error "set subdir project id failed"
19796         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19797 }
19798 run_test 230t "migrate directory with project ID set"
19799
19800 test_231a()
19801 {
19802         # For simplicity this test assumes that max_pages_per_rpc
19803         # is the same across all OSCs
19804         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19805         local bulk_size=$((max_pages * PAGE_SIZE))
19806         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19807                                        head -n 1)
19808
19809         mkdir -p $DIR/$tdir
19810         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19811                 error "failed to set stripe with -S ${brw_size}M option"
19812
19813         # clear the OSC stats
19814         $LCTL set_param osc.*.stats=0 &>/dev/null
19815         stop_writeback
19816
19817         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19818         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19819                 oflag=direct &>/dev/null || error "dd failed"
19820
19821         sync; sleep 1; sync # just to be safe
19822         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19823         if [ x$nrpcs != "x1" ]; then
19824                 $LCTL get_param osc.*.stats
19825                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19826         fi
19827
19828         start_writeback
19829         # Drop the OSC cache, otherwise we will read from it
19830         cancel_lru_locks osc
19831
19832         # clear the OSC stats
19833         $LCTL set_param osc.*.stats=0 &>/dev/null
19834
19835         # Client reads $bulk_size.
19836         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19837                 iflag=direct &>/dev/null || error "dd failed"
19838
19839         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19840         if [ x$nrpcs != "x1" ]; then
19841                 $LCTL get_param osc.*.stats
19842                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19843         fi
19844 }
19845 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19846
19847 test_231b() {
19848         mkdir -p $DIR/$tdir
19849         local i
19850         for i in {0..1023}; do
19851                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19852                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19853                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19854         done
19855         sync
19856 }
19857 run_test 231b "must not assert on fully utilized OST request buffer"
19858
19859 test_232a() {
19860         mkdir -p $DIR/$tdir
19861         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19862
19863         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19864         do_facet ost1 $LCTL set_param fail_loc=0x31c
19865
19866         # ignore dd failure
19867         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19868
19869         do_facet ost1 $LCTL set_param fail_loc=0
19870         umount_client $MOUNT || error "umount failed"
19871         mount_client $MOUNT || error "mount failed"
19872         stop ost1 || error "cannot stop ost1"
19873         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19874 }
19875 run_test 232a "failed lock should not block umount"
19876
19877 test_232b() {
19878         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19879                 skip "Need MDS version at least 2.10.58"
19880
19881         mkdir -p $DIR/$tdir
19882         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19883         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19884         sync
19885         cancel_lru_locks osc
19886
19887         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19888         do_facet ost1 $LCTL set_param fail_loc=0x31c
19889
19890         # ignore failure
19891         $LFS data_version $DIR/$tdir/$tfile || true
19892
19893         do_facet ost1 $LCTL set_param fail_loc=0
19894         umount_client $MOUNT || error "umount failed"
19895         mount_client $MOUNT || error "mount failed"
19896         stop ost1 || error "cannot stop ost1"
19897         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19898 }
19899 run_test 232b "failed data version lock should not block umount"
19900
19901 test_233a() {
19902         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19903                 skip "Need MDS version at least 2.3.64"
19904         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19905
19906         local fid=$($LFS path2fid $MOUNT)
19907
19908         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19909                 error "cannot access $MOUNT using its FID '$fid'"
19910 }
19911 run_test 233a "checking that OBF of the FS root succeeds"
19912
19913 test_233b() {
19914         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19915                 skip "Need MDS version at least 2.5.90"
19916         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19917
19918         local fid=$($LFS path2fid $MOUNT/.lustre)
19919
19920         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19921                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19922
19923         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19924         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19925                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19926 }
19927 run_test 233b "checking that OBF of the FS .lustre succeeds"
19928
19929 test_234() {
19930         local p="$TMP/sanityN-$TESTNAME.parameters"
19931         save_lustre_params client "llite.*.xattr_cache" > $p
19932         lctl set_param llite.*.xattr_cache 1 ||
19933                 skip_env "xattr cache is not supported"
19934
19935         mkdir -p $DIR/$tdir || error "mkdir failed"
19936         touch $DIR/$tdir/$tfile || error "touch failed"
19937         # OBD_FAIL_LLITE_XATTR_ENOMEM
19938         $LCTL set_param fail_loc=0x1405
19939         getfattr -n user.attr $DIR/$tdir/$tfile &&
19940                 error "getfattr should have failed with ENOMEM"
19941         $LCTL set_param fail_loc=0x0
19942         rm -rf $DIR/$tdir
19943
19944         restore_lustre_params < $p
19945         rm -f $p
19946 }
19947 run_test 234 "xattr cache should not crash on ENOMEM"
19948
19949 test_235() {
19950         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19951                 skip "Need MDS version at least 2.4.52"
19952
19953         flock_deadlock $DIR/$tfile
19954         local RC=$?
19955         case $RC in
19956                 0)
19957                 ;;
19958                 124) error "process hangs on a deadlock"
19959                 ;;
19960                 *) error "error executing flock_deadlock $DIR/$tfile"
19961                 ;;
19962         esac
19963 }
19964 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19965
19966 #LU-2935
19967 test_236() {
19968         check_swap_layouts_support
19969
19970         local ref1=/etc/passwd
19971         local ref2=/etc/group
19972         local file1=$DIR/$tdir/f1
19973         local file2=$DIR/$tdir/f2
19974
19975         test_mkdir -c1 $DIR/$tdir
19976         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19977         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19978         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19979         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19980         local fd=$(free_fd)
19981         local cmd="exec $fd<>$file2"
19982         eval $cmd
19983         rm $file2
19984         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19985                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19986         cmd="exec $fd>&-"
19987         eval $cmd
19988         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19989
19990         #cleanup
19991         rm -rf $DIR/$tdir
19992 }
19993 run_test 236 "Layout swap on open unlinked file"
19994
19995 # LU-4659 linkea consistency
19996 test_238() {
19997         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19998                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19999                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20000                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20001
20002         touch $DIR/$tfile
20003         ln $DIR/$tfile $DIR/$tfile.lnk
20004         touch $DIR/$tfile.new
20005         mv $DIR/$tfile.new $DIR/$tfile
20006         local fid1=$($LFS path2fid $DIR/$tfile)
20007         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20008         local path1=$($LFS fid2path $FSNAME "$fid1")
20009         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20010         local path2=$($LFS fid2path $FSNAME "$fid2")
20011         [ $tfile.lnk == $path2 ] ||
20012                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20013         rm -f $DIR/$tfile*
20014 }
20015 run_test 238 "Verify linkea consistency"
20016
20017 test_239A() { # was test_239
20018         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20019                 skip "Need MDS version at least 2.5.60"
20020
20021         local list=$(comma_list $(mdts_nodes))
20022
20023         mkdir -p $DIR/$tdir
20024         createmany -o $DIR/$tdir/f- 5000
20025         unlinkmany $DIR/$tdir/f- 5000
20026         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20027                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20028         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20029                         osp.*MDT*.sync_in_flight" | calc_sum)
20030         [ "$changes" -eq 0 ] || error "$changes not synced"
20031 }
20032 run_test 239A "osp_sync test"
20033
20034 test_239a() { #LU-5297
20035         remote_mds_nodsh && skip "remote MDS with nodsh"
20036
20037         touch $DIR/$tfile
20038         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20039         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20040         chgrp $RUNAS_GID $DIR/$tfile
20041         wait_delete_completed
20042 }
20043 run_test 239a "process invalid osp sync record correctly"
20044
20045 test_239b() { #LU-5297
20046         remote_mds_nodsh && skip "remote MDS with nodsh"
20047
20048         touch $DIR/$tfile1
20049         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20050         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20051         chgrp $RUNAS_GID $DIR/$tfile1
20052         wait_delete_completed
20053         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20054         touch $DIR/$tfile2
20055         chgrp $RUNAS_GID $DIR/$tfile2
20056         wait_delete_completed
20057 }
20058 run_test 239b "process osp sync record with ENOMEM error correctly"
20059
20060 test_240() {
20061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20062         remote_mds_nodsh && skip "remote MDS with nodsh"
20063
20064         mkdir -p $DIR/$tdir
20065
20066         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20067                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20068         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20069                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20070
20071         umount_client $MOUNT || error "umount failed"
20072         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20073         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20074         mount_client $MOUNT || error "failed to mount client"
20075
20076         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20077         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20078 }
20079 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20080
20081 test_241_bio() {
20082         local count=$1
20083         local bsize=$2
20084
20085         for LOOP in $(seq $count); do
20086                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20087                 cancel_lru_locks $OSC || true
20088         done
20089 }
20090
20091 test_241_dio() {
20092         local count=$1
20093         local bsize=$2
20094
20095         for LOOP in $(seq $1); do
20096                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20097                         2>/dev/null
20098         done
20099 }
20100
20101 test_241a() { # was test_241
20102         local bsize=$PAGE_SIZE
20103
20104         (( bsize < 40960 )) && bsize=40960
20105         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20106         ls -la $DIR/$tfile
20107         cancel_lru_locks $OSC
20108         test_241_bio 1000 $bsize &
20109         PID=$!
20110         test_241_dio 1000 $bsize
20111         wait $PID
20112 }
20113 run_test 241a "bio vs dio"
20114
20115 test_241b() {
20116         local bsize=$PAGE_SIZE
20117
20118         (( bsize < 40960 )) && bsize=40960
20119         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20120         ls -la $DIR/$tfile
20121         test_241_dio 1000 $bsize &
20122         PID=$!
20123         test_241_dio 1000 $bsize
20124         wait $PID
20125 }
20126 run_test 241b "dio vs dio"
20127
20128 test_242() {
20129         remote_mds_nodsh && skip "remote MDS with nodsh"
20130
20131         mkdir_on_mdt0 $DIR/$tdir
20132         touch $DIR/$tdir/$tfile
20133
20134         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20135         do_facet mds1 lctl set_param fail_loc=0x105
20136         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20137
20138         do_facet mds1 lctl set_param fail_loc=0
20139         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20140 }
20141 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20142
20143 test_243()
20144 {
20145         test_mkdir $DIR/$tdir
20146         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20147 }
20148 run_test 243 "various group lock tests"
20149
20150 test_244a()
20151 {
20152         test_mkdir $DIR/$tdir
20153         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20154         sendfile_grouplock $DIR/$tdir/$tfile || \
20155                 error "sendfile+grouplock failed"
20156         rm -rf $DIR/$tdir
20157 }
20158 run_test 244a "sendfile with group lock tests"
20159
20160 test_244b()
20161 {
20162         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20163
20164         local threads=50
20165         local size=$((1024*1024))
20166
20167         test_mkdir $DIR/$tdir
20168         for i in $(seq 1 $threads); do
20169                 local file=$DIR/$tdir/file_$((i / 10))
20170                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20171                 local pids[$i]=$!
20172         done
20173         for i in $(seq 1 $threads); do
20174                 wait ${pids[$i]}
20175         done
20176 }
20177 run_test 244b "multi-threaded write with group lock"
20178
20179 test_245() {
20180         local flagname="multi_mod_rpcs"
20181         local connect_data_name="max_mod_rpcs"
20182         local out
20183
20184         # check if multiple modify RPCs flag is set
20185         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20186                 grep "connect_flags:")
20187         echo "$out"
20188
20189         echo "$out" | grep -qw $flagname
20190         if [ $? -ne 0 ]; then
20191                 echo "connect flag $flagname is not set"
20192                 return
20193         fi
20194
20195         # check if multiple modify RPCs data is set
20196         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20197         echo "$out"
20198
20199         echo "$out" | grep -qw $connect_data_name ||
20200                 error "import should have connect data $connect_data_name"
20201 }
20202 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20203
20204 cleanup_247() {
20205         local submount=$1
20206
20207         trap 0
20208         umount_client $submount
20209         rmdir $submount
20210 }
20211
20212 test_247a() {
20213         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20214                 grep -q subtree ||
20215                 skip_env "Fileset feature is not supported"
20216
20217         local submount=${MOUNT}_$tdir
20218
20219         mkdir $MOUNT/$tdir
20220         mkdir -p $submount || error "mkdir $submount failed"
20221         FILESET="$FILESET/$tdir" mount_client $submount ||
20222                 error "mount $submount failed"
20223         trap "cleanup_247 $submount" EXIT
20224         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20225         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20226                 error "read $MOUNT/$tdir/$tfile failed"
20227         cleanup_247 $submount
20228 }
20229 run_test 247a "mount subdir as fileset"
20230
20231 test_247b() {
20232         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20233                 skip_env "Fileset feature is not supported"
20234
20235         local submount=${MOUNT}_$tdir
20236
20237         rm -rf $MOUNT/$tdir
20238         mkdir -p $submount || error "mkdir $submount failed"
20239         SKIP_FILESET=1
20240         FILESET="$FILESET/$tdir" mount_client $submount &&
20241                 error "mount $submount should fail"
20242         rmdir $submount
20243 }
20244 run_test 247b "mount subdir that dose not exist"
20245
20246 test_247c() {
20247         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20248                 skip_env "Fileset feature is not supported"
20249
20250         local submount=${MOUNT}_$tdir
20251
20252         mkdir -p $MOUNT/$tdir/dir1
20253         mkdir -p $submount || error "mkdir $submount failed"
20254         trap "cleanup_247 $submount" EXIT
20255         FILESET="$FILESET/$tdir" mount_client $submount ||
20256                 error "mount $submount failed"
20257         local fid=$($LFS path2fid $MOUNT/)
20258         $LFS fid2path $submount $fid && error "fid2path should fail"
20259         cleanup_247 $submount
20260 }
20261 run_test 247c "running fid2path outside subdirectory root"
20262
20263 test_247d() {
20264         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20265                 skip "Fileset feature is not supported"
20266
20267         local submount=${MOUNT}_$tdir
20268
20269         mkdir -p $MOUNT/$tdir/dir1
20270         mkdir -p $submount || error "mkdir $submount failed"
20271         FILESET="$FILESET/$tdir" mount_client $submount ||
20272                 error "mount $submount failed"
20273         trap "cleanup_247 $submount" EXIT
20274
20275         local td=$submount/dir1
20276         local fid=$($LFS path2fid $td)
20277         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20278
20279         # check that we get the same pathname back
20280         local rootpath
20281         local found
20282         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20283                 echo "$rootpath $fid"
20284                 found=$($LFS fid2path $rootpath "$fid")
20285                 [ -n "found" ] || error "fid2path should succeed"
20286                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20287         done
20288         # check wrong root path format
20289         rootpath=$submount"_wrong"
20290         found=$($LFS fid2path $rootpath "$fid")
20291         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20292
20293         cleanup_247 $submount
20294 }
20295 run_test 247d "running fid2path inside subdirectory root"
20296
20297 # LU-8037
20298 test_247e() {
20299         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20300                 grep -q subtree ||
20301                 skip "Fileset feature is not supported"
20302
20303         local submount=${MOUNT}_$tdir
20304
20305         mkdir $MOUNT/$tdir
20306         mkdir -p $submount || error "mkdir $submount failed"
20307         FILESET="$FILESET/.." mount_client $submount &&
20308                 error "mount $submount should fail"
20309         rmdir $submount
20310 }
20311 run_test 247e "mount .. as fileset"
20312
20313 test_247f() {
20314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20315         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20316                 skip "Need at least version 2.13.52"
20317         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20318                 skip "Need at least version 2.14.50"
20319         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20320                 grep -q subtree ||
20321                 skip "Fileset feature is not supported"
20322
20323         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20324         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20325                 error "mkdir remote failed"
20326         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20327         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20328                 error "mkdir striped failed"
20329         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20330
20331         local submount=${MOUNT}_$tdir
20332
20333         mkdir -p $submount || error "mkdir $submount failed"
20334         stack_trap "rmdir $submount"
20335
20336         local dir
20337         local stat
20338         local fileset=$FILESET
20339         local mdts=$(comma_list $(mdts_nodes))
20340
20341         stat=$(do_facet mds1 $LCTL get_param -n \
20342                 mdt.*MDT0000.enable_remote_subdir_mount)
20343         stack_trap "do_nodes $mdts $LCTL set_param \
20344                 mdt.*.enable_remote_subdir_mount=$stat"
20345
20346         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20347         stack_trap "umount_client $submount"
20348         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20349                 error "mount remote dir $dir should fail"
20350
20351         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20352                 $tdir/striped/. ; do
20353                 FILESET="$fileset/$dir" mount_client $submount ||
20354                         error "mount $dir failed"
20355                 umount_client $submount
20356         done
20357
20358         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20359         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20360                 error "mount $tdir/remote failed"
20361 }
20362 run_test 247f "mount striped or remote directory as fileset"
20363
20364 test_247g() {
20365         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20366         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20367                 skip "Need at least version 2.14.50"
20368
20369         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20370                 error "mkdir $tdir failed"
20371         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20372
20373         local submount=${MOUNT}_$tdir
20374
20375         mkdir -p $submount || error "mkdir $submount failed"
20376         stack_trap "rmdir $submount"
20377
20378         FILESET="$fileset/$tdir" mount_client $submount ||
20379                 error "mount $dir failed"
20380         stack_trap "umount $submount"
20381
20382         local mdts=$(comma_list $(mdts_nodes))
20383
20384         local nrpcs
20385
20386         stat $submount > /dev/null
20387         cancel_lru_locks $MDC
20388         stat $submount > /dev/null
20389         stat $submount/$tfile > /dev/null
20390         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20391         stat $submount/$tfile > /dev/null
20392         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20393                 awk '/getattr/ {sum += $2} END {print sum}')
20394
20395         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20396 }
20397 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20398
20399 test_248a() {
20400         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20401         [ -z "$fast_read_sav" ] && skip "no fast read support"
20402
20403         # create a large file for fast read verification
20404         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20405
20406         # make sure the file is created correctly
20407         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20408                 { rm -f $DIR/$tfile; skip "file creation error"; }
20409
20410         echo "Test 1: verify that fast read is 4 times faster on cache read"
20411
20412         # small read with fast read enabled
20413         $LCTL set_param -n llite.*.fast_read=1
20414         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20415                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20416                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20417         # small read with fast read disabled
20418         $LCTL set_param -n llite.*.fast_read=0
20419         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20420                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20421                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20422
20423         # verify that fast read is 4 times faster for cache read
20424         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20425                 error_not_in_vm "fast read was not 4 times faster: " \
20426                            "$t_fast vs $t_slow"
20427
20428         echo "Test 2: verify the performance between big and small read"
20429         $LCTL set_param -n llite.*.fast_read=1
20430
20431         # 1k non-cache read
20432         cancel_lru_locks osc
20433         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20434                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20435                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20436
20437         # 1M non-cache read
20438         cancel_lru_locks osc
20439         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20440                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20441                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20442
20443         # verify that big IO is not 4 times faster than small IO
20444         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20445                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20446
20447         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20448         rm -f $DIR/$tfile
20449 }
20450 run_test 248a "fast read verification"
20451
20452 test_248b() {
20453         # Default short_io_bytes=16384, try both smaller and larger sizes.
20454         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20455         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20456         echo "bs=53248 count=113 normal buffered write"
20457         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20458                 error "dd of initial data file failed"
20459         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20460
20461         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20462         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20463                 error "dd with sync normal writes failed"
20464         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20465
20466         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20467         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20468                 error "dd with sync small writes failed"
20469         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20470
20471         cancel_lru_locks osc
20472
20473         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20474         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20475         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20476         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20477                 iflag=direct || error "dd with O_DIRECT small read failed"
20478         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20479         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20480                 error "compare $TMP/$tfile.1 failed"
20481
20482         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20483         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20484
20485         # just to see what the maximum tunable value is, and test parsing
20486         echo "test invalid parameter 2MB"
20487         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20488                 error "too-large short_io_bytes allowed"
20489         echo "test maximum parameter 512KB"
20490         # if we can set a larger short_io_bytes, run test regardless of version
20491         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20492                 # older clients may not allow setting it this large, that's OK
20493                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20494                         skip "Need at least client version 2.13.50"
20495                 error "medium short_io_bytes failed"
20496         fi
20497         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20498         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20499
20500         echo "test large parameter 64KB"
20501         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20502         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20503
20504         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20505         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20506                 error "dd with sync large writes failed"
20507         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20508
20509         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20510         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20511         num=$((113 * 4096 / PAGE_SIZE))
20512         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20513         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20514                 error "dd with O_DIRECT large writes failed"
20515         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20516                 error "compare $DIR/$tfile.3 failed"
20517
20518         cancel_lru_locks osc
20519
20520         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20521         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20522                 error "dd with O_DIRECT large read failed"
20523         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20524                 error "compare $TMP/$tfile.2 failed"
20525
20526         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20527         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20528                 error "dd with O_DIRECT large read failed"
20529         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20530                 error "compare $TMP/$tfile.3 failed"
20531 }
20532 run_test 248b "test short_io read and write for both small and large sizes"
20533
20534 test_249() { # LU-7890
20535         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20536                 skip "Need at least version 2.8.54"
20537
20538         rm -f $DIR/$tfile
20539         $LFS setstripe -c 1 $DIR/$tfile
20540         # Offset 2T == 4k * 512M
20541         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20542                 error "dd to 2T offset failed"
20543 }
20544 run_test 249 "Write above 2T file size"
20545
20546 test_250() {
20547         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20548          && skip "no 16TB file size limit on ZFS"
20549
20550         $LFS setstripe -c 1 $DIR/$tfile
20551         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20552         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20553         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20554         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20555                 conv=notrunc,fsync && error "append succeeded"
20556         return 0
20557 }
20558 run_test 250 "Write above 16T limit"
20559
20560 test_251() {
20561         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20562
20563         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20564         #Skip once - writing the first stripe will succeed
20565         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20566         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20567                 error "short write happened"
20568
20569         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20570         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20571                 error "short read happened"
20572
20573         rm -f $DIR/$tfile
20574 }
20575 run_test 251 "Handling short read and write correctly"
20576
20577 test_252() {
20578         remote_mds_nodsh && skip "remote MDS with nodsh"
20579         remote_ost_nodsh && skip "remote OST with nodsh"
20580         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20581                 skip_env "ldiskfs only test"
20582         fi
20583
20584         local tgt
20585         local dev
20586         local out
20587         local uuid
20588         local num
20589         local gen
20590
20591         # check lr_reader on OST0000
20592         tgt=ost1
20593         dev=$(facet_device $tgt)
20594         out=$(do_facet $tgt $LR_READER $dev)
20595         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20596         echo "$out"
20597         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20598         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20599                 error "Invalid uuid returned by $LR_READER on target $tgt"
20600         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20601
20602         # check lr_reader -c on MDT0000
20603         tgt=mds1
20604         dev=$(facet_device $tgt)
20605         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20606                 skip "$LR_READER does not support additional options"
20607         fi
20608         out=$(do_facet $tgt $LR_READER -c $dev)
20609         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20610         echo "$out"
20611         num=$(echo "$out" | grep -c "mdtlov")
20612         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20613                 error "Invalid number of mdtlov clients returned by $LR_READER"
20614         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20615
20616         # check lr_reader -cr on MDT0000
20617         out=$(do_facet $tgt $LR_READER -cr $dev)
20618         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20619         echo "$out"
20620         echo "$out" | grep -q "^reply_data:$" ||
20621                 error "$LR_READER should have returned 'reply_data' section"
20622         num=$(echo "$out" | grep -c "client_generation")
20623         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20624 }
20625 run_test 252 "check lr_reader tool"
20626
20627 test_253() {
20628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20629         remote_mds_nodsh && skip "remote MDS with nodsh"
20630         remote_mgs_nodsh && skip "remote MGS with nodsh"
20631
20632         local ostidx=0
20633         local rc=0
20634         local ost_name=$(ostname_from_index $ostidx)
20635
20636         # on the mdt's osc
20637         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20638         do_facet $SINGLEMDS $LCTL get_param -n \
20639                 osp.$mdtosc_proc1.reserved_mb_high ||
20640                 skip  "remote MDS does not support reserved_mb_high"
20641
20642         rm -rf $DIR/$tdir
20643         wait_mds_ost_sync
20644         wait_delete_completed
20645         mkdir $DIR/$tdir
20646
20647         pool_add $TESTNAME || error "Pool creation failed"
20648         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20649
20650         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20651                 error "Setstripe failed"
20652
20653         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20654
20655         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20656                     grep "watermarks")
20657         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20658
20659         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20660                         osp.$mdtosc_proc1.prealloc_status)
20661         echo "prealloc_status $oa_status"
20662
20663         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20664                 error "File creation should fail"
20665
20666         #object allocation was stopped, but we still able to append files
20667         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20668                 oflag=append || error "Append failed"
20669
20670         rm -f $DIR/$tdir/$tfile.0
20671
20672         # For this test, we want to delete the files we created to go out of
20673         # space but leave the watermark, so we remain nearly out of space
20674         ost_watermarks_enospc_delete_files $tfile $ostidx
20675
20676         wait_delete_completed
20677
20678         sleep_maxage
20679
20680         for i in $(seq 10 12); do
20681                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20682                         2>/dev/null || error "File creation failed after rm"
20683         done
20684
20685         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20686                         osp.$mdtosc_proc1.prealloc_status)
20687         echo "prealloc_status $oa_status"
20688
20689         if (( oa_status != 0 )); then
20690                 error "Object allocation still disable after rm"
20691         fi
20692 }
20693 run_test 253 "Check object allocation limit"
20694
20695 test_254() {
20696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20697         remote_mds_nodsh && skip "remote MDS with nodsh"
20698         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20699                 skip "MDS does not support changelog_size"
20700
20701         local cl_user
20702         local MDT0=$(facet_svc $SINGLEMDS)
20703
20704         changelog_register || error "changelog_register failed"
20705
20706         changelog_clear 0 || error "changelog_clear failed"
20707
20708         local size1=$(do_facet $SINGLEMDS \
20709                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20710         echo "Changelog size $size1"
20711
20712         rm -rf $DIR/$tdir
20713         $LFS mkdir -i 0 $DIR/$tdir
20714         # change something
20715         mkdir -p $DIR/$tdir/pics/2008/zachy
20716         touch $DIR/$tdir/pics/2008/zachy/timestamp
20717         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20718         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20719         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20720         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20721         rm $DIR/$tdir/pics/desktop.jpg
20722
20723         local size2=$(do_facet $SINGLEMDS \
20724                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20725         echo "Changelog size after work $size2"
20726
20727         (( $size2 > $size1 )) ||
20728                 error "new Changelog size=$size2 less than old size=$size1"
20729 }
20730 run_test 254 "Check changelog size"
20731
20732 ladvise_no_type()
20733 {
20734         local type=$1
20735         local file=$2
20736
20737         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20738                 awk -F: '{print $2}' | grep $type > /dev/null
20739         if [ $? -ne 0 ]; then
20740                 return 0
20741         fi
20742         return 1
20743 }
20744
20745 ladvise_no_ioctl()
20746 {
20747         local file=$1
20748
20749         lfs ladvise -a willread $file > /dev/null 2>&1
20750         if [ $? -eq 0 ]; then
20751                 return 1
20752         fi
20753
20754         lfs ladvise -a willread $file 2>&1 |
20755                 grep "Inappropriate ioctl for device" > /dev/null
20756         if [ $? -eq 0 ]; then
20757                 return 0
20758         fi
20759         return 1
20760 }
20761
20762 percent() {
20763         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20764 }
20765
20766 # run a random read IO workload
20767 # usage: random_read_iops <filename> <filesize> <iosize>
20768 random_read_iops() {
20769         local file=$1
20770         local fsize=$2
20771         local iosize=${3:-4096}
20772
20773         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20774                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20775 }
20776
20777 drop_file_oss_cache() {
20778         local file="$1"
20779         local nodes="$2"
20780
20781         $LFS ladvise -a dontneed $file 2>/dev/null ||
20782                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20783 }
20784
20785 ladvise_willread_performance()
20786 {
20787         local repeat=10
20788         local average_origin=0
20789         local average_cache=0
20790         local average_ladvise=0
20791
20792         for ((i = 1; i <= $repeat; i++)); do
20793                 echo "Iter $i/$repeat: reading without willread hint"
20794                 cancel_lru_locks osc
20795                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20796                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20797                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20798                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20799
20800                 cancel_lru_locks osc
20801                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20802                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20803                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20804
20805                 cancel_lru_locks osc
20806                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20807                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20808                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20809                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20810                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20811         done
20812         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20813         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20814         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20815
20816         speedup_cache=$(percent $average_cache $average_origin)
20817         speedup_ladvise=$(percent $average_ladvise $average_origin)
20818
20819         echo "Average uncached read: $average_origin"
20820         echo "Average speedup with OSS cached read: " \
20821                 "$average_cache = +$speedup_cache%"
20822         echo "Average speedup with ladvise willread: " \
20823                 "$average_ladvise = +$speedup_ladvise%"
20824
20825         local lowest_speedup=20
20826         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20827                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20828                         "got $average_cache%. Skipping ladvise willread check."
20829                 return 0
20830         fi
20831
20832         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20833         # it is still good to run until then to exercise 'ladvise willread'
20834         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20835                 [ "$ost1_FSTYPE" = "zfs" ] &&
20836                 echo "osd-zfs does not support dontneed or drop_caches" &&
20837                 return 0
20838
20839         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20840         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20841                 error_not_in_vm "Speedup with willread is less than " \
20842                         "$lowest_speedup%, got $average_ladvise%"
20843 }
20844
20845 test_255a() {
20846         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20847                 skip "lustre < 2.8.54 does not support ladvise "
20848         remote_ost_nodsh && skip "remote OST with nodsh"
20849
20850         stack_trap "rm -f $DIR/$tfile"
20851         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20852
20853         ladvise_no_type willread $DIR/$tfile &&
20854                 skip "willread ladvise is not supported"
20855
20856         ladvise_no_ioctl $DIR/$tfile &&
20857                 skip "ladvise ioctl is not supported"
20858
20859         local size_mb=100
20860         local size=$((size_mb * 1048576))
20861         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20862                 error "dd to $DIR/$tfile failed"
20863
20864         lfs ladvise -a willread $DIR/$tfile ||
20865                 error "Ladvise failed with no range argument"
20866
20867         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20868                 error "Ladvise failed with no -l or -e argument"
20869
20870         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20871                 error "Ladvise failed with only -e argument"
20872
20873         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20874                 error "Ladvise failed with only -l argument"
20875
20876         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20877                 error "End offset should not be smaller than start offset"
20878
20879         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20880                 error "End offset should not be equal to start offset"
20881
20882         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20883                 error "Ladvise failed with overflowing -s argument"
20884
20885         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20886                 error "Ladvise failed with overflowing -e argument"
20887
20888         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20889                 error "Ladvise failed with overflowing -l argument"
20890
20891         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20892                 error "Ladvise succeeded with conflicting -l and -e arguments"
20893
20894         echo "Synchronous ladvise should wait"
20895         local delay=4
20896 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20897         do_nodes $(comma_list $(osts_nodes)) \
20898                 $LCTL set_param fail_val=$delay fail_loc=0x237
20899
20900         local start_ts=$SECONDS
20901         lfs ladvise -a willread $DIR/$tfile ||
20902                 error "Ladvise failed with no range argument"
20903         local end_ts=$SECONDS
20904         local inteval_ts=$((end_ts - start_ts))
20905
20906         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20907                 error "Synchronous advice didn't wait reply"
20908         fi
20909
20910         echo "Asynchronous ladvise shouldn't wait"
20911         local start_ts=$SECONDS
20912         lfs ladvise -a willread -b $DIR/$tfile ||
20913                 error "Ladvise failed with no range argument"
20914         local end_ts=$SECONDS
20915         local inteval_ts=$((end_ts - start_ts))
20916
20917         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20918                 error "Asynchronous advice blocked"
20919         fi
20920
20921         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20922         ladvise_willread_performance
20923 }
20924 run_test 255a "check 'lfs ladvise -a willread'"
20925
20926 facet_meminfo() {
20927         local facet=$1
20928         local info=$2
20929
20930         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20931 }
20932
20933 test_255b() {
20934         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20935                 skip "lustre < 2.8.54 does not support ladvise "
20936         remote_ost_nodsh && skip "remote OST with nodsh"
20937
20938         stack_trap "rm -f $DIR/$tfile"
20939         lfs setstripe -c 1 -i 0 $DIR/$tfile
20940
20941         ladvise_no_type dontneed $DIR/$tfile &&
20942                 skip "dontneed ladvise is not supported"
20943
20944         ladvise_no_ioctl $DIR/$tfile &&
20945                 skip "ladvise ioctl is not supported"
20946
20947         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20948                 [ "$ost1_FSTYPE" = "zfs" ] &&
20949                 skip "zfs-osd does not support 'ladvise dontneed'"
20950
20951         local size_mb=100
20952         local size=$((size_mb * 1048576))
20953         # In order to prevent disturbance of other processes, only check 3/4
20954         # of the memory usage
20955         local kibibytes=$((size_mb * 1024 * 3 / 4))
20956
20957         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20958                 error "dd to $DIR/$tfile failed"
20959
20960         #force write to complete before dropping OST cache & checking memory
20961         sync
20962
20963         local total=$(facet_meminfo ost1 MemTotal)
20964         echo "Total memory: $total KiB"
20965
20966         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20967         local before_read=$(facet_meminfo ost1 Cached)
20968         echo "Cache used before read: $before_read KiB"
20969
20970         lfs ladvise -a willread $DIR/$tfile ||
20971                 error "Ladvise willread failed"
20972         local after_read=$(facet_meminfo ost1 Cached)
20973         echo "Cache used after read: $after_read KiB"
20974
20975         lfs ladvise -a dontneed $DIR/$tfile ||
20976                 error "Ladvise dontneed again failed"
20977         local no_read=$(facet_meminfo ost1 Cached)
20978         echo "Cache used after dontneed ladvise: $no_read KiB"
20979
20980         if [ $total -lt $((before_read + kibibytes)) ]; then
20981                 echo "Memory is too small, abort checking"
20982                 return 0
20983         fi
20984
20985         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20986                 error "Ladvise willread should use more memory" \
20987                         "than $kibibytes KiB"
20988         fi
20989
20990         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20991                 error "Ladvise dontneed should release more memory" \
20992                         "than $kibibytes KiB"
20993         fi
20994 }
20995 run_test 255b "check 'lfs ladvise -a dontneed'"
20996
20997 test_255c() {
20998         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20999                 skip "lustre < 2.10.50 does not support lockahead"
21000
21001         local ost1_imp=$(get_osc_import_name client ost1)
21002         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21003                          cut -d'.' -f2)
21004         local count
21005         local new_count
21006         local difference
21007         local i
21008         local rc
21009
21010         test_mkdir -p $DIR/$tdir
21011         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21012
21013         #test 10 returns only success/failure
21014         i=10
21015         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21016         rc=$?
21017         if [ $rc -eq 255 ]; then
21018                 error "Ladvise test${i} failed, ${rc}"
21019         fi
21020
21021         #test 11 counts lock enqueue requests, all others count new locks
21022         i=11
21023         count=$(do_facet ost1 \
21024                 $LCTL get_param -n ost.OSS.ost.stats)
21025         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21026
21027         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21028         rc=$?
21029         if [ $rc -eq 255 ]; then
21030                 error "Ladvise test${i} failed, ${rc}"
21031         fi
21032
21033         new_count=$(do_facet ost1 \
21034                 $LCTL get_param -n ost.OSS.ost.stats)
21035         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21036                    awk '{ print $2 }')
21037
21038         difference="$((new_count - count))"
21039         if [ $difference -ne $rc ]; then
21040                 error "Ladvise test${i}, bad enqueue count, returned " \
21041                       "${rc}, actual ${difference}"
21042         fi
21043
21044         for i in $(seq 12 21); do
21045                 # If we do not do this, we run the risk of having too many
21046                 # locks and starting lock cancellation while we are checking
21047                 # lock counts.
21048                 cancel_lru_locks osc
21049
21050                 count=$($LCTL get_param -n \
21051                        ldlm.namespaces.$imp_name.lock_unused_count)
21052
21053                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21054                 rc=$?
21055                 if [ $rc -eq 255 ]; then
21056                         error "Ladvise test ${i} failed, ${rc}"
21057                 fi
21058
21059                 new_count=$($LCTL get_param -n \
21060                        ldlm.namespaces.$imp_name.lock_unused_count)
21061                 difference="$((new_count - count))"
21062
21063                 # Test 15 output is divided by 100 to map down to valid return
21064                 if [ $i -eq 15 ]; then
21065                         rc="$((rc * 100))"
21066                 fi
21067
21068                 if [ $difference -ne $rc ]; then
21069                         error "Ladvise test ${i}, bad lock count, returned " \
21070                               "${rc}, actual ${difference}"
21071                 fi
21072         done
21073
21074         #test 22 returns only success/failure
21075         i=22
21076         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21077         rc=$?
21078         if [ $rc -eq 255 ]; then
21079                 error "Ladvise test${i} failed, ${rc}"
21080         fi
21081 }
21082 run_test 255c "suite of ladvise lockahead tests"
21083
21084 test_256() {
21085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21086         remote_mds_nodsh && skip "remote MDS with nodsh"
21087         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21088         changelog_users $SINGLEMDS | grep "^cl" &&
21089                 skip "active changelog user"
21090
21091         local cl_user
21092         local cat_sl
21093         local mdt_dev
21094
21095         mdt_dev=$(mdsdevname 1)
21096         echo $mdt_dev
21097
21098         changelog_register || error "changelog_register failed"
21099
21100         rm -rf $DIR/$tdir
21101         mkdir_on_mdt0 $DIR/$tdir
21102
21103         changelog_clear 0 || error "changelog_clear failed"
21104
21105         # change something
21106         touch $DIR/$tdir/{1..10}
21107
21108         # stop the MDT
21109         stop $SINGLEMDS || error "Fail to stop MDT"
21110
21111         # remount the MDT
21112
21113         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21114
21115         #after mount new plainllog is used
21116         touch $DIR/$tdir/{11..19}
21117         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21118         stack_trap "rm -f $tmpfile"
21119         cat_sl=$(do_facet $SINGLEMDS "sync; \
21120                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21121                  llog_reader $tmpfile | grep -c type=1064553b")
21122         do_facet $SINGLEMDS llog_reader $tmpfile
21123
21124         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21125
21126         changelog_clear 0 || error "changelog_clear failed"
21127
21128         cat_sl=$(do_facet $SINGLEMDS "sync; \
21129                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21130                  llog_reader $tmpfile | grep -c type=1064553b")
21131
21132         if (( cat_sl == 2 )); then
21133                 error "Empty plain llog was not deleted from changelog catalog"
21134         elif (( cat_sl != 1 )); then
21135                 error "Active plain llog shouldn't be deleted from catalog"
21136         fi
21137 }
21138 run_test 256 "Check llog delete for empty and not full state"
21139
21140 test_257() {
21141         remote_mds_nodsh && skip "remote MDS with nodsh"
21142         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21143                 skip "Need MDS version at least 2.8.55"
21144
21145         test_mkdir $DIR/$tdir
21146
21147         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21148                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21149         stat $DIR/$tdir
21150
21151 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21152         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21153         local facet=mds$((mdtidx + 1))
21154         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21155         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21156
21157         stop $facet || error "stop MDS failed"
21158         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21159                 error "start MDS fail"
21160         wait_recovery_complete $facet
21161 }
21162 run_test 257 "xattr locks are not lost"
21163
21164 # Verify we take the i_mutex when security requires it
21165 test_258a() {
21166 #define OBD_FAIL_IMUTEX_SEC 0x141c
21167         $LCTL set_param fail_loc=0x141c
21168         touch $DIR/$tfile
21169         chmod u+s $DIR/$tfile
21170         chmod a+rwx $DIR/$tfile
21171         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21172         RC=$?
21173         if [ $RC -ne 0 ]; then
21174                 error "error, failed to take i_mutex, rc=$?"
21175         fi
21176         rm -f $DIR/$tfile
21177 }
21178 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21179
21180 # Verify we do NOT take the i_mutex in the normal case
21181 test_258b() {
21182 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21183         $LCTL set_param fail_loc=0x141d
21184         touch $DIR/$tfile
21185         chmod a+rwx $DIR
21186         chmod a+rw $DIR/$tfile
21187         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21188         RC=$?
21189         if [ $RC -ne 0 ]; then
21190                 error "error, took i_mutex unnecessarily, rc=$?"
21191         fi
21192         rm -f $DIR/$tfile
21193
21194 }
21195 run_test 258b "verify i_mutex security behavior"
21196
21197 test_259() {
21198         local file=$DIR/$tfile
21199         local before
21200         local after
21201
21202         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21203
21204         stack_trap "rm -f $file" EXIT
21205
21206         wait_delete_completed
21207         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21208         echo "before: $before"
21209
21210         $LFS setstripe -i 0 -c 1 $file
21211         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21212         sync_all_data
21213         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21214         echo "after write: $after"
21215
21216 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21217         do_facet ost1 $LCTL set_param fail_loc=0x2301
21218         $TRUNCATE $file 0
21219         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21220         echo "after truncate: $after"
21221
21222         stop ost1
21223         do_facet ost1 $LCTL set_param fail_loc=0
21224         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21225         sleep 2
21226         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21227         echo "after restart: $after"
21228         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21229                 error "missing truncate?"
21230
21231         return 0
21232 }
21233 run_test 259 "crash at delayed truncate"
21234
21235 test_260() {
21236 #define OBD_FAIL_MDC_CLOSE               0x806
21237         $LCTL set_param fail_loc=0x80000806
21238         touch $DIR/$tfile
21239
21240 }
21241 run_test 260 "Check mdc_close fail"
21242
21243 ### Data-on-MDT sanity tests ###
21244 test_270a() {
21245         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21246                 skip "Need MDS version at least 2.10.55 for DoM"
21247
21248         # create DoM file
21249         local dom=$DIR/$tdir/dom_file
21250         local tmp=$DIR/$tdir/tmp_file
21251
21252         mkdir_on_mdt0 $DIR/$tdir
21253
21254         # basic checks for DoM component creation
21255         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21256                 error "Can set MDT layout to non-first entry"
21257
21258         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21259                 error "Can define multiple entries as MDT layout"
21260
21261         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21262
21263         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21264         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21265         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21266
21267         local mdtidx=$($LFS getstripe -m $dom)
21268         local mdtname=MDT$(printf %04x $mdtidx)
21269         local facet=mds$((mdtidx + 1))
21270         local space_check=1
21271
21272         # Skip free space checks with ZFS
21273         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21274
21275         # write
21276         sync
21277         local size_tmp=$((65536 * 3))
21278         local mdtfree1=$(do_facet $facet \
21279                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21280
21281         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21282         # check also direct IO along write
21283         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21284         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21285         sync
21286         cmp $tmp $dom || error "file data is different"
21287         [ $(stat -c%s $dom) == $size_tmp ] ||
21288                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21289         if [ $space_check == 1 ]; then
21290                 local mdtfree2=$(do_facet $facet \
21291                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21292
21293                 # increase in usage from by $size_tmp
21294                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21295                         error "MDT free space wrong after write: " \
21296                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21297         fi
21298
21299         # truncate
21300         local size_dom=10000
21301
21302         $TRUNCATE $dom $size_dom
21303         [ $(stat -c%s $dom) == $size_dom ] ||
21304                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21305         if [ $space_check == 1 ]; then
21306                 mdtfree1=$(do_facet $facet \
21307                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21308                 # decrease in usage from $size_tmp to new $size_dom
21309                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21310                   $(((size_tmp - size_dom) / 1024)) ] ||
21311                         error "MDT free space is wrong after truncate: " \
21312                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21313         fi
21314
21315         # append
21316         cat $tmp >> $dom
21317         sync
21318         size_dom=$((size_dom + size_tmp))
21319         [ $(stat -c%s $dom) == $size_dom ] ||
21320                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21321         if [ $space_check == 1 ]; then
21322                 mdtfree2=$(do_facet $facet \
21323                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21324                 # increase in usage by $size_tmp from previous
21325                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21326                         error "MDT free space is wrong after append: " \
21327                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21328         fi
21329
21330         # delete
21331         rm $dom
21332         if [ $space_check == 1 ]; then
21333                 mdtfree1=$(do_facet $facet \
21334                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21335                 # decrease in usage by $size_dom from previous
21336                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21337                         error "MDT free space is wrong after removal: " \
21338                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21339         fi
21340
21341         # combined striping
21342         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21343                 error "Can't create DoM + OST striping"
21344
21345         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21346         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21347         # check also direct IO along write
21348         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21349         sync
21350         cmp $tmp $dom || error "file data is different"
21351         [ $(stat -c%s $dom) == $size_tmp ] ||
21352                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21353         rm $dom $tmp
21354
21355         return 0
21356 }
21357 run_test 270a "DoM: basic functionality tests"
21358
21359 test_270b() {
21360         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21361                 skip "Need MDS version at least 2.10.55"
21362
21363         local dom=$DIR/$tdir/dom_file
21364         local max_size=1048576
21365
21366         mkdir -p $DIR/$tdir
21367         $LFS setstripe -E $max_size -L mdt $dom
21368
21369         # truncate over the limit
21370         $TRUNCATE $dom $(($max_size + 1)) &&
21371                 error "successful truncate over the maximum size"
21372         # write over the limit
21373         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21374                 error "successful write over the maximum size"
21375         # append over the limit
21376         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21377         echo "12345" >> $dom && error "successful append over the maximum size"
21378         rm $dom
21379
21380         return 0
21381 }
21382 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21383
21384 test_270c() {
21385         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21386                 skip "Need MDS version at least 2.10.55"
21387
21388         mkdir -p $DIR/$tdir
21389         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21390
21391         # check files inherit DoM EA
21392         touch $DIR/$tdir/first
21393         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21394                 error "bad pattern"
21395         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21396                 error "bad stripe count"
21397         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21398                 error "bad stripe size"
21399
21400         # check directory inherits DoM EA and uses it as default
21401         mkdir $DIR/$tdir/subdir
21402         touch $DIR/$tdir/subdir/second
21403         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21404                 error "bad pattern in sub-directory"
21405         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21406                 error "bad stripe count in sub-directory"
21407         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21408                 error "bad stripe size in sub-directory"
21409         return 0
21410 }
21411 run_test 270c "DoM: DoM EA inheritance tests"
21412
21413 test_270d() {
21414         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21415                 skip "Need MDS version at least 2.10.55"
21416
21417         mkdir -p $DIR/$tdir
21418         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21419
21420         # inherit default DoM striping
21421         mkdir $DIR/$tdir/subdir
21422         touch $DIR/$tdir/subdir/f1
21423
21424         # change default directory striping
21425         $LFS setstripe -c 1 $DIR/$tdir/subdir
21426         touch $DIR/$tdir/subdir/f2
21427         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21428                 error "wrong default striping in file 2"
21429         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21430                 error "bad pattern in file 2"
21431         return 0
21432 }
21433 run_test 270d "DoM: change striping from DoM to RAID0"
21434
21435 test_270e() {
21436         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21437                 skip "Need MDS version at least 2.10.55"
21438
21439         mkdir -p $DIR/$tdir/dom
21440         mkdir -p $DIR/$tdir/norm
21441         DOMFILES=20
21442         NORMFILES=10
21443         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21444         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21445
21446         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21447         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21448
21449         # find DoM files by layout
21450         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21451         [ $NUM -eq  $DOMFILES ] ||
21452                 error "lfs find -L: found $NUM, expected $DOMFILES"
21453         echo "Test 1: lfs find 20 DOM files by layout: OK"
21454
21455         # there should be 1 dir with default DOM striping
21456         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21457         [ $NUM -eq  1 ] ||
21458                 error "lfs find -L: found $NUM, expected 1 dir"
21459         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21460
21461         # find DoM files by stripe size
21462         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21463         [ $NUM -eq  $DOMFILES ] ||
21464                 error "lfs find -S: found $NUM, expected $DOMFILES"
21465         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21466
21467         # find files by stripe offset except DoM files
21468         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21469         [ $NUM -eq  $NORMFILES ] ||
21470                 error "lfs find -i: found $NUM, expected $NORMFILES"
21471         echo "Test 5: lfs find no DOM files by stripe index: OK"
21472         return 0
21473 }
21474 run_test 270e "DoM: lfs find with DoM files test"
21475
21476 test_270f() {
21477         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21478                 skip "Need MDS version at least 2.10.55"
21479
21480         local mdtname=${FSNAME}-MDT0000-mdtlov
21481         local dom=$DIR/$tdir/dom_file
21482         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21483                                                 lod.$mdtname.dom_stripesize)
21484         local dom_limit=131072
21485
21486         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21487         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21488                                                 lod.$mdtname.dom_stripesize)
21489         [ ${dom_limit} -eq ${dom_current} ] ||
21490                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21491
21492         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21493         $LFS setstripe -d $DIR/$tdir
21494         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21495                 error "Can't set directory default striping"
21496
21497         # exceed maximum stripe size
21498         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21499                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21500         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21501                 error "Able to create DoM component size more than LOD limit"
21502
21503         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21504         dom_current=$(do_facet mds1 $LCTL get_param -n \
21505                                                 lod.$mdtname.dom_stripesize)
21506         [ 0 -eq ${dom_current} ] ||
21507                 error "Can't set zero DoM stripe limit"
21508         rm $dom
21509
21510         # attempt to create DoM file on server with disabled DoM should
21511         # remove DoM entry from layout and be succeed
21512         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21513                 error "Can't create DoM file (DoM is disabled)"
21514         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21515                 error "File has DoM component while DoM is disabled"
21516         rm $dom
21517
21518         # attempt to create DoM file with only DoM stripe should return error
21519         $LFS setstripe -E $dom_limit -L mdt $dom &&
21520                 error "Able to create DoM-only file while DoM is disabled"
21521
21522         # too low values to be aligned with smallest stripe size 64K
21523         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21524         dom_current=$(do_facet mds1 $LCTL get_param -n \
21525                                                 lod.$mdtname.dom_stripesize)
21526         [ 30000 -eq ${dom_current} ] &&
21527                 error "Can set too small DoM stripe limit"
21528
21529         # 64K is a minimal stripe size in Lustre, expect limit of that size
21530         [ 65536 -eq ${dom_current} ] ||
21531                 error "Limit is not set to 64K but ${dom_current}"
21532
21533         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21534         dom_current=$(do_facet mds1 $LCTL get_param -n \
21535                                                 lod.$mdtname.dom_stripesize)
21536         echo $dom_current
21537         [ 2147483648 -eq ${dom_current} ] &&
21538                 error "Can set too large DoM stripe limit"
21539
21540         do_facet mds1 $LCTL set_param -n \
21541                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21542         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21543                 error "Can't create DoM component size after limit change"
21544         do_facet mds1 $LCTL set_param -n \
21545                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21546         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21547                 error "Can't create DoM file after limit decrease"
21548         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21549                 error "Can create big DoM component after limit decrease"
21550         touch ${dom}_def ||
21551                 error "Can't create file with old default layout"
21552
21553         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21554         return 0
21555 }
21556 run_test 270f "DoM: maximum DoM stripe size checks"
21557
21558 test_270g() {
21559         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21560                 skip "Need MDS version at least 2.13.52"
21561         local dom=$DIR/$tdir/$tfile
21562
21563         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21564         local lodname=${FSNAME}-MDT0000-mdtlov
21565
21566         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21567         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21568         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21569         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21570
21571         local dom_limit=1024
21572         local dom_threshold="50%"
21573
21574         $LFS setstripe -d $DIR/$tdir
21575         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21576                 error "Can't set directory default striping"
21577
21578         do_facet mds1 $LCTL set_param -n \
21579                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21580         # set 0 threshold and create DOM file to change tunable stripesize
21581         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21582         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21583                 error "Failed to create $dom file"
21584         # now tunable dom_cur_stripesize should reach maximum
21585         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21586                                         lod.${lodname}.dom_stripesize_cur_kb)
21587         [[ $dom_current == $dom_limit ]] ||
21588                 error "Current DOM stripesize is not maximum"
21589         rm $dom
21590
21591         # set threshold for further tests
21592         do_facet mds1 $LCTL set_param -n \
21593                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21594         echo "DOM threshold is $dom_threshold free space"
21595         local dom_def
21596         local dom_set
21597         # Spoof bfree to exceed threshold
21598         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21599         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21600         for spfree in 40 20 0 15 30 55; do
21601                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21602                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21603                         error "Failed to create $dom file"
21604                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21605                                         lod.${lodname}.dom_stripesize_cur_kb)
21606                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21607                 [[ $dom_def != $dom_current ]] ||
21608                         error "Default stripe size was not changed"
21609                 if [[ $spfree > 0 ]] ; then
21610                         dom_set=$($LFS getstripe -S $dom)
21611                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21612                                 error "DOM component size is still old"
21613                 else
21614                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21615                                 error "DoM component is set with no free space"
21616                 fi
21617                 rm $dom
21618                 dom_current=$dom_def
21619         done
21620 }
21621 run_test 270g "DoM: default DoM stripe size depends on free space"
21622
21623 test_270h() {
21624         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21625                 skip "Need MDS version at least 2.13.53"
21626
21627         local mdtname=${FSNAME}-MDT0000-mdtlov
21628         local dom=$DIR/$tdir/$tfile
21629         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21630
21631         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21632         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21633
21634         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21635         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21636                 error "can't create OST file"
21637         # mirrored file with DOM entry in the second mirror
21638         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21639                 error "can't create mirror with DoM component"
21640
21641         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21642
21643         # DOM component in the middle and has other enries in the same mirror,
21644         # should succeed but lost DoM component
21645         $LFS setstripe --copy=${dom}_1 $dom ||
21646                 error "Can't create file from OST|DOM mirror layout"
21647         # check new file has no DoM layout after all
21648         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21649                 error "File has DoM component while DoM is disabled"
21650 }
21651 run_test 270h "DoM: DoM stripe removal when disabled on server"
21652
21653 test_271a() {
21654         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21655                 skip "Need MDS version at least 2.10.55"
21656
21657         local dom=$DIR/$tdir/dom
21658
21659         mkdir -p $DIR/$tdir
21660
21661         $LFS setstripe -E 1024K -L mdt $dom
21662
21663         lctl set_param -n mdc.*.stats=clear
21664         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21665         cat $dom > /dev/null
21666         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21667         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21668         ls $dom
21669         rm -f $dom
21670 }
21671 run_test 271a "DoM: data is cached for read after write"
21672
21673 test_271b() {
21674         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21675                 skip "Need MDS version at least 2.10.55"
21676
21677         local dom=$DIR/$tdir/dom
21678
21679         mkdir -p $DIR/$tdir
21680
21681         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21682
21683         lctl set_param -n mdc.*.stats=clear
21684         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21685         cancel_lru_locks mdc
21686         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21687         # second stat to check size is cached on client
21688         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21689         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21690         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21691         rm -f $dom
21692 }
21693 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21694
21695 test_271ba() {
21696         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21697                 skip "Need MDS version at least 2.10.55"
21698
21699         local dom=$DIR/$tdir/dom
21700
21701         mkdir -p $DIR/$tdir
21702
21703         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21704
21705         lctl set_param -n mdc.*.stats=clear
21706         lctl set_param -n osc.*.stats=clear
21707         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21708         cancel_lru_locks mdc
21709         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21710         # second stat to check size is cached on client
21711         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21712         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21713         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21714         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21715         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21716         rm -f $dom
21717 }
21718 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21719
21720
21721 get_mdc_stats() {
21722         local mdtidx=$1
21723         local param=$2
21724         local mdt=MDT$(printf %04x $mdtidx)
21725
21726         if [ -z $param ]; then
21727                 lctl get_param -n mdc.*$mdt*.stats
21728         else
21729                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21730         fi
21731 }
21732
21733 test_271c() {
21734         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21735                 skip "Need MDS version at least 2.10.55"
21736
21737         local dom=$DIR/$tdir/dom
21738
21739         mkdir -p $DIR/$tdir
21740
21741         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21742
21743         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21744         local facet=mds$((mdtidx + 1))
21745
21746         cancel_lru_locks mdc
21747         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21748         createmany -o $dom 1000
21749         lctl set_param -n mdc.*.stats=clear
21750         smalliomany -w $dom 1000 200
21751         get_mdc_stats $mdtidx
21752         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21753         # Each file has 1 open, 1 IO enqueues, total 2000
21754         # but now we have also +1 getxattr for security.capability, total 3000
21755         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21756         unlinkmany $dom 1000
21757
21758         cancel_lru_locks mdc
21759         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21760         createmany -o $dom 1000
21761         lctl set_param -n mdc.*.stats=clear
21762         smalliomany -w $dom 1000 200
21763         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21764         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21765         # for OPEN and IO lock.
21766         [ $((enq - enq_2)) -ge 1000 ] ||
21767                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21768         unlinkmany $dom 1000
21769         return 0
21770 }
21771 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21772
21773 cleanup_271def_tests() {
21774         trap 0
21775         rm -f $1
21776 }
21777
21778 test_271d() {
21779         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21780                 skip "Need MDS version at least 2.10.57"
21781
21782         local dom=$DIR/$tdir/dom
21783         local tmp=$TMP/$tfile
21784         trap "cleanup_271def_tests $tmp" EXIT
21785
21786         mkdir -p $DIR/$tdir
21787
21788         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21789
21790         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21791
21792         cancel_lru_locks mdc
21793         dd if=/dev/urandom of=$tmp bs=1000 count=1
21794         dd if=$tmp of=$dom bs=1000 count=1
21795         cancel_lru_locks mdc
21796
21797         cat /etc/hosts >> $tmp
21798         lctl set_param -n mdc.*.stats=clear
21799
21800         # append data to the same file it should update local page
21801         echo "Append to the same page"
21802         cat /etc/hosts >> $dom
21803         local num=$(get_mdc_stats $mdtidx ost_read)
21804         local ra=$(get_mdc_stats $mdtidx req_active)
21805         local rw=$(get_mdc_stats $mdtidx req_waittime)
21806
21807         [ -z $num ] || error "$num READ RPC occured"
21808         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21809         echo "... DONE"
21810
21811         # compare content
21812         cmp $tmp $dom || error "file miscompare"
21813
21814         cancel_lru_locks mdc
21815         lctl set_param -n mdc.*.stats=clear
21816
21817         echo "Open and read file"
21818         cat $dom > /dev/null
21819         local num=$(get_mdc_stats $mdtidx ost_read)
21820         local ra=$(get_mdc_stats $mdtidx req_active)
21821         local rw=$(get_mdc_stats $mdtidx req_waittime)
21822
21823         [ -z $num ] || error "$num READ RPC occured"
21824         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21825         echo "... DONE"
21826
21827         # compare content
21828         cmp $tmp $dom || error "file miscompare"
21829
21830         return 0
21831 }
21832 run_test 271d "DoM: read on open (1K file in reply buffer)"
21833
21834 test_271f() {
21835         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21836                 skip "Need MDS version at least 2.10.57"
21837
21838         local dom=$DIR/$tdir/dom
21839         local tmp=$TMP/$tfile
21840         trap "cleanup_271def_tests $tmp" EXIT
21841
21842         mkdir -p $DIR/$tdir
21843
21844         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21845
21846         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21847
21848         cancel_lru_locks mdc
21849         dd if=/dev/urandom of=$tmp bs=265000 count=1
21850         dd if=$tmp of=$dom bs=265000 count=1
21851         cancel_lru_locks mdc
21852         cat /etc/hosts >> $tmp
21853         lctl set_param -n mdc.*.stats=clear
21854
21855         echo "Append to the same page"
21856         cat /etc/hosts >> $dom
21857         local num=$(get_mdc_stats $mdtidx ost_read)
21858         local ra=$(get_mdc_stats $mdtidx req_active)
21859         local rw=$(get_mdc_stats $mdtidx req_waittime)
21860
21861         [ -z $num ] || error "$num READ RPC occured"
21862         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21863         echo "... DONE"
21864
21865         # compare content
21866         cmp $tmp $dom || error "file miscompare"
21867
21868         cancel_lru_locks mdc
21869         lctl set_param -n mdc.*.stats=clear
21870
21871         echo "Open and read file"
21872         cat $dom > /dev/null
21873         local num=$(get_mdc_stats $mdtidx ost_read)
21874         local ra=$(get_mdc_stats $mdtidx req_active)
21875         local rw=$(get_mdc_stats $mdtidx req_waittime)
21876
21877         [ -z $num ] && num=0
21878         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21879         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21880         echo "... DONE"
21881
21882         # compare content
21883         cmp $tmp $dom || error "file miscompare"
21884
21885         return 0
21886 }
21887 run_test 271f "DoM: read on open (200K file and read tail)"
21888
21889 test_271g() {
21890         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21891                 skip "Skipping due to old client or server version"
21892
21893         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21894         # to get layout
21895         $CHECKSTAT -t file $DIR1/$tfile
21896
21897         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21898         MULTIOP_PID=$!
21899         sleep 1
21900         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21901         $LCTL set_param fail_loc=0x80000314
21902         rm $DIR1/$tfile || error "Unlink fails"
21903         RC=$?
21904         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21905         [ $RC -eq 0 ] || error "Failed write to stale object"
21906 }
21907 run_test 271g "Discard DoM data vs client flush race"
21908
21909 test_272a() {
21910         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21911                 skip "Need MDS version at least 2.11.50"
21912
21913         local dom=$DIR/$tdir/dom
21914         mkdir -p $DIR/$tdir
21915
21916         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21917         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21918                 error "failed to write data into $dom"
21919         local old_md5=$(md5sum $dom)
21920
21921         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21922                 error "failed to migrate to the same DoM component"
21923
21924         local new_md5=$(md5sum $dom)
21925
21926         [ "$old_md5" == "$new_md5" ] ||
21927                 error "md5sum differ: $old_md5, $new_md5"
21928
21929         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21930                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21931 }
21932 run_test 272a "DoM migration: new layout with the same DOM component"
21933
21934 test_272b() {
21935         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21936                 skip "Need MDS version at least 2.11.50"
21937
21938         local dom=$DIR/$tdir/dom
21939         mkdir -p $DIR/$tdir
21940         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21941
21942         local mdtidx=$($LFS getstripe -m $dom)
21943         local mdtname=MDT$(printf %04x $mdtidx)
21944         local facet=mds$((mdtidx + 1))
21945
21946         local mdtfree1=$(do_facet $facet \
21947                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21948         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21949                 error "failed to write data into $dom"
21950         local old_md5=$(md5sum $dom)
21951         cancel_lru_locks mdc
21952         local mdtfree1=$(do_facet $facet \
21953                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21954
21955         $LFS migrate -c2 $dom ||
21956                 error "failed to migrate to the new composite layout"
21957         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21958                 error "MDT stripe was not removed"
21959
21960         cancel_lru_locks mdc
21961         local new_md5=$(md5sum $dom)
21962         [ "$old_md5" == "$new_md5" ] ||
21963                 error "$old_md5 != $new_md5"
21964
21965         # Skip free space checks with ZFS
21966         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21967                 local mdtfree2=$(do_facet $facet \
21968                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21969                 [ $mdtfree2 -gt $mdtfree1 ] ||
21970                         error "MDT space is not freed after migration"
21971         fi
21972         return 0
21973 }
21974 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21975
21976 test_272c() {
21977         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21978                 skip "Need MDS version at least 2.11.50"
21979
21980         local dom=$DIR/$tdir/$tfile
21981         mkdir -p $DIR/$tdir
21982         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21983
21984         local mdtidx=$($LFS getstripe -m $dom)
21985         local mdtname=MDT$(printf %04x $mdtidx)
21986         local facet=mds$((mdtidx + 1))
21987
21988         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21989                 error "failed to write data into $dom"
21990         local old_md5=$(md5sum $dom)
21991         cancel_lru_locks mdc
21992         local mdtfree1=$(do_facet $facet \
21993                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21994
21995         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21996                 error "failed to migrate to the new composite layout"
21997         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21998                 error "MDT stripe was not removed"
21999
22000         cancel_lru_locks mdc
22001         local new_md5=$(md5sum $dom)
22002         [ "$old_md5" == "$new_md5" ] ||
22003                 error "$old_md5 != $new_md5"
22004
22005         # Skip free space checks with ZFS
22006         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22007                 local mdtfree2=$(do_facet $facet \
22008                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22009                 [ $mdtfree2 -gt $mdtfree1 ] ||
22010                         error "MDS space is not freed after migration"
22011         fi
22012         return 0
22013 }
22014 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22015
22016 test_272d() {
22017         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22018                 skip "Need MDS version at least 2.12.55"
22019
22020         local dom=$DIR/$tdir/$tfile
22021         mkdir -p $DIR/$tdir
22022         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22023
22024         local mdtidx=$($LFS getstripe -m $dom)
22025         local mdtname=MDT$(printf %04x $mdtidx)
22026         local facet=mds$((mdtidx + 1))
22027
22028         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22029                 error "failed to write data into $dom"
22030         local old_md5=$(md5sum $dom)
22031         cancel_lru_locks mdc
22032         local mdtfree1=$(do_facet $facet \
22033                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22034
22035         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22036                 error "failed mirroring to the new composite layout"
22037         $LFS mirror resync $dom ||
22038                 error "failed mirror resync"
22039         $LFS mirror split --mirror-id 1 -d $dom ||
22040                 error "failed mirror split"
22041
22042         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22043                 error "MDT stripe was not removed"
22044
22045         cancel_lru_locks mdc
22046         local new_md5=$(md5sum $dom)
22047         [ "$old_md5" == "$new_md5" ] ||
22048                 error "$old_md5 != $new_md5"
22049
22050         # Skip free space checks with ZFS
22051         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22052                 local mdtfree2=$(do_facet $facet \
22053                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22054                 [ $mdtfree2 -gt $mdtfree1 ] ||
22055                         error "MDS space is not freed after DOM mirror deletion"
22056         fi
22057         return 0
22058 }
22059 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22060
22061 test_272e() {
22062         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22063                 skip "Need MDS version at least 2.12.55"
22064
22065         local dom=$DIR/$tdir/$tfile
22066         mkdir -p $DIR/$tdir
22067         $LFS setstripe -c 2 $dom
22068
22069         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22070                 error "failed to write data into $dom"
22071         local old_md5=$(md5sum $dom)
22072         cancel_lru_locks mdc
22073
22074         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22075                 error "failed mirroring to the DOM layout"
22076         $LFS mirror resync $dom ||
22077                 error "failed mirror resync"
22078         $LFS mirror split --mirror-id 1 -d $dom ||
22079                 error "failed mirror split"
22080
22081         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22082                 error "MDT stripe was not removed"
22083
22084         cancel_lru_locks mdc
22085         local new_md5=$(md5sum $dom)
22086         [ "$old_md5" == "$new_md5" ] ||
22087                 error "$old_md5 != $new_md5"
22088
22089         return 0
22090 }
22091 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22092
22093 test_272f() {
22094         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22095                 skip "Need MDS version at least 2.12.55"
22096
22097         local dom=$DIR/$tdir/$tfile
22098         mkdir -p $DIR/$tdir
22099         $LFS setstripe -c 2 $dom
22100
22101         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22102                 error "failed to write data into $dom"
22103         local old_md5=$(md5sum $dom)
22104         cancel_lru_locks mdc
22105
22106         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22107                 error "failed migrating to the DOM file"
22108
22109         cancel_lru_locks mdc
22110         local new_md5=$(md5sum $dom)
22111         [ "$old_md5" != "$new_md5" ] &&
22112                 error "$old_md5 != $new_md5"
22113
22114         return 0
22115 }
22116 run_test 272f "DoM migration: OST-striped file to DOM file"
22117
22118 test_273a() {
22119         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22120                 skip "Need MDS version at least 2.11.50"
22121
22122         # Layout swap cannot be done if either file has DOM component,
22123         # this will never be supported, migration should be used instead
22124
22125         local dom=$DIR/$tdir/$tfile
22126         mkdir -p $DIR/$tdir
22127
22128         $LFS setstripe -c2 ${dom}_plain
22129         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22130         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22131                 error "can swap layout with DoM component"
22132         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22133                 error "can swap layout with DoM component"
22134
22135         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22136         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22137                 error "can swap layout with DoM component"
22138         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22139                 error "can swap layout with DoM component"
22140         return 0
22141 }
22142 run_test 273a "DoM: layout swapping should fail with DOM"
22143
22144 test_273b() {
22145         mkdir -p $DIR/$tdir
22146         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22147
22148 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22149         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22150
22151         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22152 }
22153 run_test 273b "DoM: race writeback and object destroy"
22154
22155 test_275() {
22156         remote_ost_nodsh && skip "remote OST with nodsh"
22157         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22158                 skip "Need OST version >= 2.10.57"
22159
22160         local file=$DIR/$tfile
22161         local oss
22162
22163         oss=$(comma_list $(osts_nodes))
22164
22165         dd if=/dev/urandom of=$file bs=1M count=2 ||
22166                 error "failed to create a file"
22167         cancel_lru_locks osc
22168
22169         #lock 1
22170         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22171                 error "failed to read a file"
22172
22173 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22174         $LCTL set_param fail_loc=0x8000031f
22175
22176         cancel_lru_locks osc &
22177         sleep 1
22178
22179 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22180         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22181         #IO takes another lock, but matches the PENDING one
22182         #and places it to the IO RPC
22183         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22184                 error "failed to read a file with PENDING lock"
22185 }
22186 run_test 275 "Read on a canceled duplicate lock"
22187
22188 test_276() {
22189         remote_ost_nodsh && skip "remote OST with nodsh"
22190         local pid
22191
22192         do_facet ost1 "(while true; do \
22193                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22194                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22195         pid=$!
22196
22197         for LOOP in $(seq 20); do
22198                 stop ost1
22199                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22200         done
22201         kill -9 $pid
22202         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22203                 rm $TMP/sanity_276_pid"
22204 }
22205 run_test 276 "Race between mount and obd_statfs"
22206
22207 test_277() {
22208         $LCTL set_param ldlm.namespaces.*.lru_size=0
22209         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22210         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22211                         grep ^used_mb | awk '{print $2}')
22212         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22214                 oflag=direct conv=notrunc
22215         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22216                         grep ^used_mb | awk '{print $2}')
22217         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22218 }
22219 run_test 277 "Direct IO shall drop page cache"
22220
22221 test_278() {
22222         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22223         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22224         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22225                 skip "needs the same host for mdt1 mdt2" && return
22226
22227         local pid1
22228         local pid2
22229
22230 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22231         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22232         stop mds2 &
22233         pid2=$!
22234
22235         stop mds1
22236
22237         echo "Starting MDTs"
22238         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22239         wait $pid2
22240 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22241 #will return NULL
22242         do_facet mds2 $LCTL set_param fail_loc=0
22243
22244         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22245         wait_recovery_complete mds2
22246 }
22247 run_test 278 "Race starting MDS between MDTs stop/start"
22248
22249 test_280() {
22250         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22251                 skip "Need MGS version at least 2.13.52"
22252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22253         combined_mgs_mds || skip "needs combined MGS/MDT"
22254
22255         umount_client $MOUNT
22256 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22257         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22258
22259         mount_client $MOUNT &
22260         sleep 1
22261         stop mgs || error "stop mgs failed"
22262         #for a race mgs would crash
22263         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22264         # make sure we unmount client before remounting
22265         wait
22266         umount_client $MOUNT
22267         mount_client $MOUNT || error "mount client failed"
22268 }
22269 run_test 280 "Race between MGS umount and client llog processing"
22270
22271 cleanup_test_300() {
22272         trap 0
22273         umask $SAVE_UMASK
22274 }
22275 test_striped_dir() {
22276         local mdt_index=$1
22277         local stripe_count
22278         local stripe_index
22279
22280         mkdir -p $DIR/$tdir
22281
22282         SAVE_UMASK=$(umask)
22283         trap cleanup_test_300 RETURN EXIT
22284
22285         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22286                                                 $DIR/$tdir/striped_dir ||
22287                 error "set striped dir error"
22288
22289         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22290         [ "$mode" = "755" ] || error "expect 755 got $mode"
22291
22292         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22293                 error "getdirstripe failed"
22294         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22295         if [ "$stripe_count" != "2" ]; then
22296                 error "1:stripe_count is $stripe_count, expect 2"
22297         fi
22298         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22299         if [ "$stripe_count" != "2" ]; then
22300                 error "2:stripe_count is $stripe_count, expect 2"
22301         fi
22302
22303         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22304         if [ "$stripe_index" != "$mdt_index" ]; then
22305                 error "stripe_index is $stripe_index, expect $mdt_index"
22306         fi
22307
22308         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22309                 error "nlink error after create striped dir"
22310
22311         mkdir $DIR/$tdir/striped_dir/a
22312         mkdir $DIR/$tdir/striped_dir/b
22313
22314         stat $DIR/$tdir/striped_dir/a ||
22315                 error "create dir under striped dir failed"
22316         stat $DIR/$tdir/striped_dir/b ||
22317                 error "create dir under striped dir failed"
22318
22319         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22320                 error "nlink error after mkdir"
22321
22322         rmdir $DIR/$tdir/striped_dir/a
22323         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22324                 error "nlink error after rmdir"
22325
22326         rmdir $DIR/$tdir/striped_dir/b
22327         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22328                 error "nlink error after rmdir"
22329
22330         chattr +i $DIR/$tdir/striped_dir
22331         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22332                 error "immutable flags not working under striped dir!"
22333         chattr -i $DIR/$tdir/striped_dir
22334
22335         rmdir $DIR/$tdir/striped_dir ||
22336                 error "rmdir striped dir error"
22337
22338         cleanup_test_300
22339
22340         true
22341 }
22342
22343 test_300a() {
22344         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22345                 skip "skipped for lustre < 2.7.0"
22346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22348
22349         test_striped_dir 0 || error "failed on striped dir on MDT0"
22350         test_striped_dir 1 || error "failed on striped dir on MDT0"
22351 }
22352 run_test 300a "basic striped dir sanity test"
22353
22354 test_300b() {
22355         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22356                 skip "skipped for lustre < 2.7.0"
22357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22359
22360         local i
22361         local mtime1
22362         local mtime2
22363         local mtime3
22364
22365         test_mkdir $DIR/$tdir || error "mkdir fail"
22366         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22367                 error "set striped dir error"
22368         for i in {0..9}; do
22369                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22370                 sleep 1
22371                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22372                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22373                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22374                 sleep 1
22375                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22376                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22377                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22378         done
22379         true
22380 }
22381 run_test 300b "check ctime/mtime for striped dir"
22382
22383 test_300c() {
22384         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22385                 skip "skipped for lustre < 2.7.0"
22386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22388
22389         local file_count
22390
22391         mkdir_on_mdt0 $DIR/$tdir
22392         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22393                 error "set striped dir error"
22394
22395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22396                 error "chown striped dir failed"
22397
22398         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22399                 error "create 5k files failed"
22400
22401         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22402
22403         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22404
22405         rm -rf $DIR/$tdir
22406 }
22407 run_test 300c "chown && check ls under striped directory"
22408
22409 test_300d() {
22410         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22411                 skip "skipped for lustre < 2.7.0"
22412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22414
22415         local stripe_count
22416         local file
22417
22418         mkdir -p $DIR/$tdir
22419         $LFS setstripe -c 2 $DIR/$tdir
22420
22421         #local striped directory
22422         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22423                 error "set striped dir error"
22424         #look at the directories for debug purposes
22425         ls -l $DIR/$tdir
22426         $LFS getdirstripe $DIR/$tdir
22427         ls -l $DIR/$tdir/striped_dir
22428         $LFS getdirstripe $DIR/$tdir/striped_dir
22429         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22430                 error "create 10 files failed"
22431
22432         #remote striped directory
22433         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22434                 error "set striped dir error"
22435         #look at the directories for debug purposes
22436         ls -l $DIR/$tdir
22437         $LFS getdirstripe $DIR/$tdir
22438         ls -l $DIR/$tdir/remote_striped_dir
22439         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22440         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22441                 error "create 10 files failed"
22442
22443         for file in $(find $DIR/$tdir); do
22444                 stripe_count=$($LFS getstripe -c $file)
22445                 [ $stripe_count -eq 2 ] ||
22446                         error "wrong stripe $stripe_count for $file"
22447         done
22448
22449         rm -rf $DIR/$tdir
22450 }
22451 run_test 300d "check default stripe under striped directory"
22452
22453 test_300e() {
22454         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22455                 skip "Need MDS version at least 2.7.55"
22456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22458
22459         local stripe_count
22460         local file
22461
22462         mkdir -p $DIR/$tdir
22463
22464         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22465                 error "set striped dir error"
22466
22467         touch $DIR/$tdir/striped_dir/a
22468         touch $DIR/$tdir/striped_dir/b
22469         touch $DIR/$tdir/striped_dir/c
22470
22471         mkdir $DIR/$tdir/striped_dir/dir_a
22472         mkdir $DIR/$tdir/striped_dir/dir_b
22473         mkdir $DIR/$tdir/striped_dir/dir_c
22474
22475         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22476                 error "set striped adir under striped dir error"
22477
22478         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22479                 error "set striped bdir under striped dir error"
22480
22481         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22482                 error "set striped cdir under striped dir error"
22483
22484         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22485                 error "rename dir under striped dir fails"
22486
22487         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22488                 error "rename dir under different stripes fails"
22489
22490         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22491                 error "rename file under striped dir should succeed"
22492
22493         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22494                 error "rename dir under striped dir should succeed"
22495
22496         rm -rf $DIR/$tdir
22497 }
22498 run_test 300e "check rename under striped directory"
22499
22500 test_300f() {
22501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22503         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22504                 skip "Need MDS version at least 2.7.55"
22505
22506         local stripe_count
22507         local file
22508
22509         rm -rf $DIR/$tdir
22510         mkdir -p $DIR/$tdir
22511
22512         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22513                 error "set striped dir error"
22514
22515         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22516                 error "set striped dir error"
22517
22518         touch $DIR/$tdir/striped_dir/a
22519         mkdir $DIR/$tdir/striped_dir/dir_a
22520         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22521                 error "create striped dir under striped dir fails"
22522
22523         touch $DIR/$tdir/striped_dir1/b
22524         mkdir $DIR/$tdir/striped_dir1/dir_b
22525         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22526                 error "create striped dir under striped dir fails"
22527
22528         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22529                 error "rename dir under different striped dir should fail"
22530
22531         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22532                 error "rename striped dir under diff striped dir should fail"
22533
22534         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22535                 error "rename file under diff striped dirs fails"
22536
22537         rm -rf $DIR/$tdir
22538 }
22539 run_test 300f "check rename cross striped directory"
22540
22541 test_300_check_default_striped_dir()
22542 {
22543         local dirname=$1
22544         local default_count=$2
22545         local default_index=$3
22546         local stripe_count
22547         local stripe_index
22548         local dir_stripe_index
22549         local dir
22550
22551         echo "checking $dirname $default_count $default_index"
22552         $LFS setdirstripe -D -c $default_count -i $default_index \
22553                                 -H all_char $DIR/$tdir/$dirname ||
22554                 error "set default stripe on striped dir error"
22555         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22556         [ $stripe_count -eq $default_count ] ||
22557                 error "expect $default_count get $stripe_count for $dirname"
22558
22559         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22560         [ $stripe_index -eq $default_index ] ||
22561                 error "expect $default_index get $stripe_index for $dirname"
22562
22563         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22564                                                 error "create dirs failed"
22565
22566         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22567         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22568         for dir in $(find $DIR/$tdir/$dirname/*); do
22569                 stripe_count=$($LFS getdirstripe -c $dir)
22570                 (( $stripe_count == $default_count )) ||
22571                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22572                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22573                 error "stripe count $default_count != $stripe_count for $dir"
22574
22575                 stripe_index=$($LFS getdirstripe -i $dir)
22576                 [ $default_index -eq -1 ] ||
22577                         [ $stripe_index -eq $default_index ] ||
22578                         error "$stripe_index != $default_index for $dir"
22579
22580                 #check default stripe
22581                 stripe_count=$($LFS getdirstripe -D -c $dir)
22582                 [ $stripe_count -eq $default_count ] ||
22583                 error "default count $default_count != $stripe_count for $dir"
22584
22585                 stripe_index=$($LFS getdirstripe -D -i $dir)
22586                 [ $stripe_index -eq $default_index ] ||
22587                 error "default index $default_index != $stripe_index for $dir"
22588         done
22589         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22590 }
22591
22592 test_300g() {
22593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22594         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22595                 skip "Need MDS version at least 2.7.55"
22596
22597         local dir
22598         local stripe_count
22599         local stripe_index
22600
22601         mkdir_on_mdt0 $DIR/$tdir
22602         mkdir $DIR/$tdir/normal_dir
22603
22604         #Checking when client cache stripe index
22605         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22606         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22607                 error "create striped_dir failed"
22608
22609         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22610                 error "create dir0 fails"
22611         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22612         [ $stripe_index -eq 0 ] ||
22613                 error "dir0 expect index 0 got $stripe_index"
22614
22615         mkdir $DIR/$tdir/striped_dir/dir1 ||
22616                 error "create dir1 fails"
22617         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22618         [ $stripe_index -eq 1 ] ||
22619                 error "dir1 expect index 1 got $stripe_index"
22620
22621         #check default stripe count/stripe index
22622         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22623         test_300_check_default_striped_dir normal_dir 1 0
22624         test_300_check_default_striped_dir normal_dir -1 1
22625         test_300_check_default_striped_dir normal_dir 2 -1
22626
22627         #delete default stripe information
22628         echo "delete default stripeEA"
22629         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22630                 error "set default stripe on striped dir error"
22631
22632         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22633         for dir in $(find $DIR/$tdir/normal_dir/*); do
22634                 stripe_count=$($LFS getdirstripe -c $dir)
22635                 [ $stripe_count -eq 0 ] ||
22636                         error "expect 1 get $stripe_count for $dir"
22637                 stripe_index=$($LFS getdirstripe -i $dir)
22638                 [ $stripe_index -eq 0 ] ||
22639                         error "expect 0 get $stripe_index for $dir"
22640         done
22641 }
22642 run_test 300g "check default striped directory for normal directory"
22643
22644 test_300h() {
22645         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22646         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22647                 skip "Need MDS version at least 2.7.55"
22648
22649         local dir
22650         local stripe_count
22651
22652         mkdir $DIR/$tdir
22653         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22654                 error "set striped dir error"
22655
22656         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22657         test_300_check_default_striped_dir striped_dir 1 0
22658         test_300_check_default_striped_dir striped_dir -1 1
22659         test_300_check_default_striped_dir striped_dir 2 -1
22660
22661         #delete default stripe information
22662         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22663                 error "set default stripe on striped dir error"
22664
22665         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22666         for dir in $(find $DIR/$tdir/striped_dir/*); do
22667                 stripe_count=$($LFS getdirstripe -c $dir)
22668                 [ $stripe_count -eq 0 ] ||
22669                         error "expect 1 get $stripe_count for $dir"
22670         done
22671 }
22672 run_test 300h "check default striped directory for striped directory"
22673
22674 test_300i() {
22675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22677         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22678                 skip "Need MDS version at least 2.7.55"
22679
22680         local stripe_count
22681         local file
22682
22683         mkdir $DIR/$tdir
22684
22685         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22686                 error "set striped dir error"
22687
22688         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22689                 error "create files under striped dir failed"
22690
22691         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22692                 error "set striped hashdir error"
22693
22694         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22695                 error "create dir0 under hash dir failed"
22696         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22697                 error "create dir1 under hash dir failed"
22698         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22699                 error "create dir2 under hash dir failed"
22700
22701         # unfortunately, we need to umount to clear dir layout cache for now
22702         # once we fully implement dir layout, we can drop this
22703         umount_client $MOUNT || error "umount failed"
22704         mount_client $MOUNT || error "mount failed"
22705
22706         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22707         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22708         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22709
22710         #set the stripe to be unknown hash type
22711         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22712         $LCTL set_param fail_loc=0x1901
22713         for ((i = 0; i < 10; i++)); do
22714                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22715                         error "stat f-$i failed"
22716                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22717         done
22718
22719         touch $DIR/$tdir/striped_dir/f0 &&
22720                 error "create under striped dir with unknown hash should fail"
22721
22722         $LCTL set_param fail_loc=0
22723
22724         umount_client $MOUNT || error "umount failed"
22725         mount_client $MOUNT || error "mount failed"
22726
22727         return 0
22728 }
22729 run_test 300i "client handle unknown hash type striped directory"
22730
22731 test_300j() {
22732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22734         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22735                 skip "Need MDS version at least 2.7.55"
22736
22737         local stripe_count
22738         local file
22739
22740         mkdir $DIR/$tdir
22741
22742         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22743         $LCTL set_param fail_loc=0x1702
22744         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22745                 error "set striped dir error"
22746
22747         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22748                 error "create files under striped dir failed"
22749
22750         $LCTL set_param fail_loc=0
22751
22752         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22753
22754         return 0
22755 }
22756 run_test 300j "test large update record"
22757
22758 test_300k() {
22759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22761         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22762                 skip "Need MDS version at least 2.7.55"
22763
22764         # this test needs a huge transaction
22765         local kb
22766         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22767              osd*.$FSNAME-MDT0000.kbytestotal")
22768         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22769
22770         local stripe_count
22771         local file
22772
22773         mkdir $DIR/$tdir
22774
22775         #define OBD_FAIL_LARGE_STRIPE   0x1703
22776         $LCTL set_param fail_loc=0x1703
22777         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22778                 error "set striped dir error"
22779         $LCTL set_param fail_loc=0
22780
22781         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22782                 error "getstripeddir fails"
22783         rm -rf $DIR/$tdir/striped_dir ||
22784                 error "unlink striped dir fails"
22785
22786         return 0
22787 }
22788 run_test 300k "test large striped directory"
22789
22790 test_300l() {
22791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22793         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22794                 skip "Need MDS version at least 2.7.55"
22795
22796         local stripe_index
22797
22798         test_mkdir -p $DIR/$tdir/striped_dir
22799         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22800                         error "chown $RUNAS_ID failed"
22801         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22802                 error "set default striped dir failed"
22803
22804         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22805         $LCTL set_param fail_loc=0x80000158
22806         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22807
22808         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22809         [ $stripe_index -eq 1 ] ||
22810                 error "expect 1 get $stripe_index for $dir"
22811 }
22812 run_test 300l "non-root user to create dir under striped dir with stale layout"
22813
22814 test_300m() {
22815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22816         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22817         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22818                 skip "Need MDS version at least 2.7.55"
22819
22820         mkdir -p $DIR/$tdir/striped_dir
22821         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22822                 error "set default stripes dir error"
22823
22824         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22825
22826         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22827         [ $stripe_count -eq 0 ] ||
22828                         error "expect 0 get $stripe_count for a"
22829
22830         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22831                 error "set default stripes dir error"
22832
22833         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22834
22835         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22836         [ $stripe_count -eq 0 ] ||
22837                         error "expect 0 get $stripe_count for b"
22838
22839         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22840                 error "set default stripes dir error"
22841
22842         mkdir $DIR/$tdir/striped_dir/c &&
22843                 error "default stripe_index is invalid, mkdir c should fails"
22844
22845         rm -rf $DIR/$tdir || error "rmdir fails"
22846 }
22847 run_test 300m "setstriped directory on single MDT FS"
22848
22849 cleanup_300n() {
22850         local list=$(comma_list $(mdts_nodes))
22851
22852         trap 0
22853         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22854 }
22855
22856 test_300n() {
22857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22859         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22860                 skip "Need MDS version at least 2.7.55"
22861         remote_mds_nodsh && skip "remote MDS with nodsh"
22862
22863         local stripe_index
22864         local list=$(comma_list $(mdts_nodes))
22865
22866         trap cleanup_300n RETURN EXIT
22867         mkdir -p $DIR/$tdir
22868         chmod 777 $DIR/$tdir
22869         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22870                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22871                 error "create striped dir succeeds with gid=0"
22872
22873         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22874         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22875                 error "create striped dir fails with gid=-1"
22876
22877         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22878         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22879                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22880                 error "set default striped dir succeeds with gid=0"
22881
22882
22883         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22884         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22885                 error "set default striped dir fails with gid=-1"
22886
22887
22888         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22889         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22890                                         error "create test_dir fails"
22891         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22892                                         error "create test_dir1 fails"
22893         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22894                                         error "create test_dir2 fails"
22895         cleanup_300n
22896 }
22897 run_test 300n "non-root user to create dir under striped dir with default EA"
22898
22899 test_300o() {
22900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22902         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22903                 skip "Need MDS version at least 2.7.55"
22904
22905         local numfree1
22906         local numfree2
22907
22908         mkdir -p $DIR/$tdir
22909
22910         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22911         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22912         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22913                 skip "not enough free inodes $numfree1 $numfree2"
22914         fi
22915
22916         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22917         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22918         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22919                 skip "not enough free space $numfree1 $numfree2"
22920         fi
22921
22922         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22923                 error "setdirstripe fails"
22924
22925         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22926                 error "create dirs fails"
22927
22928         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22929         ls $DIR/$tdir/striped_dir > /dev/null ||
22930                 error "ls striped dir fails"
22931         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22932                 error "unlink big striped dir fails"
22933 }
22934 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22935
22936 test_300p() {
22937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22939         remote_mds_nodsh && skip "remote MDS with nodsh"
22940
22941         mkdir_on_mdt0 $DIR/$tdir
22942
22943         #define OBD_FAIL_OUT_ENOSPC     0x1704
22944         do_facet mds2 lctl set_param fail_loc=0x80001704
22945         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22946                  && error "create striped directory should fail"
22947
22948         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22949
22950         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22951         true
22952 }
22953 run_test 300p "create striped directory without space"
22954
22955 test_300q() {
22956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22958
22959         local fd=$(free_fd)
22960         local cmd="exec $fd<$tdir"
22961         cd $DIR
22962         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22963         eval $cmd
22964         cmd="exec $fd<&-"
22965         trap "eval $cmd" EXIT
22966         cd $tdir || error "cd $tdir fails"
22967         rmdir  ../$tdir || error "rmdir $tdir fails"
22968         mkdir local_dir && error "create dir succeeds"
22969         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22970         eval $cmd
22971         return 0
22972 }
22973 run_test 300q "create remote directory under orphan directory"
22974
22975 test_300r() {
22976         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22977                 skip "Need MDS version at least 2.7.55" && return
22978         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22979
22980         mkdir $DIR/$tdir
22981
22982         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22983                 error "set striped dir error"
22984
22985         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22986                 error "getstripeddir fails"
22987
22988         local stripe_count
22989         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22990                       awk '/lmv_stripe_count:/ { print $2 }')
22991
22992         [ $MDSCOUNT -ne $stripe_count ] &&
22993                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22994
22995         rm -rf $DIR/$tdir/striped_dir ||
22996                 error "unlink striped dir fails"
22997 }
22998 run_test 300r "test -1 striped directory"
22999
23000 test_300s_helper() {
23001         local count=$1
23002
23003         local stripe_dir=$DIR/$tdir/striped_dir.$count
23004
23005         $LFS mkdir -c $count $stripe_dir ||
23006                 error "lfs mkdir -c error"
23007
23008         $LFS getdirstripe $stripe_dir ||
23009                 error "lfs getdirstripe fails"
23010
23011         local stripe_count
23012         stripe_count=$($LFS getdirstripe $stripe_dir |
23013                       awk '/lmv_stripe_count:/ { print $2 }')
23014
23015         [ $count -ne $stripe_count ] &&
23016                 error_noexit "bad stripe count $stripe_count expected $count"
23017
23018         local dupe_stripes
23019         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23020                 awk '/0x/ {count[$1] += 1}; END {
23021                         for (idx in count) {
23022                                 if (count[idx]>1) {
23023                                         print "index " idx " count " count[idx]
23024                                 }
23025                         }
23026                 }')
23027
23028         if [[ -n "$dupe_stripes" ]] ; then
23029                 lfs getdirstripe $stripe_dir
23030                 error_noexit "Dupe MDT above: $dupe_stripes "
23031         fi
23032
23033         rm -rf $stripe_dir ||
23034                 error_noexit "unlink $stripe_dir fails"
23035 }
23036
23037 test_300s() {
23038         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23039                 skip "Need MDS version at least 2.7.55" && return
23040         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23041
23042         mkdir $DIR/$tdir
23043         for count in $(seq 2 $MDSCOUNT); do
23044                 test_300s_helper $count
23045         done
23046 }
23047 run_test 300s "test lfs mkdir -c without -i"
23048
23049
23050 prepare_remote_file() {
23051         mkdir $DIR/$tdir/src_dir ||
23052                 error "create remote source failed"
23053
23054         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23055                  error "cp to remote source failed"
23056         touch $DIR/$tdir/src_dir/a
23057
23058         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23059                 error "create remote target dir failed"
23060
23061         touch $DIR/$tdir/tgt_dir/b
23062
23063         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23064                 error "rename dir cross MDT failed!"
23065
23066         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23067                 error "src_child still exists after rename"
23068
23069         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23070                 error "missing file(a) after rename"
23071
23072         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23073                 error "diff after rename"
23074 }
23075
23076 test_310a() {
23077         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23079
23080         local remote_file=$DIR/$tdir/tgt_dir/b
23081
23082         mkdir -p $DIR/$tdir
23083
23084         prepare_remote_file || error "prepare remote file failed"
23085
23086         #open-unlink file
23087         $OPENUNLINK $remote_file $remote_file ||
23088                 error "openunlink $remote_file failed"
23089         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23090 }
23091 run_test 310a "open unlink remote file"
23092
23093 test_310b() {
23094         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23096
23097         local remote_file=$DIR/$tdir/tgt_dir/b
23098
23099         mkdir -p $DIR/$tdir
23100
23101         prepare_remote_file || error "prepare remote file failed"
23102
23103         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23104         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23105         $CHECKSTAT -t file $remote_file || error "check file failed"
23106 }
23107 run_test 310b "unlink remote file with multiple links while open"
23108
23109 test_310c() {
23110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23111         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23112
23113         local remote_file=$DIR/$tdir/tgt_dir/b
23114
23115         mkdir -p $DIR/$tdir
23116
23117         prepare_remote_file || error "prepare remote file failed"
23118
23119         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23120         multiop_bg_pause $remote_file O_uc ||
23121                         error "mulitop failed for remote file"
23122         MULTIPID=$!
23123         $MULTIOP $DIR/$tfile Ouc
23124         kill -USR1 $MULTIPID
23125         wait $MULTIPID
23126 }
23127 run_test 310c "open-unlink remote file with multiple links"
23128
23129 #LU-4825
23130 test_311() {
23131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23132         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23133         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23134                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23135         remote_mds_nodsh && skip "remote MDS with nodsh"
23136
23137         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23138         local mdts=$(comma_list $(mdts_nodes))
23139
23140         mkdir -p $DIR/$tdir
23141         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23142         createmany -o $DIR/$tdir/$tfile. 1000
23143
23144         # statfs data is not real time, let's just calculate it
23145         old_iused=$((old_iused + 1000))
23146
23147         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23148                         osp.*OST0000*MDT0000.create_count")
23149         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23150                                 osp.*OST0000*MDT0000.max_create_count")
23151         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23152
23153         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23154         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23155         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23156
23157         unlinkmany $DIR/$tdir/$tfile. 1000
23158
23159         do_nodes $mdts "$LCTL set_param -n \
23160                         osp.*OST0000*.max_create_count=$max_count"
23161         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23162                 do_nodes $mdts "$LCTL set_param -n \
23163                                 osp.*OST0000*.create_count=$count"
23164         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23165                         grep "=0" && error "create_count is zero"
23166
23167         local new_iused
23168         for i in $(seq 120); do
23169                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23170                 # system may be too busy to destroy all objs in time, use
23171                 # a somewhat small value to not fail autotest
23172                 [ $((old_iused - new_iused)) -gt 400 ] && break
23173                 sleep 1
23174         done
23175
23176         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23177         [ $((old_iused - new_iused)) -gt 400 ] ||
23178                 error "objs not destroyed after unlink"
23179 }
23180 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23181
23182 zfs_oid_to_objid()
23183 {
23184         local ost=$1
23185         local objid=$2
23186
23187         local vdevdir=$(dirname $(facet_vdevice $ost))
23188         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23189         local zfs_zapid=$(do_facet $ost $cmd |
23190                           grep -w "/O/0/d$((objid%32))" -C 5 |
23191                           awk '/Object/{getline; print $1}')
23192         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23193                           awk "/$objid = /"'{printf $3}')
23194
23195         echo $zfs_objid
23196 }
23197
23198 zfs_object_blksz() {
23199         local ost=$1
23200         local objid=$2
23201
23202         local vdevdir=$(dirname $(facet_vdevice $ost))
23203         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23204         local blksz=$(do_facet $ost $cmd $objid |
23205                       awk '/dblk/{getline; printf $4}')
23206
23207         case "${blksz: -1}" in
23208                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23209                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23210                 *) ;;
23211         esac
23212
23213         echo $blksz
23214 }
23215
23216 test_312() { # LU-4856
23217         remote_ost_nodsh && skip "remote OST with nodsh"
23218         [ "$ost1_FSTYPE" = "zfs" ] ||
23219                 skip_env "the test only applies to zfs"
23220
23221         local max_blksz=$(do_facet ost1 \
23222                           $ZFS get -p recordsize $(facet_device ost1) |
23223                           awk '!/VALUE/{print $3}')
23224
23225         # to make life a little bit easier
23226         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23227         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23228
23229         local tf=$DIR/$tdir/$tfile
23230         touch $tf
23231         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23232
23233         # Get ZFS object id
23234         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23235         # block size change by sequential overwrite
23236         local bs
23237
23238         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23239                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23240
23241                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23242                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23243         done
23244         rm -f $tf
23245
23246         # block size change by sequential append write
23247         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23248         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23249         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23250         local count
23251
23252         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23253                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23254                         oflag=sync conv=notrunc
23255
23256                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23257                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23258                         error "blksz error, actual $blksz, " \
23259                                 "expected: 2 * $count * $PAGE_SIZE"
23260         done
23261         rm -f $tf
23262
23263         # random write
23264         touch $tf
23265         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23266         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23267
23268         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23269         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23270         [ $blksz -eq $PAGE_SIZE ] ||
23271                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23272
23273         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23274         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23275         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23276
23277         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23278         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23279         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23280 }
23281 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23282
23283 test_313() {
23284         remote_ost_nodsh && skip "remote OST with nodsh"
23285
23286         local file=$DIR/$tfile
23287
23288         rm -f $file
23289         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23290
23291         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23292         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23293         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23294                 error "write should failed"
23295         do_facet ost1 "$LCTL set_param fail_loc=0"
23296         rm -f $file
23297 }
23298 run_test 313 "io should fail after last_rcvd update fail"
23299
23300 test_314() {
23301         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23302
23303         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23304         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23305         rm -f $DIR/$tfile
23306         wait_delete_completed
23307         do_facet ost1 "$LCTL set_param fail_loc=0"
23308 }
23309 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23310
23311 test_315() { # LU-618
23312         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23313
23314         local file=$DIR/$tfile
23315         rm -f $file
23316
23317         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23318                 error "multiop file write failed"
23319         $MULTIOP $file oO_RDONLY:r4063232_c &
23320         PID=$!
23321
23322         sleep 2
23323
23324         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23325         kill -USR1 $PID
23326
23327         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23328         rm -f $file
23329 }
23330 run_test 315 "read should be accounted"
23331
23332 test_316() {
23333         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23334         large_xattr_enabled || skip_env "ea_inode feature disabled"
23335
23336         rm -rf $DIR/$tdir/d
23337         mkdir -p $DIR/$tdir/d
23338         chown nobody $DIR/$tdir/d
23339         touch $DIR/$tdir/d/file
23340
23341         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23342 }
23343 run_test 316 "lfs mv"
23344
23345 test_317() {
23346         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23347                 skip "Need MDS version at least 2.11.53"
23348         if [ "$ost1_FSTYPE" == "zfs" ]; then
23349                 skip "LU-10370: no implementation for ZFS"
23350         fi
23351
23352         local trunc_sz
23353         local grant_blk_size
23354
23355         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23356                         awk '/grant_block_size:/ { print $2; exit; }')
23357         #
23358         # Create File of size 5M. Truncate it to below size's and verify
23359         # blocks count.
23360         #
23361         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23362                 error "Create file $DIR/$tfile failed"
23363         stack_trap "rm -f $DIR/$tfile" EXIT
23364
23365         for trunc_sz in 2097152 4097 4000 509 0; do
23366                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23367                         error "truncate $tfile to $trunc_sz failed"
23368                 local sz=$(stat --format=%s $DIR/$tfile)
23369                 local blk=$(stat --format=%b $DIR/$tfile)
23370                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23371                                      grant_blk_size) * 8))
23372
23373                 if [[ $blk -ne $trunc_blk ]]; then
23374                         $(which stat) $DIR/$tfile
23375                         error "Expected Block $trunc_blk got $blk for $tfile"
23376                 fi
23377
23378                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23379                         error "Expected Size $trunc_sz got $sz for $tfile"
23380         done
23381
23382         #
23383         # sparse file test
23384         # Create file with a hole and write actual two blocks. Block count
23385         # must be 16.
23386         #
23387         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23388                 conv=fsync || error "Create file : $DIR/$tfile"
23389
23390         # Calculate the final truncate size.
23391         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23392
23393         #
23394         # truncate to size $trunc_sz bytes. Strip the last block
23395         # The block count must drop to 8
23396         #
23397         $TRUNCATE $DIR/$tfile $trunc_sz ||
23398                 error "truncate $tfile to $trunc_sz failed"
23399
23400         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23401         sz=$(stat --format=%s $DIR/$tfile)
23402         blk=$(stat --format=%b $DIR/$tfile)
23403
23404         if [[ $blk -ne $trunc_bsz ]]; then
23405                 $(which stat) $DIR/$tfile
23406                 error "Expected Block $trunc_bsz got $blk for $tfile"
23407         fi
23408
23409         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23410                 error "Expected Size $trunc_sz got $sz for $tfile"
23411 }
23412 run_test 317 "Verify blocks get correctly update after truncate"
23413
23414 test_318() {
23415         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23416         local old_max_active=$($LCTL get_param -n \
23417                             ${llite_name}.max_read_ahead_async_active \
23418                             2>/dev/null)
23419
23420         $LCTL set_param llite.*.max_read_ahead_async_active=256
23421         local max_active=$($LCTL get_param -n \
23422                            ${llite_name}.max_read_ahead_async_active \
23423                            2>/dev/null)
23424         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23425
23426         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23427                 error "set max_read_ahead_async_active should succeed"
23428
23429         $LCTL set_param llite.*.max_read_ahead_async_active=512
23430         max_active=$($LCTL get_param -n \
23431                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23432         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23433
23434         # restore @max_active
23435         [ $old_max_active -ne 0 ] && $LCTL set_param \
23436                 llite.*.max_read_ahead_async_active=$old_max_active
23437
23438         local old_threshold=$($LCTL get_param -n \
23439                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23440         local max_per_file_mb=$($LCTL get_param -n \
23441                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23442
23443         local invalid=$(($max_per_file_mb + 1))
23444         $LCTL set_param \
23445                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23446                         && error "set $invalid should fail"
23447
23448         local valid=$(($invalid - 1))
23449         $LCTL set_param \
23450                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23451                         error "set $valid should succeed"
23452         local threshold=$($LCTL get_param -n \
23453                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23454         [ $threshold -eq $valid ] || error \
23455                 "expect threshold $valid got $threshold"
23456         $LCTL set_param \
23457                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23458 }
23459 run_test 318 "Verify async readahead tunables"
23460
23461 test_319() {
23462         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23463
23464         local before=$(date +%s)
23465         local evict
23466         local mdir=$DIR/$tdir
23467         local file=$mdir/xxx
23468
23469         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23470         touch $file
23471
23472 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23473         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23474         $LFS mv -m1 $file &
23475
23476         sleep 1
23477         dd if=$file of=/dev/null
23478         wait
23479         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23480           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23481
23482         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23483 }
23484 run_test 319 "lost lease lock on migrate error"
23485
23486 test_398a() { # LU-4198
23487         local ost1_imp=$(get_osc_import_name client ost1)
23488         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23489                          cut -d'.' -f2)
23490
23491         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23492         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23493
23494         # request a new lock on client
23495         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23496
23497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23498         local lock_count=$($LCTL get_param -n \
23499                            ldlm.namespaces.$imp_name.lru_size)
23500         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23501
23502         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23503
23504         # no lock cached, should use lockless IO and not enqueue new lock
23505         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23506         lock_count=$($LCTL get_param -n \
23507                      ldlm.namespaces.$imp_name.lru_size)
23508         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23509 }
23510 run_test 398a "direct IO should cancel lock otherwise lockless"
23511
23512 test_398b() { # LU-4198
23513         which fio || skip_env "no fio installed"
23514         $LFS setstripe -c -1 $DIR/$tfile
23515
23516         local size=12
23517         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23518
23519         local njobs=4
23520         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23521         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23522                 --numjobs=$njobs --fallocate=none \
23523                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23524                 --filename=$DIR/$tfile &
23525         bg_pid=$!
23526
23527         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23528         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23529                 --numjobs=$njobs --fallocate=none \
23530                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23531                 --filename=$DIR/$tfile || true
23532         wait $bg_pid
23533
23534         rm -f $DIR/$tfile
23535 }
23536 run_test 398b "DIO and buffer IO race"
23537
23538 test_398c() { # LU-4198
23539         local ost1_imp=$(get_osc_import_name client ost1)
23540         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23541                          cut -d'.' -f2)
23542
23543         which fio || skip_env "no fio installed"
23544
23545         saved_debug=$($LCTL get_param -n debug)
23546         $LCTL set_param debug=0
23547
23548         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23549         ((size /= 1024)) # by megabytes
23550         ((size /= 2)) # write half of the OST at most
23551         [ $size -gt 40 ] && size=40 #reduce test time anyway
23552
23553         $LFS setstripe -c 1 $DIR/$tfile
23554
23555         # it seems like ldiskfs reserves more space than necessary if the
23556         # writing blocks are not mapped, so it extends the file firstly
23557         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23558         cancel_lru_locks osc
23559
23560         # clear and verify rpc_stats later
23561         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23562
23563         local njobs=4
23564         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23565         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23566                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23567                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23568                 --filename=$DIR/$tfile
23569         [ $? -eq 0 ] || error "fio write error"
23570
23571         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23572                 error "Locks were requested while doing AIO"
23573
23574         # get the percentage of 1-page I/O
23575         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23576                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23577                 awk '{print $7}')
23578         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23579
23580         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23581         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23582                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23583                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23584                 --filename=$DIR/$tfile
23585         [ $? -eq 0 ] || error "fio mixed read write error"
23586
23587         echo "AIO with large block size ${size}M"
23588         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23589                 --numjobs=1 --fallocate=none --ioengine=libaio \
23590                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23591                 --filename=$DIR/$tfile
23592         [ $? -eq 0 ] || error "fio large block size failed"
23593
23594         rm -f $DIR/$tfile
23595         $LCTL set_param debug="$saved_debug"
23596 }
23597 run_test 398c "run fio to test AIO"
23598
23599 test_398d() { #  LU-13846
23600         which aiocp || skip_env "no aiocp installed"
23601         local aio_file=$DIR/$tfile.aio
23602
23603         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23604
23605         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23606         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23607         stack_trap "rm -f $DIR/$tfile $aio_file"
23608
23609         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23610
23611         # make sure we don't crash and fail properly
23612         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23613                 error "aio not aligned with PAGE SIZE should fail"
23614
23615         rm -f $DIR/$tfile $aio_file
23616 }
23617 run_test 398d "run aiocp to verify block size > stripe size"
23618
23619 test_398e() {
23620         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23621         touch $DIR/$tfile.new
23622         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23623 }
23624 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23625
23626 test_398f() { #  LU-14687
23627         which aiocp || skip_env "no aiocp installed"
23628         local aio_file=$DIR/$tfile.aio
23629
23630         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23631
23632         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23633         stack_trap "rm -f $DIR/$tfile $aio_file"
23634
23635         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23636         $LCTL set_param fail_loc=0x1418
23637         # make sure we don't crash and fail properly
23638         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23639                 error "aio with page allocation failure succeeded"
23640         $LCTL set_param fail_loc=0
23641         diff $DIR/$tfile $aio_file
23642         [[ $? != 0 ]] || error "no diff after failed aiocp"
23643 }
23644 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23645
23646 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23647 # stripe and i/o size must be > stripe size
23648 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23649 # single RPC in flight.  This test shows async DIO submission is working by
23650 # showing multiple RPCs in flight.
23651 test_398g() { #  LU-13798
23652         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23653
23654         # We need to do some i/o first to acquire enough grant to put our RPCs
23655         # in flight; otherwise a new connection may not have enough grant
23656         # available
23657         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23658                 error "parallel dio failed"
23659         stack_trap "rm -f $DIR/$tfile"
23660
23661         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23662         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23663         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23664         stack_trap "$LCTL set_param -n $pages_per_rpc"
23665
23666         # Recreate file so it's empty
23667         rm -f $DIR/$tfile
23668         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23669         #Pause rpc completion to guarantee we see multiple rpcs in flight
23670         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23671         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23672         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23673
23674         # Clear rpc stats
23675         $LCTL set_param osc.*.rpc_stats=c
23676
23677         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23678                 error "parallel dio failed"
23679         stack_trap "rm -f $DIR/$tfile"
23680
23681         $LCTL get_param osc.*-OST0000-*.rpc_stats
23682         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23683                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23684                 grep "8:" | awk '{print $8}')
23685         # We look at the "8 rpcs in flight" field, and verify A) it is present
23686         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23687         # as expected for an 8M DIO to a file with 1M stripes.
23688         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23689
23690         # Verify turning off parallel dio works as expected
23691         # Clear rpc stats
23692         $LCTL set_param osc.*.rpc_stats=c
23693         $LCTL set_param llite.*.parallel_dio=0
23694         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23695
23696         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23697                 error "dio with parallel dio disabled failed"
23698
23699         # Ideally, we would see only one RPC in flight here, but there is an
23700         # unavoidable race between i/o completion and RPC in flight counting,
23701         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23702         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23703         # So instead we just verify it's always < 8.
23704         $LCTL get_param osc.*-OST0000-*.rpc_stats
23705         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23706                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23707                 grep '^$' -B1 | grep . | awk '{print $1}')
23708         [ $ret != "8:" ] ||
23709                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23710 }
23711 run_test 398g "verify parallel dio async RPC submission"
23712
23713 test_398h() { #  LU-13798
23714         local dio_file=$DIR/$tfile.dio
23715
23716         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23717
23718         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23719         stack_trap "rm -f $DIR/$tfile $dio_file"
23720
23721         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23722                 error "parallel dio failed"
23723         diff $DIR/$tfile $dio_file
23724         [[ $? == 0 ]] || error "file diff after aiocp"
23725 }
23726 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23727
23728 test_398i() { #  LU-13798
23729         local dio_file=$DIR/$tfile.dio
23730
23731         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23732
23733         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23734         stack_trap "rm -f $DIR/$tfile $dio_file"
23735
23736         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23737         $LCTL set_param fail_loc=0x1418
23738         # make sure we don't crash and fail properly
23739         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23740                 error "parallel dio page allocation failure succeeded"
23741         diff $DIR/$tfile $dio_file
23742         [[ $? != 0 ]] || error "no diff after failed aiocp"
23743 }
23744 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23745
23746 test_398j() { #  LU-13798
23747         # Stripe size > RPC size but less than i/o size tests split across
23748         # stripes and RPCs for individual i/o op
23749         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23750
23751         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23752         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23753         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23754         stack_trap "$LCTL set_param -n $pages_per_rpc"
23755
23756         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23757                 error "parallel dio write failed"
23758         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23759
23760         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23761                 error "parallel dio read failed"
23762         diff $DIR/$tfile $DIR/$tfile.2
23763         [[ $? == 0 ]] || error "file diff after parallel dio read"
23764 }
23765 run_test 398j "test parallel dio where stripe size > rpc_size"
23766
23767 test_398k() { #  LU-13798
23768         wait_delete_completed
23769         wait_mds_ost_sync
23770
23771         # 4 stripe file; we will cause out of space on OST0
23772         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23773
23774         # Fill OST0 (if it's not too large)
23775         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23776                    head -n1)
23777         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23778                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23779         fi
23780         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23781         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23782                 error "dd should fill OST0"
23783         stack_trap "rm -f $DIR/$tfile.1"
23784
23785         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23786         err=$?
23787
23788         ls -la $DIR/$tfile
23789         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23790                 error "file is not 0 bytes in size"
23791
23792         # dd above should not succeed, but don't error until here so we can
23793         # get debug info above
23794         [[ $err != 0 ]] ||
23795                 error "parallel dio write with enospc succeeded"
23796         stack_trap "rm -f $DIR/$tfile"
23797 }
23798 run_test 398k "test enospc on first stripe"
23799
23800 test_398l() { #  LU-13798
23801         wait_delete_completed
23802         wait_mds_ost_sync
23803
23804         # 4 stripe file; we will cause out of space on OST0
23805         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23806         # happens on the second i/o chunk we issue
23807         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23808
23809         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23810         stack_trap "rm -f $DIR/$tfile"
23811
23812         # Fill OST0 (if it's not too large)
23813         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23814                    head -n1)
23815         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23816                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23817         fi
23818         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23819         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23820                 error "dd should fill OST0"
23821         stack_trap "rm -f $DIR/$tfile.1"
23822
23823         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23824         err=$?
23825         stack_trap "rm -f $DIR/$tfile.2"
23826
23827         # Check that short write completed as expected
23828         ls -la $DIR/$tfile.2
23829         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23830                 error "file is not 1M in size"
23831
23832         # dd above should not succeed, but don't error until here so we can
23833         # get debug info above
23834         [[ $err != 0 ]] ||
23835                 error "parallel dio write with enospc succeeded"
23836
23837         # Truncate source file to same length as output file and diff them
23838         $TRUNCATE $DIR/$tfile 1048576
23839         diff $DIR/$tfile $DIR/$tfile.2
23840         [[ $? == 0 ]] || error "data incorrect after short write"
23841 }
23842 run_test 398l "test enospc on intermediate stripe/RPC"
23843
23844 test_398m() { #  LU-13798
23845         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23846
23847         lctl set_param *debug=-1 debug_mb=10000
23848
23849         # Set up failure on OST0, the first stripe:
23850         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23851         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23852         # So this fail_val specifies OST0
23853         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23854         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23855
23856         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23857                 error "parallel dio write with failure on first stripe succeeded"
23858         stack_trap "rm -f $DIR/$tfile"
23859         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23860
23861         # Place data in file for read
23862         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23863                 error "parallel dio write failed"
23864
23865         # Fail read on OST0, first stripe
23866         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23867         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
23868         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23869                 error "parallel dio read with error on first stripe succeeded"
23870         rm -f $DIR/$tfile.2
23871         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23872
23873         # Switch to testing on OST1, second stripe
23874         # Clear file contents, maintain striping
23875         echo > $DIR/$tfile
23876         # Set up failure on OST1, second stripe:
23877         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
23878         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23879
23880         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23881                 error "parallel dio write with failure on first stripe succeeded"
23882         stack_trap "rm -f $DIR/$tfile"
23883         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23884
23885         # Place data in file for read
23886         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23887                 error "parallel dio write failed"
23888
23889         # Fail read on OST1, second stripe
23890         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23891         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
23892         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23893                 error "parallel dio read with error on first stripe succeeded"
23894         rm -f $DIR/$tfile.2
23895         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
23896 }
23897 run_test 398m "test RPC failures with parallel dio"
23898
23899 # Parallel submission of DIO should not cause problems for append, but it's
23900 # important to verify.
23901 test_398n() { #  LU-13798
23902         $LFS setstripe -C 2 -S 1M $DIR/$tfile
23903
23904         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
23905                 error "dd to create source file failed"
23906         stack_trap "rm -f $DIR/$tfile"
23907
23908         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
23909                 error "parallel dio write with failure on second stripe succeeded"
23910         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
23911         diff $DIR/$tfile $DIR/$tfile.1
23912         [[ $? == 0 ]] || error "data incorrect after append"
23913
23914 }
23915 run_test 398n "test append with parallel DIO"
23916
23917 test_fake_rw() {
23918         local read_write=$1
23919         if [ "$read_write" = "write" ]; then
23920                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23921         elif [ "$read_write" = "read" ]; then
23922                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23923         else
23924                 error "argument error"
23925         fi
23926
23927         # turn off debug for performance testing
23928         local saved_debug=$($LCTL get_param -n debug)
23929         $LCTL set_param debug=0
23930
23931         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23932
23933         # get ost1 size - $FSNAME-OST0000
23934         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23935         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23936         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23937
23938         if [ "$read_write" = "read" ]; then
23939                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23940         fi
23941
23942         local start_time=$(date +%s.%N)
23943         $dd_cmd bs=1M count=$blocks oflag=sync ||
23944                 error "real dd $read_write error"
23945         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23946
23947         if [ "$read_write" = "write" ]; then
23948                 rm -f $DIR/$tfile
23949         fi
23950
23951         # define OBD_FAIL_OST_FAKE_RW           0x238
23952         do_facet ost1 $LCTL set_param fail_loc=0x238
23953
23954         local start_time=$(date +%s.%N)
23955         $dd_cmd bs=1M count=$blocks oflag=sync ||
23956                 error "fake dd $read_write error"
23957         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23958
23959         if [ "$read_write" = "write" ]; then
23960                 # verify file size
23961                 cancel_lru_locks osc
23962                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23963                         error "$tfile size not $blocks MB"
23964         fi
23965         do_facet ost1 $LCTL set_param fail_loc=0
23966
23967         echo "fake $read_write $duration_fake vs. normal $read_write" \
23968                 "$duration in seconds"
23969         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23970                 error_not_in_vm "fake write is slower"
23971
23972         $LCTL set_param -n debug="$saved_debug"
23973         rm -f $DIR/$tfile
23974 }
23975 test_399a() { # LU-7655 for OST fake write
23976         remote_ost_nodsh && skip "remote OST with nodsh"
23977
23978         test_fake_rw write
23979 }
23980 run_test 399a "fake write should not be slower than normal write"
23981
23982 test_399b() { # LU-8726 for OST fake read
23983         remote_ost_nodsh && skip "remote OST with nodsh"
23984         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23985                 skip_env "ldiskfs only test"
23986         fi
23987
23988         test_fake_rw read
23989 }
23990 run_test 399b "fake read should not be slower than normal read"
23991
23992 test_400a() { # LU-1606, was conf-sanity test_74
23993         if ! which $CC > /dev/null 2>&1; then
23994                 skip_env "$CC is not installed"
23995         fi
23996
23997         local extra_flags=''
23998         local out=$TMP/$tfile
23999         local prefix=/usr/include/lustre
24000         local prog
24001
24002         # Oleg removes c files in his test rig so test if any c files exist
24003         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24004                 skip_env "Needed c test files are missing"
24005
24006         if ! [[ -d $prefix ]]; then
24007                 # Assume we're running in tree and fixup the include path.
24008                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24009                 extra_flags+=" -L$LUSTRE/utils/.lib"
24010         fi
24011
24012         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24013                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24014                         error "client api broken"
24015         done
24016         rm -f $out
24017 }
24018 run_test 400a "Lustre client api program can compile and link"
24019
24020 test_400b() { # LU-1606, LU-5011
24021         local header
24022         local out=$TMP/$tfile
24023         local prefix=/usr/include/linux/lustre
24024
24025         # We use a hard coded prefix so that this test will not fail
24026         # when run in tree. There are headers in lustre/include/lustre/
24027         # that are not packaged (like lustre_idl.h) and have more
24028         # complicated include dependencies (like config.h and lnet/types.h).
24029         # Since this test about correct packaging we just skip them when
24030         # they don't exist (see below) rather than try to fixup cppflags.
24031
24032         if ! which $CC > /dev/null 2>&1; then
24033                 skip_env "$CC is not installed"
24034         fi
24035
24036         for header in $prefix/*.h; do
24037                 if ! [[ -f "$header" ]]; then
24038                         continue
24039                 fi
24040
24041                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24042                         continue # lustre_ioctl.h is internal header
24043                 fi
24044
24045                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24046                         error "cannot compile '$header'"
24047         done
24048         rm -f $out
24049 }
24050 run_test 400b "packaged headers can be compiled"
24051
24052 test_401a() { #LU-7437
24053         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24054         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24055
24056         #count the number of parameters by "list_param -R"
24057         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24058         #count the number of parameters by listing proc files
24059         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
24060         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24061         echo "proc_dirs='$proc_dirs'"
24062         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24063         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24064                       sort -u | wc -l)
24065
24066         [ $params -eq $procs ] ||
24067                 error "found $params parameters vs. $procs proc files"
24068
24069         # test the list_param -D option only returns directories
24070         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24071         #count the number of parameters by listing proc directories
24072         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24073                 sort -u | wc -l)
24074
24075         [ $params -eq $procs ] ||
24076                 error "found $params parameters vs. $procs proc files"
24077 }
24078 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24079
24080 test_401b() {
24081         # jobid_var may not allow arbitrary values, so use jobid_name
24082         # if available
24083         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24084                 local testname=jobid_name tmp='testing%p'
24085         else
24086                 local testname=jobid_var tmp=testing
24087         fi
24088
24089         local save=$($LCTL get_param -n $testname)
24090
24091         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24092                 error "no error returned when setting bad parameters"
24093
24094         local jobid_new=$($LCTL get_param -n foe $testname baz)
24095         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24096
24097         $LCTL set_param -n fog=bam $testname=$save bat=fog
24098         local jobid_old=$($LCTL get_param -n foe $testname bag)
24099         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24100 }
24101 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24102
24103 test_401c() {
24104         # jobid_var may not allow arbitrary values, so use jobid_name
24105         # if available
24106         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24107                 local testname=jobid_name
24108         else
24109                 local testname=jobid_var
24110         fi
24111
24112         local jobid_var_old=$($LCTL get_param -n $testname)
24113         local jobid_var_new
24114
24115         $LCTL set_param $testname= &&
24116                 error "no error returned for 'set_param a='"
24117
24118         jobid_var_new=$($LCTL get_param -n $testname)
24119         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24120                 error "$testname was changed by setting without value"
24121
24122         $LCTL set_param $testname &&
24123                 error "no error returned for 'set_param a'"
24124
24125         jobid_var_new=$($LCTL get_param -n $testname)
24126         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24127                 error "$testname was changed by setting without value"
24128 }
24129 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24130
24131 test_401d() {
24132         # jobid_var may not allow arbitrary values, so use jobid_name
24133         # if available
24134         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24135                 local testname=jobid_name new_value='foo=bar%p'
24136         else
24137                 local testname=jobid_var new_valuie=foo=bar
24138         fi
24139
24140         local jobid_var_old=$($LCTL get_param -n $testname)
24141         local jobid_var_new
24142
24143         $LCTL set_param $testname=$new_value ||
24144                 error "'set_param a=b' did not accept a value containing '='"
24145
24146         jobid_var_new=$($LCTL get_param -n $testname)
24147         [[ "$jobid_var_new" == "$new_value" ]] ||
24148                 error "'set_param a=b' failed on a value containing '='"
24149
24150         # Reset the $testname to test the other format
24151         $LCTL set_param $testname=$jobid_var_old
24152         jobid_var_new=$($LCTL get_param -n $testname)
24153         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24154                 error "failed to reset $testname"
24155
24156         $LCTL set_param $testname $new_value ||
24157                 error "'set_param a b' did not accept a value containing '='"
24158
24159         jobid_var_new=$($LCTL get_param -n $testname)
24160         [[ "$jobid_var_new" == "$new_value" ]] ||
24161                 error "'set_param a b' failed on a value containing '='"
24162
24163         $LCTL set_param $testname $jobid_var_old
24164         jobid_var_new=$($LCTL get_param -n $testname)
24165         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24166                 error "failed to reset $testname"
24167 }
24168 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24169
24170 test_401e() { # LU-14779
24171         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24172                 error "lctl list_param MGC* failed"
24173         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24174         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24175                 error "lctl get_param lru_size failed"
24176 }
24177 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24178
24179 test_402() {
24180         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24181         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24182                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24183         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24184                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24185                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24186         remote_mds_nodsh && skip "remote MDS with nodsh"
24187
24188         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24189 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24190         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24191         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24192                 echo "Touch failed - OK"
24193 }
24194 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24195
24196 test_403() {
24197         local file1=$DIR/$tfile.1
24198         local file2=$DIR/$tfile.2
24199         local tfile=$TMP/$tfile
24200
24201         rm -f $file1 $file2 $tfile
24202
24203         touch $file1
24204         ln $file1 $file2
24205
24206         # 30 sec OBD_TIMEOUT in ll_getattr()
24207         # right before populating st_nlink
24208         $LCTL set_param fail_loc=0x80001409
24209         stat -c %h $file1 > $tfile &
24210
24211         # create an alias, drop all locks and reclaim the dentry
24212         < $file2
24213         cancel_lru_locks mdc
24214         cancel_lru_locks osc
24215         sysctl -w vm.drop_caches=2
24216
24217         wait
24218
24219         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24220
24221         rm -f $tfile $file1 $file2
24222 }
24223 run_test 403 "i_nlink should not drop to zero due to aliasing"
24224
24225 test_404() { # LU-6601
24226         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24227                 skip "Need server version newer than 2.8.52"
24228         remote_mds_nodsh && skip "remote MDS with nodsh"
24229
24230         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24231                 awk '/osp .*-osc-MDT/ { print $4}')
24232
24233         local osp
24234         for osp in $mosps; do
24235                 echo "Deactivate: " $osp
24236                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24237                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24238                         awk -vp=$osp '$4 == p { print $2 }')
24239                 [ $stat = IN ] || {
24240                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24241                         error "deactivate error"
24242                 }
24243                 echo "Activate: " $osp
24244                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24245                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24246                         awk -vp=$osp '$4 == p { print $2 }')
24247                 [ $stat = UP ] || {
24248                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24249                         error "activate error"
24250                 }
24251         done
24252 }
24253 run_test 404 "validate manual {de}activated works properly for OSPs"
24254
24255 test_405() {
24256         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24257         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24258                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24259                         skip "Layout swap lock is not supported"
24260
24261         check_swap_layouts_support
24262         check_swap_layout_no_dom $DIR
24263
24264         test_mkdir $DIR/$tdir
24265         swap_lock_test -d $DIR/$tdir ||
24266                 error "One layout swap locked test failed"
24267 }
24268 run_test 405 "Various layout swap lock tests"
24269
24270 test_406() {
24271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24272         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24273         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24275         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24276                 skip "Need MDS version at least 2.8.50"
24277
24278         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24279         local test_pool=$TESTNAME
24280
24281         pool_add $test_pool || error "pool_add failed"
24282         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24283                 error "pool_add_targets failed"
24284
24285         save_layout_restore_at_exit $MOUNT
24286
24287         # parent set default stripe count only, child will stripe from both
24288         # parent and fs default
24289         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24290                 error "setstripe $MOUNT failed"
24291         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24292         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24293         for i in $(seq 10); do
24294                 local f=$DIR/$tdir/$tfile.$i
24295                 touch $f || error "touch failed"
24296                 local count=$($LFS getstripe -c $f)
24297                 [ $count -eq $OSTCOUNT ] ||
24298                         error "$f stripe count $count != $OSTCOUNT"
24299                 local offset=$($LFS getstripe -i $f)
24300                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24301                 local size=$($LFS getstripe -S $f)
24302                 [ $size -eq $((def_stripe_size * 2)) ] ||
24303                         error "$f stripe size $size != $((def_stripe_size * 2))"
24304                 local pool=$($LFS getstripe -p $f)
24305                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24306         done
24307
24308         # change fs default striping, delete parent default striping, now child
24309         # will stripe from new fs default striping only
24310         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24311                 error "change $MOUNT default stripe failed"
24312         $LFS setstripe -c 0 $DIR/$tdir ||
24313                 error "delete $tdir default stripe failed"
24314         for i in $(seq 11 20); do
24315                 local f=$DIR/$tdir/$tfile.$i
24316                 touch $f || error "touch $f failed"
24317                 local count=$($LFS getstripe -c $f)
24318                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24319                 local offset=$($LFS getstripe -i $f)
24320                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24321                 local size=$($LFS getstripe -S $f)
24322                 [ $size -eq $def_stripe_size ] ||
24323                         error "$f stripe size $size != $def_stripe_size"
24324                 local pool=$($LFS getstripe -p $f)
24325                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24326         done
24327
24328         unlinkmany $DIR/$tdir/$tfile. 1 20
24329
24330         local f=$DIR/$tdir/$tfile
24331         pool_remove_all_targets $test_pool $f
24332         pool_remove $test_pool $f
24333 }
24334 run_test 406 "DNE support fs default striping"
24335
24336 test_407() {
24337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24338         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24339                 skip "Need MDS version at least 2.8.55"
24340         remote_mds_nodsh && skip "remote MDS with nodsh"
24341
24342         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24343                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24344         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24345                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24346         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24347
24348         #define OBD_FAIL_DT_TXN_STOP    0x2019
24349         for idx in $(seq $MDSCOUNT); do
24350                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24351         done
24352         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24353         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24354                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24355         true
24356 }
24357 run_test 407 "transaction fail should cause operation fail"
24358
24359 test_408() {
24360         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24361
24362         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24363         lctl set_param fail_loc=0x8000040a
24364         # let ll_prepare_partial_page() fail
24365         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24366
24367         rm -f $DIR/$tfile
24368
24369         # create at least 100 unused inodes so that
24370         # shrink_icache_memory(0) should not return 0
24371         touch $DIR/$tfile-{0..100}
24372         rm -f $DIR/$tfile-{0..100}
24373         sync
24374
24375         echo 2 > /proc/sys/vm/drop_caches
24376 }
24377 run_test 408 "drop_caches should not hang due to page leaks"
24378
24379 test_409()
24380 {
24381         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24382
24383         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24384         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24385         touch $DIR/$tdir/guard || error "(2) Fail to create"
24386
24387         local PREFIX=$(str_repeat 'A' 128)
24388         echo "Create 1K hard links start at $(date)"
24389         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24390                 error "(3) Fail to hard link"
24391
24392         echo "Links count should be right although linkEA overflow"
24393         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24394         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24395         [ $linkcount -eq 1001 ] ||
24396                 error "(5) Unexpected hard links count: $linkcount"
24397
24398         echo "List all links start at $(date)"
24399         ls -l $DIR/$tdir/foo > /dev/null ||
24400                 error "(6) Fail to list $DIR/$tdir/foo"
24401
24402         echo "Unlink hard links start at $(date)"
24403         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24404                 error "(7) Fail to unlink"
24405         echo "Unlink hard links finished at $(date)"
24406 }
24407 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24408
24409 test_410()
24410 {
24411         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24412                 skip "Need client version at least 2.9.59"
24413         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24414                 skip "Need MODULES build"
24415
24416         # Create a file, and stat it from the kernel
24417         local testfile=$DIR/$tfile
24418         touch $testfile
24419
24420         local run_id=$RANDOM
24421         local my_ino=$(stat --format "%i" $testfile)
24422
24423         # Try to insert the module. This will always fail as the
24424         # module is designed to not be inserted.
24425         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24426             &> /dev/null
24427
24428         # Anything but success is a test failure
24429         dmesg | grep -q \
24430             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24431             error "no inode match"
24432 }
24433 run_test 410 "Test inode number returned from kernel thread"
24434
24435 cleanup_test411_cgroup() {
24436         trap 0
24437         rmdir "$1"
24438 }
24439
24440 test_411() {
24441         local cg_basedir=/sys/fs/cgroup/memory
24442         # LU-9966
24443         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24444                 skip "no setup for cgroup"
24445
24446         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24447                 error "test file creation failed"
24448         cancel_lru_locks osc
24449
24450         # Create a very small memory cgroup to force a slab allocation error
24451         local cgdir=$cg_basedir/osc_slab_alloc
24452         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24453         trap "cleanup_test411_cgroup $cgdir" EXIT
24454         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24455         echo 1M > $cgdir/memory.limit_in_bytes
24456
24457         # Should not LBUG, just be killed by oom-killer
24458         # dd will return 0 even allocation failure in some environment.
24459         # So don't check return value
24460         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24461         cleanup_test411_cgroup $cgdir
24462
24463         return 0
24464 }
24465 run_test 411 "Slab allocation error with cgroup does not LBUG"
24466
24467 test_412() {
24468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24469         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24470                 skip "Need server version at least 2.10.55"
24471         fi
24472
24473         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24474                 error "mkdir failed"
24475         $LFS getdirstripe $DIR/$tdir
24476         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24477         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24478                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24479         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24480         [ $stripe_count -eq 2 ] ||
24481                 error "expect 2 get $stripe_count"
24482 }
24483 run_test 412 "mkdir on specific MDTs"
24484
24485 test_qos_mkdir() {
24486         local mkdir_cmd=$1
24487         local stripe_count=$2
24488         local mdts=$(comma_list $(mdts_nodes))
24489
24490         local testdir
24491         local lmv_qos_prio_free
24492         local lmv_qos_threshold_rr
24493         local lmv_qos_maxage
24494         local lod_qos_prio_free
24495         local lod_qos_threshold_rr
24496         local lod_qos_maxage
24497         local count
24498         local i
24499
24500         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24501         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24502         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24503                 head -n1)
24504         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24505         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24506         stack_trap "$LCTL set_param \
24507                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24508         stack_trap "$LCTL set_param \
24509                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24510         stack_trap "$LCTL set_param \
24511                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24512
24513         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24514                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24515         lod_qos_prio_free=${lod_qos_prio_free%%%}
24516         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24517                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24518         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24519         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24520                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24521         stack_trap "do_nodes $mdts $LCTL set_param \
24522                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24523         stack_trap "do_nodes $mdts $LCTL set_param \
24524                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24525                 EXIT
24526         stack_trap "do_nodes $mdts $LCTL set_param \
24527                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24528
24529         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24530         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24531
24532         testdir=$DIR/$tdir-s$stripe_count/rr
24533
24534         local stripe_index=$($LFS getstripe -m $testdir)
24535         local test_mkdir_rr=true
24536
24537         getfattr -d -m dmv $testdir | grep dmv
24538         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24539                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24540
24541                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24542         fi
24543
24544         echo
24545         $test_mkdir_rr &&
24546                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24547                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24548
24549         for i in $(seq $((100 * MDSCOUNT))); do
24550                 eval $mkdir_cmd $testdir/subdir$i ||
24551                         error "$mkdir_cmd subdir$i failed"
24552         done
24553
24554         for i in $(seq $MDSCOUNT); do
24555                 count=$($LFS getdirstripe -i $testdir/* |
24556                                 grep ^$((i - 1))$ | wc -l)
24557                 echo "$count directories created on MDT$((i - 1))"
24558                 if $test_mkdir_rr; then
24559                         (( $count == 100 )) ||
24560                                 error "subdirs are not evenly distributed"
24561                 elif [ $((i - 1)) -eq $stripe_index ]; then
24562                         (( $count == 100 * MDSCOUNT )) ||
24563                                 error "$count subdirs created on MDT$((i - 1))"
24564                 else
24565                         (( $count == 0 )) ||
24566                                 error "$count subdirs created on MDT$((i - 1))"
24567                 fi
24568
24569                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24570                         count=$($LFS getdirstripe $testdir/* |
24571                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24572                         echo "$count stripes created on MDT$((i - 1))"
24573                         # deviation should < 5% of average
24574                         (( $count < 95 * stripe_count )) ||
24575                         (( $count > 105 * stripe_count)) &&
24576                                 error "stripes are not evenly distributed"
24577                 fi
24578         done
24579
24580         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24581         do_nodes $mdts $LCTL set_param \
24582                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24583
24584         echo
24585         echo "Check for uneven MDTs: "
24586
24587         local ffree
24588         local bavail
24589         local max
24590         local min
24591         local max_index
24592         local min_index
24593         local tmp
24594
24595         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24596         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24597         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24598
24599         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24600         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24601         max_index=0
24602         min_index=0
24603         for ((i = 1; i < ${#ffree[@]}; i++)); do
24604                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24605                 if [ $tmp -gt $max ]; then
24606                         max=$tmp
24607                         max_index=$i
24608                 fi
24609                 if [ $tmp -lt $min ]; then
24610                         min=$tmp
24611                         min_index=$i
24612                 fi
24613         done
24614
24615         (( ${ffree[min_index]} == 0 )) &&
24616                 skip "no free files in MDT$min_index"
24617         (( ${ffree[min_index]} > 100000000 )) &&
24618                 skip "too many free files in MDT$min_index"
24619
24620         # Check if we need to generate uneven MDTs
24621         local threshold=50
24622         local diff=$(((max - min) * 100 / min))
24623         local value="$(generate_string 1024)"
24624
24625         while [ $diff -lt $threshold ]; do
24626                 # generate uneven MDTs, create till $threshold% diff
24627                 echo -n "weight diff=$diff% must be > $threshold% ..."
24628                 count=$((${ffree[min_index]} / 10))
24629                 # 50 sec per 10000 files in vm
24630                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24631                         skip "$count files to create"
24632                 echo "Fill MDT$min_index with $count files"
24633                 [ -d $DIR/$tdir-MDT$min_index ] ||
24634                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24635                         error "mkdir $tdir-MDT$min_index failed"
24636                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24637                         error "create d$count failed"
24638
24639                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24640                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24641                 max=$(((${ffree[max_index]} >> 8) * \
24642                         (${bavail[max_index]} * bsize >> 16)))
24643                 min=$(((${ffree[min_index]} >> 8) * \
24644                         (${bavail[min_index]} * bsize >> 16)))
24645                 diff=$(((max - min) * 100 / min))
24646         done
24647
24648         echo "MDT filesfree available: ${ffree[@]}"
24649         echo "MDT blocks available: ${bavail[@]}"
24650         echo "weight diff=$diff%"
24651
24652         echo
24653         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24654
24655         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24656         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24657         # decrease statfs age, so that it can be updated in time
24658         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24659         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24660
24661         sleep 1
24662
24663         testdir=$DIR/$tdir-s$stripe_count/qos
24664
24665         for i in $(seq $((100 * MDSCOUNT))); do
24666                 eval $mkdir_cmd $testdir/subdir$i ||
24667                         error "$mkdir_cmd subdir$i failed"
24668         done
24669
24670         for i in $(seq $MDSCOUNT); do
24671                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24672                         wc -l)
24673                 echo "$count directories created on MDT$((i - 1))"
24674
24675                 if [ $stripe_count -gt 1 ]; then
24676                         count=$($LFS getdirstripe $testdir/* |
24677                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24678                         echo "$count stripes created on MDT$((i - 1))"
24679                 fi
24680         done
24681
24682         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24683         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24684
24685         # D-value should > 10% of averge
24686         (( $max - $min < 10 )) &&
24687                 error "subdirs shouldn't be evenly distributed"
24688
24689         # ditto
24690         if [ $stripe_count -gt 1 ]; then
24691                 max=$($LFS getdirstripe $testdir/* |
24692                         grep -P "^\s+$max_index\t" | wc -l)
24693                 min=$($LFS getdirstripe $testdir/* |
24694                         grep -P "^\s+$min_index\t" | wc -l)
24695                 (( $max - $min < 10 * $stripe_count )) &&
24696                         error "stripes shouldn't be evenly distributed"|| true
24697         fi
24698 }
24699
24700 test_413a() {
24701         [ $MDSCOUNT -lt 2 ] &&
24702                 skip "We need at least 2 MDTs for this test"
24703
24704         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24705                 skip "Need server version at least 2.12.52"
24706
24707         local stripe_count
24708
24709         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24710                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24711                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24712                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24713                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24714         done
24715 }
24716 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24717
24718 test_413b() {
24719         [ $MDSCOUNT -lt 2 ] &&
24720                 skip "We need at least 2 MDTs for this test"
24721
24722         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24723                 skip "Need server version at least 2.12.52"
24724
24725         local testdir
24726         local stripe_count
24727
24728         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24729                 testdir=$DIR/$tdir-s$stripe_count
24730                 mkdir $testdir || error "mkdir $testdir failed"
24731                 mkdir $testdir/rr || error "mkdir rr failed"
24732                 mkdir $testdir/qos || error "mkdir qos failed"
24733                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24734                         $testdir/rr || error "setdirstripe rr failed"
24735                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24736                         error "setdirstripe failed"
24737                 test_qos_mkdir "mkdir" $stripe_count
24738         done
24739 }
24740 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24741
24742 test_413c() {
24743         [ $MDSCOUNT -ge 2 ] ||
24744                 skip "We need at least 2 MDTs for this test"
24745
24746         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24747                 skip "Need server version at least 2.14.50"
24748
24749         local testdir
24750         local inherit
24751         local inherit_rr
24752
24753         testdir=$DIR/${tdir}-s1
24754         mkdir $testdir || error "mkdir $testdir failed"
24755         mkdir $testdir/rr || error "mkdir rr failed"
24756         mkdir $testdir/qos || error "mkdir qos failed"
24757         # default max_inherit is -1, default max_inherit_rr is 0
24758         $LFS setdirstripe -D -c 1 $testdir/rr ||
24759                 error "setdirstripe rr failed"
24760         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24761                 error "setdirstripe qos failed"
24762         test_qos_mkdir "mkdir" 1
24763
24764         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24765         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24766         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24767         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24768         (( $inherit_rr == 0 )) ||
24769                 error "rr/level1 inherit-rr $inherit_rr != 0"
24770
24771         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24772         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24773         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24774         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24775         (( $inherit_rr == 0 )) ||
24776                 error "qos/level1 inherit-rr $inherit_rr !=0"
24777         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24778         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24779                 error "level2 shouldn't have default LMV" || true
24780 }
24781 run_test 413c "mkdir with default LMV max inherit rr"
24782
24783 test_414() {
24784 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24785         $LCTL set_param fail_loc=0x80000521
24786         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24787         rm -f $DIR/$tfile
24788 }
24789 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24790
24791 test_415() {
24792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24793         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24794                 skip "Need server version at least 2.11.52"
24795
24796         # LU-11102
24797         local total
24798         local setattr_pid
24799         local start_time
24800         local end_time
24801         local duration
24802
24803         total=500
24804         # this test may be slow on ZFS
24805         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24806
24807         # though this test is designed for striped directory, let's test normal
24808         # directory too since lock is always saved as CoS lock.
24809         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24810         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24811
24812         (
24813                 while true; do
24814                         touch $DIR/$tdir
24815                 done
24816         ) &
24817         setattr_pid=$!
24818
24819         start_time=$(date +%s)
24820         for i in $(seq $total); do
24821                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24822                         > /dev/null
24823         done
24824         end_time=$(date +%s)
24825         duration=$((end_time - start_time))
24826
24827         kill -9 $setattr_pid
24828
24829         echo "rename $total files took $duration sec"
24830         [ $duration -lt 100 ] || error "rename took $duration sec"
24831 }
24832 run_test 415 "lock revoke is not missing"
24833
24834 test_416() {
24835         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24836                 skip "Need server version at least 2.11.55"
24837
24838         # define OBD_FAIL_OSD_TXN_START    0x19a
24839         do_facet mds1 lctl set_param fail_loc=0x19a
24840
24841         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24842
24843         true
24844 }
24845 run_test 416 "transaction start failure won't cause system hung"
24846
24847 cleanup_417() {
24848         trap 0
24849         do_nodes $(comma_list $(mdts_nodes)) \
24850                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24851         do_nodes $(comma_list $(mdts_nodes)) \
24852                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24853         do_nodes $(comma_list $(mdts_nodes)) \
24854                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24855 }
24856
24857 test_417() {
24858         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24859         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24860                 skip "Need MDS version at least 2.11.56"
24861
24862         trap cleanup_417 RETURN EXIT
24863
24864         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24865         do_nodes $(comma_list $(mdts_nodes)) \
24866                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24867         $LFS migrate -m 0 $DIR/$tdir.1 &&
24868                 error "migrate dir $tdir.1 should fail"
24869
24870         do_nodes $(comma_list $(mdts_nodes)) \
24871                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24872         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24873                 error "create remote dir $tdir.2 should fail"
24874
24875         do_nodes $(comma_list $(mdts_nodes)) \
24876                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24877         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24878                 error "create striped dir $tdir.3 should fail"
24879         true
24880 }
24881 run_test 417 "disable remote dir, striped dir and dir migration"
24882
24883 # Checks that the outputs of df [-i] and lfs df [-i] match
24884 #
24885 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24886 check_lfs_df() {
24887         local dir=$2
24888         local inodes
24889         local df_out
24890         local lfs_df_out
24891         local count
24892         local passed=false
24893
24894         # blocks or inodes
24895         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24896
24897         for count in {1..100}; do
24898                 cancel_lru_locks
24899                 sync; sleep 0.2
24900
24901                 # read the lines of interest
24902                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24903                         error "df $inodes $dir | tail -n +2 failed"
24904                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24905                         error "lfs df $inodes $dir | grep summary: failed"
24906
24907                 # skip first substrings of each output as they are different
24908                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24909                 # compare the two outputs
24910                 passed=true
24911                 for i in {1..5}; do
24912                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24913                 done
24914                 $passed && break
24915         done
24916
24917         if ! $passed; then
24918                 df -P $inodes $dir
24919                 echo
24920                 lfs df $inodes $dir
24921                 error "df and lfs df $1 output mismatch: "      \
24922                       "df ${inodes}: ${df_out[*]}, "            \
24923                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24924         fi
24925 }
24926
24927 test_418() {
24928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24929
24930         local dir=$DIR/$tdir
24931         local numfiles=$((RANDOM % 4096 + 2))
24932         local numblocks=$((RANDOM % 256 + 1))
24933
24934         wait_delete_completed
24935         test_mkdir $dir
24936
24937         # check block output
24938         check_lfs_df blocks $dir
24939         # check inode output
24940         check_lfs_df inodes $dir
24941
24942         # create a single file and retest
24943         echo "Creating a single file and testing"
24944         createmany -o $dir/$tfile- 1 &>/dev/null ||
24945                 error "creating 1 file in $dir failed"
24946         check_lfs_df blocks $dir
24947         check_lfs_df inodes $dir
24948
24949         # create a random number of files
24950         echo "Creating $((numfiles - 1)) files and testing"
24951         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24952                 error "creating $((numfiles - 1)) files in $dir failed"
24953
24954         # write a random number of blocks to the first test file
24955         echo "Writing $numblocks 4K blocks and testing"
24956         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24957                 count=$numblocks &>/dev/null ||
24958                 error "dd to $dir/${tfile}-0 failed"
24959
24960         # retest
24961         check_lfs_df blocks $dir
24962         check_lfs_df inodes $dir
24963
24964         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24965                 error "unlinking $numfiles files in $dir failed"
24966 }
24967 run_test 418 "df and lfs df outputs match"
24968
24969 test_419()
24970 {
24971         local dir=$DIR/$tdir
24972
24973         mkdir -p $dir
24974         touch $dir/file
24975
24976         cancel_lru_locks mdc
24977
24978         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24979         $LCTL set_param fail_loc=0x1410
24980         cat $dir/file
24981         $LCTL set_param fail_loc=0
24982         rm -rf $dir
24983 }
24984 run_test 419 "Verify open file by name doesn't crash kernel"
24985
24986 test_420()
24987 {
24988         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24989                 skip "Need MDS version at least 2.12.53"
24990
24991         local SAVE_UMASK=$(umask)
24992         local dir=$DIR/$tdir
24993         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24994
24995         mkdir -p $dir
24996         umask 0000
24997         mkdir -m03777 $dir/testdir
24998         ls -dn $dir/testdir
24999         # Need to remove trailing '.' when SELinux is enabled
25000         local dirperms=$(ls -dn $dir/testdir |
25001                          awk '{ sub(/\.$/, "", $1); print $1}')
25002         [ $dirperms == "drwxrwsrwt" ] ||
25003                 error "incorrect perms on $dir/testdir"
25004
25005         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25006                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25007         ls -n $dir/testdir/testfile
25008         local fileperms=$(ls -n $dir/testdir/testfile |
25009                           awk '{ sub(/\.$/, "", $1); print $1}')
25010         [ $fileperms == "-rwxr-xr-x" ] ||
25011                 error "incorrect perms on $dir/testdir/testfile"
25012
25013         umask $SAVE_UMASK
25014 }
25015 run_test 420 "clear SGID bit on non-directories for non-members"
25016
25017 test_421a() {
25018         local cnt
25019         local fid1
25020         local fid2
25021
25022         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25023                 skip "Need MDS version at least 2.12.54"
25024
25025         test_mkdir $DIR/$tdir
25026         createmany -o $DIR/$tdir/f 3
25027         cnt=$(ls -1 $DIR/$tdir | wc -l)
25028         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25029
25030         fid1=$(lfs path2fid $DIR/$tdir/f1)
25031         fid2=$(lfs path2fid $DIR/$tdir/f2)
25032         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25033
25034         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25035         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25036
25037         cnt=$(ls -1 $DIR/$tdir | wc -l)
25038         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25039
25040         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25041         createmany -o $DIR/$tdir/f 3
25042         cnt=$(ls -1 $DIR/$tdir | wc -l)
25043         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25044
25045         fid1=$(lfs path2fid $DIR/$tdir/f1)
25046         fid2=$(lfs path2fid $DIR/$tdir/f2)
25047         echo "remove using fsname $FSNAME"
25048         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25049
25050         cnt=$(ls -1 $DIR/$tdir | wc -l)
25051         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25052 }
25053 run_test 421a "simple rm by fid"
25054
25055 test_421b() {
25056         local cnt
25057         local FID1
25058         local FID2
25059
25060         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25061                 skip "Need MDS version at least 2.12.54"
25062
25063         test_mkdir $DIR/$tdir
25064         createmany -o $DIR/$tdir/f 3
25065         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25066         MULTIPID=$!
25067
25068         FID1=$(lfs path2fid $DIR/$tdir/f1)
25069         FID2=$(lfs path2fid $DIR/$tdir/f2)
25070         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25071
25072         kill -USR1 $MULTIPID
25073         wait
25074
25075         cnt=$(ls $DIR/$tdir | wc -l)
25076         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25077 }
25078 run_test 421b "rm by fid on open file"
25079
25080 test_421c() {
25081         local cnt
25082         local FIDS
25083
25084         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25085                 skip "Need MDS version at least 2.12.54"
25086
25087         test_mkdir $DIR/$tdir
25088         createmany -o $DIR/$tdir/f 3
25089         touch $DIR/$tdir/$tfile
25090         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25091         cnt=$(ls -1 $DIR/$tdir | wc -l)
25092         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25093
25094         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25095         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25096
25097         cnt=$(ls $DIR/$tdir | wc -l)
25098         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25099 }
25100 run_test 421c "rm by fid against hardlinked files"
25101
25102 test_421d() {
25103         local cnt
25104         local FIDS
25105
25106         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25107                 skip "Need MDS version at least 2.12.54"
25108
25109         test_mkdir $DIR/$tdir
25110         createmany -o $DIR/$tdir/f 4097
25111         cnt=$(ls -1 $DIR/$tdir | wc -l)
25112         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25113
25114         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25115         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25116
25117         cnt=$(ls $DIR/$tdir | wc -l)
25118         rm -rf $DIR/$tdir
25119         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25120 }
25121 run_test 421d "rmfid en masse"
25122
25123 test_421e() {
25124         local cnt
25125         local FID
25126
25127         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25128         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25129                 skip "Need MDS version at least 2.12.54"
25130
25131         mkdir -p $DIR/$tdir
25132         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25133         createmany -o $DIR/$tdir/striped_dir/f 512
25134         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25135         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25136
25137         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25138                 sed "s/[/][^:]*://g")
25139         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25140
25141         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25142         rm -rf $DIR/$tdir
25143         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25144 }
25145 run_test 421e "rmfid in DNE"
25146
25147 test_421f() {
25148         local cnt
25149         local FID
25150
25151         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25152                 skip "Need MDS version at least 2.12.54"
25153
25154         test_mkdir $DIR/$tdir
25155         touch $DIR/$tdir/f
25156         cnt=$(ls -1 $DIR/$tdir | wc -l)
25157         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25158
25159         FID=$(lfs path2fid $DIR/$tdir/f)
25160         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25161         # rmfid should fail
25162         cnt=$(ls -1 $DIR/$tdir | wc -l)
25163         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25164
25165         chmod a+rw $DIR/$tdir
25166         ls -la $DIR/$tdir
25167         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25168         # rmfid should fail
25169         cnt=$(ls -1 $DIR/$tdir | wc -l)
25170         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25171
25172         rm -f $DIR/$tdir/f
25173         $RUNAS touch $DIR/$tdir/f
25174         FID=$(lfs path2fid $DIR/$tdir/f)
25175         echo "rmfid as root"
25176         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25177         cnt=$(ls -1 $DIR/$tdir | wc -l)
25178         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25179
25180         rm -f $DIR/$tdir/f
25181         $RUNAS touch $DIR/$tdir/f
25182         cnt=$(ls -1 $DIR/$tdir | wc -l)
25183         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25184         FID=$(lfs path2fid $DIR/$tdir/f)
25185         # rmfid w/o user_fid2path mount option should fail
25186         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25187         cnt=$(ls -1 $DIR/$tdir | wc -l)
25188         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25189
25190         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25191         stack_trap "rmdir $tmpdir"
25192         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25193                 error "failed to mount client'"
25194         stack_trap "umount_client $tmpdir"
25195
25196         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25197         # rmfid should succeed
25198         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25199         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25200
25201         # rmfid shouldn't allow to remove files due to dir's permission
25202         chmod a+rwx $tmpdir/$tdir
25203         touch $tmpdir/$tdir/f
25204         ls -la $tmpdir/$tdir
25205         FID=$(lfs path2fid $tmpdir/$tdir/f)
25206         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25207         return 0
25208 }
25209 run_test 421f "rmfid checks permissions"
25210
25211 test_421g() {
25212         local cnt
25213         local FIDS
25214
25215         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25216         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25217                 skip "Need MDS version at least 2.12.54"
25218
25219         mkdir -p $DIR/$tdir
25220         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25221         createmany -o $DIR/$tdir/striped_dir/f 512
25222         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25223         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25224
25225         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25226                 sed "s/[/][^:]*://g")
25227
25228         rm -f $DIR/$tdir/striped_dir/f1*
25229         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25230         removed=$((512 - cnt))
25231
25232         # few files have been just removed, so we expect
25233         # rmfid to fail on their fids
25234         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25235         [ $removed != $errors ] && error "$errors != $removed"
25236
25237         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25238         rm -rf $DIR/$tdir
25239         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25240 }
25241 run_test 421g "rmfid to return errors properly"
25242
25243 test_422() {
25244         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25245         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25246         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25247         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25248         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25249
25250         local amc=$(at_max_get client)
25251         local amo=$(at_max_get mds1)
25252         local timeout=`lctl get_param -n timeout`
25253
25254         at_max_set 0 client
25255         at_max_set 0 mds1
25256
25257 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25258         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25259                         fail_val=$(((2*timeout + 10)*1000))
25260         touch $DIR/$tdir/d3/file &
25261         sleep 2
25262 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25263         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25264                         fail_val=$((2*timeout + 5))
25265         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25266         local pid=$!
25267         sleep 1
25268         kill -9 $pid
25269         sleep $((2 * timeout))
25270         echo kill $pid
25271         kill -9 $pid
25272         lctl mark touch
25273         touch $DIR/$tdir/d2/file3
25274         touch $DIR/$tdir/d2/file4
25275         touch $DIR/$tdir/d2/file5
25276
25277         wait
25278         at_max_set $amc client
25279         at_max_set $amo mds1
25280
25281         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25282         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25283                 error "Watchdog is always throttled"
25284 }
25285 run_test 422 "kill a process with RPC in progress"
25286
25287 stat_test() {
25288     df -h $MOUNT &
25289     df -h $MOUNT &
25290     df -h $MOUNT &
25291     df -h $MOUNT &
25292     df -h $MOUNT &
25293     df -h $MOUNT &
25294 }
25295
25296 test_423() {
25297     local _stats
25298     # ensure statfs cache is expired
25299     sleep 2;
25300
25301     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25302     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25303
25304     return 0
25305 }
25306 run_test 423 "statfs should return a right data"
25307
25308 test_424() {
25309 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25310         $LCTL set_param fail_loc=0x80000522
25311         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25312         rm -f $DIR/$tfile
25313 }
25314 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25315
25316 test_425() {
25317         test_mkdir -c -1 $DIR/$tdir
25318         $LFS setstripe -c -1 $DIR/$tdir
25319
25320         lru_resize_disable "" 100
25321         stack_trap "lru_resize_enable" EXIT
25322
25323         sleep 5
25324
25325         for i in $(seq $((MDSCOUNT * 125))); do
25326                 local t=$DIR/$tdir/$tfile_$i
25327
25328                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25329                         error_noexit "Create file $t"
25330         done
25331         stack_trap "rm -rf $DIR/$tdir" EXIT
25332
25333         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25334                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25335                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25336
25337                 [ $lock_count -le $lru_size ] ||
25338                         error "osc lock count $lock_count > lru size $lru_size"
25339         done
25340
25341         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25342                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25343                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25344
25345                 [ $lock_count -le $lru_size ] ||
25346                         error "mdc lock count $lock_count > lru size $lru_size"
25347         done
25348 }
25349 run_test 425 "lock count should not exceed lru size"
25350
25351 test_426() {
25352         splice-test -r $DIR/$tfile
25353         splice-test -rd $DIR/$tfile
25354         splice-test $DIR/$tfile
25355         splice-test -d $DIR/$tfile
25356 }
25357 run_test 426 "splice test on Lustre"
25358
25359 test_427() {
25360         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25361         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25362                 skip "Need MDS version at least 2.12.4"
25363         local log
25364
25365         mkdir $DIR/$tdir
25366         mkdir $DIR/$tdir/1
25367         mkdir $DIR/$tdir/2
25368         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25369         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25370
25371         $LFS getdirstripe $DIR/$tdir/1/dir
25372
25373         #first setfattr for creating updatelog
25374         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25375
25376 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25377         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25378         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25379         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25380
25381         sleep 2
25382         fail mds2
25383         wait_recovery_complete mds2 $((2*TIMEOUT))
25384
25385         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25386         echo $log | grep "get update log failed" &&
25387                 error "update log corruption is detected" || true
25388 }
25389 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25390
25391 test_428() {
25392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25393         local cache_limit=$CACHE_MAX
25394
25395         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25396         $LCTL set_param -n llite.*.max_cached_mb=64
25397
25398         mkdir $DIR/$tdir
25399         $LFS setstripe -c 1 $DIR/$tdir
25400         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25401         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25402         #test write
25403         for f in $(seq 4); do
25404                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25405         done
25406         wait
25407
25408         cancel_lru_locks osc
25409         # Test read
25410         for f in $(seq 4); do
25411                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25412         done
25413         wait
25414 }
25415 run_test 428 "large block size IO should not hang"
25416
25417 test_429() { # LU-7915 / LU-10948
25418         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25419         local testfile=$DIR/$tfile
25420         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25421         local new_flag=1
25422         local first_rpc
25423         local second_rpc
25424         local third_rpc
25425
25426         $LCTL get_param $ll_opencache_threshold_count ||
25427                 skip "client does not have opencache parameter"
25428
25429         set_opencache $new_flag
25430         stack_trap "restore_opencache"
25431         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25432                 error "enable opencache failed"
25433         touch $testfile
25434         # drop MDC DLM locks
25435         cancel_lru_locks mdc
25436         # clear MDC RPC stats counters
25437         $LCTL set_param $mdc_rpcstats=clear
25438
25439         # According to the current implementation, we need to run 3 times
25440         # open & close file to verify if opencache is enabled correctly.
25441         # 1st, RPCs are sent for lookup/open and open handle is released on
25442         #      close finally.
25443         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25444         #      so open handle won't be released thereafter.
25445         # 3rd, No RPC is sent out.
25446         $MULTIOP $testfile oc || error "multiop failed"
25447         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25448         echo "1st: $first_rpc RPCs in flight"
25449
25450         $MULTIOP $testfile oc || error "multiop failed"
25451         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25452         echo "2nd: $second_rpc RPCs in flight"
25453
25454         $MULTIOP $testfile oc || error "multiop failed"
25455         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25456         echo "3rd: $third_rpc RPCs in flight"
25457
25458         #verify no MDC RPC is sent
25459         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25460 }
25461 run_test 429 "verify if opencache flag on client side does work"
25462
25463 lseek_test_430() {
25464         local offset
25465         local file=$1
25466
25467         # data at [200K, 400K)
25468         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25469                 error "256K->512K dd fails"
25470         # data at [2M, 3M)
25471         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25472                 error "2M->3M dd fails"
25473         # data at [4M, 5M)
25474         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25475                 error "4M->5M dd fails"
25476         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25477         # start at first component hole #1
25478         printf "Seeking hole from 1000 ... "
25479         offset=$(lseek_test -l 1000 $file)
25480         echo $offset
25481         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25482         printf "Seeking data from 1000 ... "
25483         offset=$(lseek_test -d 1000 $file)
25484         echo $offset
25485         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25486
25487         # start at first component data block
25488         printf "Seeking hole from 300000 ... "
25489         offset=$(lseek_test -l 300000 $file)
25490         echo $offset
25491         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25492         printf "Seeking data from 300000 ... "
25493         offset=$(lseek_test -d 300000 $file)
25494         echo $offset
25495         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25496
25497         # start at the first component but beyond end of object size
25498         printf "Seeking hole from 1000000 ... "
25499         offset=$(lseek_test -l 1000000 $file)
25500         echo $offset
25501         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25502         printf "Seeking data from 1000000 ... "
25503         offset=$(lseek_test -d 1000000 $file)
25504         echo $offset
25505         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25506
25507         # start at second component stripe 2 (empty file)
25508         printf "Seeking hole from 1500000 ... "
25509         offset=$(lseek_test -l 1500000 $file)
25510         echo $offset
25511         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25512         printf "Seeking data from 1500000 ... "
25513         offset=$(lseek_test -d 1500000 $file)
25514         echo $offset
25515         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25516
25517         # start at second component stripe 1 (all data)
25518         printf "Seeking hole from 3000000 ... "
25519         offset=$(lseek_test -l 3000000 $file)
25520         echo $offset
25521         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25522         printf "Seeking data from 3000000 ... "
25523         offset=$(lseek_test -d 3000000 $file)
25524         echo $offset
25525         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25526
25527         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25528                 error "2nd dd fails"
25529         echo "Add data block at 640K...1280K"
25530
25531         # start at before new data block, in hole
25532         printf "Seeking hole from 600000 ... "
25533         offset=$(lseek_test -l 600000 $file)
25534         echo $offset
25535         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25536         printf "Seeking data from 600000 ... "
25537         offset=$(lseek_test -d 600000 $file)
25538         echo $offset
25539         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25540
25541         # start at the first component new data block
25542         printf "Seeking hole from 1000000 ... "
25543         offset=$(lseek_test -l 1000000 $file)
25544         echo $offset
25545         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25546         printf "Seeking data from 1000000 ... "
25547         offset=$(lseek_test -d 1000000 $file)
25548         echo $offset
25549         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25550
25551         # start at second component stripe 2, new data
25552         printf "Seeking hole from 1200000 ... "
25553         offset=$(lseek_test -l 1200000 $file)
25554         echo $offset
25555         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25556         printf "Seeking data from 1200000 ... "
25557         offset=$(lseek_test -d 1200000 $file)
25558         echo $offset
25559         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25560
25561         # start beyond file end
25562         printf "Using offset > filesize ... "
25563         lseek_test -l 4000000 $file && error "lseek should fail"
25564         printf "Using offset > filesize ... "
25565         lseek_test -d 4000000 $file && error "lseek should fail"
25566
25567         printf "Done\n\n"
25568 }
25569
25570 test_430a() {
25571         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25572                 skip "MDT does not support SEEK_HOLE"
25573
25574         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25575                 skip "OST does not support SEEK_HOLE"
25576
25577         local file=$DIR/$tdir/$tfile
25578
25579         mkdir -p $DIR/$tdir
25580
25581         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25582         # OST stripe #1 will have continuous data at [1M, 3M)
25583         # OST stripe #2 is empty
25584         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25585         lseek_test_430 $file
25586         rm $file
25587         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25588         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25589         lseek_test_430 $file
25590         rm $file
25591         $LFS setstripe -c2 -S 512K $file
25592         echo "Two stripes, stripe size 512K"
25593         lseek_test_430 $file
25594         rm $file
25595         # FLR with stale mirror
25596         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25597                        -N -c2 -S 1M $file
25598         echo "Mirrored file:"
25599         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25600         echo "Plain 2 stripes 1M"
25601         lseek_test_430 $file
25602         rm $file
25603 }
25604 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25605
25606 test_430b() {
25607         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25608                 skip "OST does not support SEEK_HOLE"
25609
25610         local offset
25611         local file=$DIR/$tdir/$tfile
25612
25613         mkdir -p $DIR/$tdir
25614         # Empty layout lseek should fail
25615         $MCREATE $file
25616         # seek from 0
25617         printf "Seeking hole from 0 ... "
25618         lseek_test -l 0 $file && error "lseek should fail"
25619         printf "Seeking data from 0 ... "
25620         lseek_test -d 0 $file && error "lseek should fail"
25621         rm $file
25622
25623         # 1M-hole file
25624         $LFS setstripe -E 1M -c2 -E eof $file
25625         $TRUNCATE $file 1048576
25626         printf "Seeking hole from 1000000 ... "
25627         offset=$(lseek_test -l 1000000 $file)
25628         echo $offset
25629         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25630         printf "Seeking data from 1000000 ... "
25631         lseek_test -d 1000000 $file && error "lseek should fail"
25632         rm $file
25633
25634         # full component followed by non-inited one
25635         $LFS setstripe -E 1M -c2 -E eof $file
25636         dd if=/dev/urandom of=$file bs=1M count=1
25637         printf "Seeking hole from 1000000 ... "
25638         offset=$(lseek_test -l 1000000 $file)
25639         echo $offset
25640         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25641         printf "Seeking hole from 1048576 ... "
25642         lseek_test -l 1048576 $file && error "lseek should fail"
25643         # init second component and truncate back
25644         echo "123" >> $file
25645         $TRUNCATE $file 1048576
25646         printf "Seeking hole from 1000000 ... "
25647         offset=$(lseek_test -l 1000000 $file)
25648         echo $offset
25649         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25650         printf "Seeking hole from 1048576 ... "
25651         lseek_test -l 1048576 $file && error "lseek should fail"
25652         # boundary checks for big values
25653         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25654         offset=$(lseek_test -d 0 $file.10g)
25655         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25656         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25657         offset=$(lseek_test -d 0 $file.100g)
25658         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25659         return 0
25660 }
25661 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25662
25663 test_430c() {
25664         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25665                 skip "OST does not support SEEK_HOLE"
25666
25667         local file=$DIR/$tdir/$tfile
25668         local start
25669
25670         mkdir -p $DIR/$tdir
25671         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25672
25673         # cp version 8.33+ prefers lseek over fiemap
25674         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25675                 start=$SECONDS
25676                 time cp $file /dev/null
25677                 (( SECONDS - start < 5 )) ||
25678                         error "cp: too long runtime $((SECONDS - start))"
25679
25680         fi
25681         # tar version 1.29+ supports SEEK_HOLE/DATA
25682         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25683                 start=$SECONDS
25684                 time tar cS $file - | cat > /dev/null
25685                 (( SECONDS - start < 5 )) ||
25686                         error "tar: too long runtime $((SECONDS - start))"
25687         fi
25688 }
25689 run_test 430c "lseek: external tools check"
25690
25691 test_431() { # LU-14187
25692         local file=$DIR/$tdir/$tfile
25693
25694         mkdir -p $DIR/$tdir
25695         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25696         dd if=/dev/urandom of=$file bs=4k count=1
25697         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25698         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25699         #define OBD_FAIL_OST_RESTART_IO 0x251
25700         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25701         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25702         cp $file $file.0
25703         cancel_lru_locks
25704         sync_all_data
25705         echo 3 > /proc/sys/vm/drop_caches
25706         diff  $file $file.0 || error "data diff"
25707 }
25708 run_test 431 "Restart transaction for IO"
25709
25710 prep_801() {
25711         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25712         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25713                 skip "Need server version at least 2.9.55"
25714
25715         start_full_debug_logging
25716 }
25717
25718 post_801() {
25719         stop_full_debug_logging
25720 }
25721
25722 barrier_stat() {
25723         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25724                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25725                            awk '/The barrier for/ { print $7 }')
25726                 echo $st
25727         else
25728                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25729                 echo \'$st\'
25730         fi
25731 }
25732
25733 barrier_expired() {
25734         local expired
25735
25736         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25737                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25738                           awk '/will be expired/ { print $7 }')
25739         else
25740                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25741         fi
25742
25743         echo $expired
25744 }
25745
25746 test_801a() {
25747         prep_801
25748
25749         echo "Start barrier_freeze at: $(date)"
25750         #define OBD_FAIL_BARRIER_DELAY          0x2202
25751         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25752         # Do not reduce barrier time - See LU-11873
25753         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25754
25755         sleep 2
25756         local b_status=$(barrier_stat)
25757         echo "Got barrier status at: $(date)"
25758         [ "$b_status" = "'freezing_p1'" ] ||
25759                 error "(1) unexpected barrier status $b_status"
25760
25761         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25762         wait
25763         b_status=$(barrier_stat)
25764         [ "$b_status" = "'frozen'" ] ||
25765                 error "(2) unexpected barrier status $b_status"
25766
25767         local expired=$(barrier_expired)
25768         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25769         sleep $((expired + 3))
25770
25771         b_status=$(barrier_stat)
25772         [ "$b_status" = "'expired'" ] ||
25773                 error "(3) unexpected barrier status $b_status"
25774
25775         # Do not reduce barrier time - See LU-11873
25776         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25777                 error "(4) fail to freeze barrier"
25778
25779         b_status=$(barrier_stat)
25780         [ "$b_status" = "'frozen'" ] ||
25781                 error "(5) unexpected barrier status $b_status"
25782
25783         echo "Start barrier_thaw at: $(date)"
25784         #define OBD_FAIL_BARRIER_DELAY          0x2202
25785         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25786         do_facet mgs $LCTL barrier_thaw $FSNAME &
25787
25788         sleep 2
25789         b_status=$(barrier_stat)
25790         echo "Got barrier status at: $(date)"
25791         [ "$b_status" = "'thawing'" ] ||
25792                 error "(6) unexpected barrier status $b_status"
25793
25794         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25795         wait
25796         b_status=$(barrier_stat)
25797         [ "$b_status" = "'thawed'" ] ||
25798                 error "(7) unexpected barrier status $b_status"
25799
25800         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25801         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25802         do_facet mgs $LCTL barrier_freeze $FSNAME
25803
25804         b_status=$(barrier_stat)
25805         [ "$b_status" = "'failed'" ] ||
25806                 error "(8) unexpected barrier status $b_status"
25807
25808         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25809         do_facet mgs $LCTL barrier_thaw $FSNAME
25810
25811         post_801
25812 }
25813 run_test 801a "write barrier user interfaces and stat machine"
25814
25815 test_801b() {
25816         prep_801
25817
25818         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25819         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25820         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25821         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25822         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25823
25824         cancel_lru_locks mdc
25825
25826         # 180 seconds should be long enough
25827         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25828
25829         local b_status=$(barrier_stat)
25830         [ "$b_status" = "'frozen'" ] ||
25831                 error "(6) unexpected barrier status $b_status"
25832
25833         mkdir $DIR/$tdir/d0/d10 &
25834         mkdir_pid=$!
25835
25836         touch $DIR/$tdir/d1/f13 &
25837         touch_pid=$!
25838
25839         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25840         ln_pid=$!
25841
25842         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25843         mv_pid=$!
25844
25845         rm -f $DIR/$tdir/d4/f12 &
25846         rm_pid=$!
25847
25848         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25849
25850         # To guarantee taht the 'stat' is not blocked
25851         b_status=$(barrier_stat)
25852         [ "$b_status" = "'frozen'" ] ||
25853                 error "(8) unexpected barrier status $b_status"
25854
25855         # let above commands to run at background
25856         sleep 5
25857
25858         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25859         ps -p $touch_pid || error "(10) touch should be blocked"
25860         ps -p $ln_pid || error "(11) link should be blocked"
25861         ps -p $mv_pid || error "(12) rename should be blocked"
25862         ps -p $rm_pid || error "(13) unlink should be blocked"
25863
25864         b_status=$(barrier_stat)
25865         [ "$b_status" = "'frozen'" ] ||
25866                 error "(14) unexpected barrier status $b_status"
25867
25868         do_facet mgs $LCTL barrier_thaw $FSNAME
25869         b_status=$(barrier_stat)
25870         [ "$b_status" = "'thawed'" ] ||
25871                 error "(15) unexpected barrier status $b_status"
25872
25873         wait $mkdir_pid || error "(16) mkdir should succeed"
25874         wait $touch_pid || error "(17) touch should succeed"
25875         wait $ln_pid || error "(18) link should succeed"
25876         wait $mv_pid || error "(19) rename should succeed"
25877         wait $rm_pid || error "(20) unlink should succeed"
25878
25879         post_801
25880 }
25881 run_test 801b "modification will be blocked by write barrier"
25882
25883 test_801c() {
25884         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25885
25886         prep_801
25887
25888         stop mds2 || error "(1) Fail to stop mds2"
25889
25890         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25891
25892         local b_status=$(barrier_stat)
25893         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25894                 do_facet mgs $LCTL barrier_thaw $FSNAME
25895                 error "(2) unexpected barrier status $b_status"
25896         }
25897
25898         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25899                 error "(3) Fail to rescan barrier bitmap"
25900
25901         # Do not reduce barrier time - See LU-11873
25902         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25903
25904         b_status=$(barrier_stat)
25905         [ "$b_status" = "'frozen'" ] ||
25906                 error "(4) unexpected barrier status $b_status"
25907
25908         do_facet mgs $LCTL barrier_thaw $FSNAME
25909         b_status=$(barrier_stat)
25910         [ "$b_status" = "'thawed'" ] ||
25911                 error "(5) unexpected barrier status $b_status"
25912
25913         local devname=$(mdsdevname 2)
25914
25915         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25916
25917         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25918                 error "(7) Fail to rescan barrier bitmap"
25919
25920         post_801
25921 }
25922 run_test 801c "rescan barrier bitmap"
25923
25924 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25925 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25926 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25927 saved_MOUNT_OPTS=$MOUNT_OPTS
25928
25929 cleanup_802a() {
25930         trap 0
25931
25932         stopall
25933         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25934         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25935         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25936         MOUNT_OPTS=$saved_MOUNT_OPTS
25937         setupall
25938 }
25939
25940 test_802a() {
25941         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25942         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25943         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25944                 skip "Need server version at least 2.9.55"
25945
25946         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25947
25948         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25949
25950         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25951                 error "(2) Fail to copy"
25952
25953         trap cleanup_802a EXIT
25954
25955         # sync by force before remount as readonly
25956         sync; sync_all_data; sleep 3; sync_all_data
25957
25958         stopall
25959
25960         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25961         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25962         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25963
25964         echo "Mount the server as read only"
25965         setupall server_only || error "(3) Fail to start servers"
25966
25967         echo "Mount client without ro should fail"
25968         mount_client $MOUNT &&
25969                 error "(4) Mount client without 'ro' should fail"
25970
25971         echo "Mount client with ro should succeed"
25972         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25973         mount_client $MOUNT ||
25974                 error "(5) Mount client with 'ro' should succeed"
25975
25976         echo "Modify should be refused"
25977         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25978
25979         echo "Read should be allowed"
25980         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25981                 error "(7) Read should succeed under ro mode"
25982
25983         cleanup_802a
25984 }
25985 run_test 802a "simulate readonly device"
25986
25987 test_802b() {
25988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25989         remote_mds_nodsh && skip "remote MDS with nodsh"
25990
25991         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25992                 skip "readonly option not available"
25993
25994         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25995
25996         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25997                 error "(2) Fail to copy"
25998
25999         # write back all cached data before setting MDT to readonly
26000         cancel_lru_locks
26001         sync_all_data
26002
26003         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26004         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26005
26006         echo "Modify should be refused"
26007         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26008
26009         echo "Read should be allowed"
26010         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26011                 error "(7) Read should succeed under ro mode"
26012
26013         # disable readonly
26014         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26015 }
26016 run_test 802b "be able to set MDTs to readonly"
26017
26018 test_803a() {
26019         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26020         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26021                 skip "MDS needs to be newer than 2.10.54"
26022
26023         mkdir_on_mdt0 $DIR/$tdir
26024         # Create some objects on all MDTs to trigger related logs objects
26025         for idx in $(seq $MDSCOUNT); do
26026                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26027                         $DIR/$tdir/dir${idx} ||
26028                         error "Fail to create $DIR/$tdir/dir${idx}"
26029         done
26030
26031         sync; sleep 3
26032         wait_delete_completed # ensure old test cleanups are finished
26033         echo "before create:"
26034         $LFS df -i $MOUNT
26035         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26036
26037         for i in {1..10}; do
26038                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26039                         error "Fail to create $DIR/$tdir/foo$i"
26040         done
26041
26042         sync; sleep 3
26043         echo "after create:"
26044         $LFS df -i $MOUNT
26045         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26046
26047         # allow for an llog to be cleaned up during the test
26048         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26049                 error "before ($before_used) + 10 > after ($after_used)"
26050
26051         for i in {1..10}; do
26052                 rm -rf $DIR/$tdir/foo$i ||
26053                         error "Fail to remove $DIR/$tdir/foo$i"
26054         done
26055
26056         sleep 3 # avoid MDT return cached statfs
26057         wait_delete_completed
26058         echo "after unlink:"
26059         $LFS df -i $MOUNT
26060         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26061
26062         # allow for an llog to be created during the test
26063         [ $after_used -le $((before_used + 1)) ] ||
26064                 error "after ($after_used) > before ($before_used) + 1"
26065 }
26066 run_test 803a "verify agent object for remote object"
26067
26068 test_803b() {
26069         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26070         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26071                 skip "MDS needs to be newer than 2.13.56"
26072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26073
26074         for i in $(seq 0 $((MDSCOUNT - 1))); do
26075                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26076         done
26077
26078         local before=0
26079         local after=0
26080
26081         local tmp
26082
26083         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26084         for i in $(seq 0 $((MDSCOUNT - 1))); do
26085                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26086                         awk '/getattr/ { print $2 }')
26087                 before=$((before + tmp))
26088         done
26089         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26090         for i in $(seq 0 $((MDSCOUNT - 1))); do
26091                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26092                         awk '/getattr/ { print $2 }')
26093                 after=$((after + tmp))
26094         done
26095
26096         [ $before -eq $after ] || error "getattr count $before != $after"
26097 }
26098 run_test 803b "remote object can getattr from cache"
26099
26100 test_804() {
26101         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26102         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26103                 skip "MDS needs to be newer than 2.10.54"
26104         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26105
26106         mkdir -p $DIR/$tdir
26107         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26108                 error "Fail to create $DIR/$tdir/dir0"
26109
26110         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26111         local dev=$(mdsdevname 2)
26112
26113         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26114                 grep ${fid} || error "NOT found agent entry for dir0"
26115
26116         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26117                 error "Fail to create $DIR/$tdir/dir1"
26118
26119         touch $DIR/$tdir/dir1/foo0 ||
26120                 error "Fail to create $DIR/$tdir/dir1/foo0"
26121         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26122         local rc=0
26123
26124         for idx in $(seq $MDSCOUNT); do
26125                 dev=$(mdsdevname $idx)
26126                 do_facet mds${idx} \
26127                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26128                         grep ${fid} && rc=$idx
26129         done
26130
26131         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26132                 error "Fail to rename foo0 to foo1"
26133         if [ $rc -eq 0 ]; then
26134                 for idx in $(seq $MDSCOUNT); do
26135                         dev=$(mdsdevname $idx)
26136                         do_facet mds${idx} \
26137                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26138                         grep ${fid} && rc=$idx
26139                 done
26140         fi
26141
26142         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26143                 error "Fail to rename foo1 to foo2"
26144         if [ $rc -eq 0 ]; then
26145                 for idx in $(seq $MDSCOUNT); do
26146                         dev=$(mdsdevname $idx)
26147                         do_facet mds${idx} \
26148                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26149                         grep ${fid} && rc=$idx
26150                 done
26151         fi
26152
26153         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26154
26155         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26156                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26157         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26158                 error "Fail to rename foo2 to foo0"
26159         unlink $DIR/$tdir/dir1/foo0 ||
26160                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26161         rm -rf $DIR/$tdir/dir0 ||
26162                 error "Fail to rm $DIR/$tdir/dir0"
26163
26164         for idx in $(seq $MDSCOUNT); do
26165                 dev=$(mdsdevname $idx)
26166                 rc=0
26167
26168                 stop mds${idx}
26169                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26170                         rc=$?
26171                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26172                         error "mount mds$idx failed"
26173                 df $MOUNT > /dev/null 2>&1
26174
26175                 # e2fsck should not return error
26176                 [ $rc -eq 0 ] ||
26177                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26178         done
26179 }
26180 run_test 804 "verify agent entry for remote entry"
26181
26182 cleanup_805() {
26183         do_facet $SINGLEMDS zfs set quota=$old $fsset
26184         unlinkmany $DIR/$tdir/f- 1000000
26185         trap 0
26186 }
26187
26188 test_805() {
26189         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26190         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26191         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26192                 skip "netfree not implemented before 0.7"
26193         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26194                 skip "Need MDS version at least 2.10.57"
26195
26196         local fsset
26197         local freekb
26198         local usedkb
26199         local old
26200         local quota
26201         local pref="osd-zfs.$FSNAME-MDT0000."
26202
26203         # limit available space on MDS dataset to meet nospace issue
26204         # quickly. then ZFS 0.7.2 can use reserved space if asked
26205         # properly (using netfree flag in osd_declare_destroy()
26206         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26207         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26208                 gawk '{print $3}')
26209         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26210         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26211         let "usedkb=usedkb-freekb"
26212         let "freekb=freekb/2"
26213         if let "freekb > 5000"; then
26214                 let "freekb=5000"
26215         fi
26216         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26217         trap cleanup_805 EXIT
26218         mkdir_on_mdt0 $DIR/$tdir
26219         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26220                 error "Can't set PFL layout"
26221         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26222         rm -rf $DIR/$tdir || error "not able to remove"
26223         do_facet $SINGLEMDS zfs set quota=$old $fsset
26224         trap 0
26225 }
26226 run_test 805 "ZFS can remove from full fs"
26227
26228 # Size-on-MDS test
26229 check_lsom_data()
26230 {
26231         local file=$1
26232         local expect=$(stat -c %s $file)
26233
26234         check_lsom_size $1 $expect
26235
26236         local blocks=$($LFS getsom -b $file)
26237         expect=$(stat -c %b $file)
26238         [[ $blocks == $expect ]] ||
26239                 error "$file expected blocks: $expect, got: $blocks"
26240 }
26241
26242 check_lsom_size()
26243 {
26244         local size
26245         local expect=$2
26246
26247         cancel_lru_locks mdc
26248
26249         size=$($LFS getsom -s $1)
26250         [[ $size == $expect ]] ||
26251                 error "$file expected size: $expect, got: $size"
26252 }
26253
26254 test_806() {
26255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26256                 skip "Need MDS version at least 2.11.52"
26257
26258         local bs=1048576
26259
26260         touch $DIR/$tfile || error "touch $tfile failed"
26261
26262         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26263         save_lustre_params client "llite.*.xattr_cache" > $save
26264         lctl set_param llite.*.xattr_cache=0
26265         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26266
26267         # single-threaded write
26268         echo "Test SOM for single-threaded write"
26269         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26270                 error "write $tfile failed"
26271         check_lsom_size $DIR/$tfile $bs
26272
26273         local num=32
26274         local size=$(($num * $bs))
26275         local offset=0
26276         local i
26277
26278         echo "Test SOM for single client multi-threaded($num) write"
26279         $TRUNCATE $DIR/$tfile 0
26280         for ((i = 0; i < $num; i++)); do
26281                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26282                 local pids[$i]=$!
26283                 offset=$((offset + $bs))
26284         done
26285         for (( i=0; i < $num; i++ )); do
26286                 wait ${pids[$i]}
26287         done
26288         check_lsom_size $DIR/$tfile $size
26289
26290         $TRUNCATE $DIR/$tfile 0
26291         for ((i = 0; i < $num; i++)); do
26292                 offset=$((offset - $bs))
26293                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26294                 local pids[$i]=$!
26295         done
26296         for (( i=0; i < $num; i++ )); do
26297                 wait ${pids[$i]}
26298         done
26299         check_lsom_size $DIR/$tfile $size
26300
26301         # multi-client writes
26302         num=$(get_node_count ${CLIENTS//,/ })
26303         size=$(($num * $bs))
26304         offset=0
26305         i=0
26306
26307         echo "Test SOM for multi-client ($num) writes"
26308         $TRUNCATE $DIR/$tfile 0
26309         for client in ${CLIENTS//,/ }; do
26310                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26311                 local pids[$i]=$!
26312                 i=$((i + 1))
26313                 offset=$((offset + $bs))
26314         done
26315         for (( i=0; i < $num; i++ )); do
26316                 wait ${pids[$i]}
26317         done
26318         check_lsom_size $DIR/$tfile $offset
26319
26320         i=0
26321         $TRUNCATE $DIR/$tfile 0
26322         for client in ${CLIENTS//,/ }; do
26323                 offset=$((offset - $bs))
26324                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26325                 local pids[$i]=$!
26326                 i=$((i + 1))
26327         done
26328         for (( i=0; i < $num; i++ )); do
26329                 wait ${pids[$i]}
26330         done
26331         check_lsom_size $DIR/$tfile $size
26332
26333         # verify truncate
26334         echo "Test SOM for truncate"
26335         $TRUNCATE $DIR/$tfile 1048576
26336         check_lsom_size $DIR/$tfile 1048576
26337         $TRUNCATE $DIR/$tfile 1234
26338         check_lsom_size $DIR/$tfile 1234
26339
26340         # verify SOM blocks count
26341         echo "Verify SOM block count"
26342         $TRUNCATE $DIR/$tfile 0
26343         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26344                 error "failed to write file $tfile"
26345         check_lsom_data $DIR/$tfile
26346 }
26347 run_test 806 "Verify Lazy Size on MDS"
26348
26349 test_807() {
26350         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26351         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26352                 skip "Need MDS version at least 2.11.52"
26353
26354         # Registration step
26355         changelog_register || error "changelog_register failed"
26356         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26357         changelog_users $SINGLEMDS | grep -q $cl_user ||
26358                 error "User $cl_user not found in changelog_users"
26359
26360         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26361         save_lustre_params client "llite.*.xattr_cache" > $save
26362         lctl set_param llite.*.xattr_cache=0
26363         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26364
26365         rm -rf $DIR/$tdir || error "rm $tdir failed"
26366         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26367         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26368         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26369         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26370                 error "truncate $tdir/trunc failed"
26371
26372         local bs=1048576
26373         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26374                 error "write $tfile failed"
26375
26376         # multi-client wirtes
26377         local num=$(get_node_count ${CLIENTS//,/ })
26378         local offset=0
26379         local i=0
26380
26381         echo "Test SOM for multi-client ($num) writes"
26382         touch $DIR/$tfile || error "touch $tfile failed"
26383         $TRUNCATE $DIR/$tfile 0
26384         for client in ${CLIENTS//,/ }; do
26385                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26386                 local pids[$i]=$!
26387                 i=$((i + 1))
26388                 offset=$((offset + $bs))
26389         done
26390         for (( i=0; i < $num; i++ )); do
26391                 wait ${pids[$i]}
26392         done
26393
26394         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26395         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26396         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26397         check_lsom_data $DIR/$tdir/trunc
26398         check_lsom_data $DIR/$tdir/single_dd
26399         check_lsom_data $DIR/$tfile
26400
26401         rm -rf $DIR/$tdir
26402         # Deregistration step
26403         changelog_deregister || error "changelog_deregister failed"
26404 }
26405 run_test 807 "verify LSOM syncing tool"
26406
26407 check_som_nologged()
26408 {
26409         local lines=$($LFS changelog $FSNAME-MDT0000 |
26410                 grep 'x=trusted.som' | wc -l)
26411         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26412 }
26413
26414 test_808() {
26415         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26416                 skip "Need MDS version at least 2.11.55"
26417
26418         # Registration step
26419         changelog_register || error "changelog_register failed"
26420
26421         touch $DIR/$tfile || error "touch $tfile failed"
26422         check_som_nologged
26423
26424         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26425                 error "write $tfile failed"
26426         check_som_nologged
26427
26428         $TRUNCATE $DIR/$tfile 1234
26429         check_som_nologged
26430
26431         $TRUNCATE $DIR/$tfile 1048576
26432         check_som_nologged
26433
26434         # Deregistration step
26435         changelog_deregister || error "changelog_deregister failed"
26436 }
26437 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26438
26439 check_som_nodata()
26440 {
26441         $LFS getsom $1
26442         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26443 }
26444
26445 test_809() {
26446         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26447                 skip "Need MDS version at least 2.11.56"
26448
26449         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26450                 error "failed to create DoM-only file $DIR/$tfile"
26451         touch $DIR/$tfile || error "touch $tfile failed"
26452         check_som_nodata $DIR/$tfile
26453
26454         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26455                 error "write $tfile failed"
26456         check_som_nodata $DIR/$tfile
26457
26458         $TRUNCATE $DIR/$tfile 1234
26459         check_som_nodata $DIR/$tfile
26460
26461         $TRUNCATE $DIR/$tfile 4097
26462         check_som_nodata $DIR/$file
26463 }
26464 run_test 809 "Verify no SOM xattr store for DoM-only files"
26465
26466 test_810() {
26467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26468         $GSS && skip_env "could not run with gss"
26469         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26470                 skip "OST < 2.12.58 doesn't align checksum"
26471
26472         set_checksums 1
26473         stack_trap "set_checksums $ORIG_CSUM" EXIT
26474         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26475
26476         local csum
26477         local before
26478         local after
26479         for csum in $CKSUM_TYPES; do
26480                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26481                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26482                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26483                         eval set -- $i
26484                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26485                         before=$(md5sum $DIR/$tfile)
26486                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26487                         after=$(md5sum $DIR/$tfile)
26488                         [ "$before" == "$after" ] ||
26489                                 error "$csum: $before != $after bs=$1 seek=$2"
26490                 done
26491         done
26492 }
26493 run_test 810 "partial page writes on ZFS (LU-11663)"
26494
26495 test_812a() {
26496         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26497                 skip "OST < 2.12.51 doesn't support this fail_loc"
26498
26499         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26500         # ensure ost1 is connected
26501         stat $DIR/$tfile >/dev/null || error "can't stat"
26502         wait_osc_import_state client ost1 FULL
26503         # no locks, no reqs to let the connection idle
26504         cancel_lru_locks osc
26505
26506         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26507 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26508         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26509         wait_osc_import_state client ost1 CONNECTING
26510         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26511
26512         stat $DIR/$tfile >/dev/null || error "can't stat file"
26513 }
26514 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26515
26516 test_812b() { # LU-12378
26517         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26518                 skip "OST < 2.12.51 doesn't support this fail_loc"
26519
26520         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26521         # ensure ost1 is connected
26522         stat $DIR/$tfile >/dev/null || error "can't stat"
26523         wait_osc_import_state client ost1 FULL
26524         # no locks, no reqs to let the connection idle
26525         cancel_lru_locks osc
26526
26527         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26528 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26529         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26530         wait_osc_import_state client ost1 CONNECTING
26531         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26532
26533         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26534         wait_osc_import_state client ost1 IDLE
26535 }
26536 run_test 812b "do not drop no resend request for idle connect"
26537
26538 test_812c() {
26539         local old
26540
26541         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26542
26543         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26544         $LFS getstripe $DIR/$tfile
26545         $LCTL set_param osc.*.idle_timeout=10
26546         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26547         # ensure ost1 is connected
26548         stat $DIR/$tfile >/dev/null || error "can't stat"
26549         wait_osc_import_state client ost1 FULL
26550         # no locks, no reqs to let the connection idle
26551         cancel_lru_locks osc
26552
26553 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26554         $LCTL set_param fail_loc=0x80000533
26555         sleep 15
26556         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26557 }
26558 run_test 812c "idle import vs lock enqueue race"
26559
26560 test_813() {
26561         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26562         [ -z "$file_heat_sav" ] && skip "no file heat support"
26563
26564         local readsample
26565         local writesample
26566         local readbyte
26567         local writebyte
26568         local readsample1
26569         local writesample1
26570         local readbyte1
26571         local writebyte1
26572
26573         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26574         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26575
26576         $LCTL set_param -n llite.*.file_heat=1
26577         echo "Turn on file heat"
26578         echo "Period second: $period_second, Decay percentage: $decay_pct"
26579
26580         echo "QQQQ" > $DIR/$tfile
26581         echo "QQQQ" > $DIR/$tfile
26582         echo "QQQQ" > $DIR/$tfile
26583         cat $DIR/$tfile > /dev/null
26584         cat $DIR/$tfile > /dev/null
26585         cat $DIR/$tfile > /dev/null
26586         cat $DIR/$tfile > /dev/null
26587
26588         local out=$($LFS heat_get $DIR/$tfile)
26589
26590         $LFS heat_get $DIR/$tfile
26591         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26592         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26593         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26594         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26595
26596         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26597         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26598         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26599         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26600
26601         sleep $((period_second + 3))
26602         echo "Sleep $((period_second + 3)) seconds..."
26603         # The recursion formula to calculate the heat of the file f is as
26604         # follow:
26605         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26606         # Where Hi is the heat value in the period between time points i*I and
26607         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26608         # to the weight of Ci.
26609         out=$($LFS heat_get $DIR/$tfile)
26610         $LFS heat_get $DIR/$tfile
26611         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26612         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26613         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26614         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26615
26616         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26617                 error "read sample ($readsample) is wrong"
26618         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26619                 error "write sample ($writesample) is wrong"
26620         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26621                 error "read bytes ($readbyte) is wrong"
26622         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26623                 error "write bytes ($writebyte) is wrong"
26624
26625         echo "QQQQ" > $DIR/$tfile
26626         echo "QQQQ" > $DIR/$tfile
26627         echo "QQQQ" > $DIR/$tfile
26628         cat $DIR/$tfile > /dev/null
26629         cat $DIR/$tfile > /dev/null
26630         cat $DIR/$tfile > /dev/null
26631         cat $DIR/$tfile > /dev/null
26632
26633         sleep $((period_second + 3))
26634         echo "Sleep $((period_second + 3)) seconds..."
26635
26636         out=$($LFS heat_get $DIR/$tfile)
26637         $LFS heat_get $DIR/$tfile
26638         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26639         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26640         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26641         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26642
26643         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26644                 4 * $decay_pct) / 100") -eq 1 ] ||
26645                 error "read sample ($readsample1) is wrong"
26646         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26647                 3 * $decay_pct) / 100") -eq 1 ] ||
26648                 error "write sample ($writesample1) is wrong"
26649         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26650                 20 * $decay_pct) / 100") -eq 1 ] ||
26651                 error "read bytes ($readbyte1) is wrong"
26652         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26653                 15 * $decay_pct) / 100") -eq 1 ] ||
26654                 error "write bytes ($writebyte1) is wrong"
26655
26656         echo "Turn off file heat for the file $DIR/$tfile"
26657         $LFS heat_set -o $DIR/$tfile
26658
26659         echo "QQQQ" > $DIR/$tfile
26660         echo "QQQQ" > $DIR/$tfile
26661         echo "QQQQ" > $DIR/$tfile
26662         cat $DIR/$tfile > /dev/null
26663         cat $DIR/$tfile > /dev/null
26664         cat $DIR/$tfile > /dev/null
26665         cat $DIR/$tfile > /dev/null
26666
26667         out=$($LFS heat_get $DIR/$tfile)
26668         $LFS heat_get $DIR/$tfile
26669         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26670         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26671         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26672         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26673
26674         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26675         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26676         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26677         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26678
26679         echo "Trun on file heat for the file $DIR/$tfile"
26680         $LFS heat_set -O $DIR/$tfile
26681
26682         echo "QQQQ" > $DIR/$tfile
26683         echo "QQQQ" > $DIR/$tfile
26684         echo "QQQQ" > $DIR/$tfile
26685         cat $DIR/$tfile > /dev/null
26686         cat $DIR/$tfile > /dev/null
26687         cat $DIR/$tfile > /dev/null
26688         cat $DIR/$tfile > /dev/null
26689
26690         out=$($LFS heat_get $DIR/$tfile)
26691         $LFS heat_get $DIR/$tfile
26692         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26693         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26694         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26695         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26696
26697         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26698         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26699         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26700         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26701
26702         $LFS heat_set -c $DIR/$tfile
26703         $LCTL set_param -n llite.*.file_heat=0
26704         echo "Turn off file heat support for the Lustre filesystem"
26705
26706         echo "QQQQ" > $DIR/$tfile
26707         echo "QQQQ" > $DIR/$tfile
26708         echo "QQQQ" > $DIR/$tfile
26709         cat $DIR/$tfile > /dev/null
26710         cat $DIR/$tfile > /dev/null
26711         cat $DIR/$tfile > /dev/null
26712         cat $DIR/$tfile > /dev/null
26713
26714         out=$($LFS heat_get $DIR/$tfile)
26715         $LFS heat_get $DIR/$tfile
26716         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26717         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26718         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26719         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26720
26721         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26722         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26723         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26724         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26725
26726         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26727         rm -f $DIR/$tfile
26728 }
26729 run_test 813 "File heat verfication"
26730
26731 test_814()
26732 {
26733         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26734         echo -n y >> $DIR/$tfile
26735         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26736         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26737 }
26738 run_test 814 "sparse cp works as expected (LU-12361)"
26739
26740 test_815()
26741 {
26742         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26743         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26744 }
26745 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26746
26747 test_816() {
26748         local ost1_imp=$(get_osc_import_name client ost1)
26749         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26750                          cut -d'.' -f2)
26751
26752         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26753         # ensure ost1 is connected
26754
26755         stat $DIR/$tfile >/dev/null || error "can't stat"
26756         wait_osc_import_state client ost1 FULL
26757         # no locks, no reqs to let the connection idle
26758         cancel_lru_locks osc
26759         lru_resize_disable osc
26760         local before
26761         local now
26762         before=$($LCTL get_param -n \
26763                  ldlm.namespaces.$imp_name.lru_size)
26764
26765         wait_osc_import_state client ost1 IDLE
26766         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26767         now=$($LCTL get_param -n \
26768               ldlm.namespaces.$imp_name.lru_size)
26769         [ $before == $now ] || error "lru_size changed $before != $now"
26770 }
26771 run_test 816 "do not reset lru_resize on idle reconnect"
26772
26773 cleanup_817() {
26774         umount $tmpdir
26775         exportfs -u localhost:$DIR/nfsexp
26776         rm -rf $DIR/nfsexp
26777 }
26778
26779 test_817() {
26780         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26781
26782         mkdir -p $DIR/nfsexp
26783         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26784                 error "failed to export nfs"
26785
26786         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26787         stack_trap cleanup_817 EXIT
26788
26789         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26790                 error "failed to mount nfs to $tmpdir"
26791
26792         cp /bin/true $tmpdir
26793         $DIR/nfsexp/true || error "failed to execute 'true' command"
26794 }
26795 run_test 817 "nfsd won't cache write lock for exec file"
26796
26797 test_818() {
26798         mkdir $DIR/$tdir
26799         $LFS setstripe -c1 -i0 $DIR/$tfile
26800         $LFS setstripe -c1 -i1 $DIR/$tfile
26801         stop $SINGLEMDS
26802         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26803         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26804         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26805                 error "start $SINGLEMDS failed"
26806         rm -rf $DIR/$tdir
26807 }
26808 run_test 818 "unlink with failed llog"
26809
26810 test_819a() {
26811         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26812         cancel_lru_locks osc
26813         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26814         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26815         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26816         rm -f $TDIR/$tfile
26817 }
26818 run_test 819a "too big niobuf in read"
26819
26820 test_819b() {
26821         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26822         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26823         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26824         cancel_lru_locks osc
26825         sleep 1
26826         rm -f $TDIR/$tfile
26827 }
26828 run_test 819b "too big niobuf in write"
26829
26830
26831 function test_820_start_ost() {
26832         sleep 5
26833
26834         for num in $(seq $OSTCOUNT); do
26835                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26836         done
26837 }
26838
26839 test_820() {
26840         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26841
26842         mkdir $DIR/$tdir
26843         umount_client $MOUNT || error "umount failed"
26844         for num in $(seq $OSTCOUNT); do
26845                 stop ost$num
26846         done
26847
26848         # mount client with no active OSTs
26849         # so that the client can't initialize max LOV EA size
26850         # from OSC notifications
26851         mount_client $MOUNT || error "mount failed"
26852         # delay OST starting to keep this 0 max EA size for a while
26853         test_820_start_ost &
26854
26855         # create a directory on MDS2
26856         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26857                 error "Failed to create directory"
26858         # open intent should update default EA size
26859         # see mdc_update_max_ea_from_body()
26860         # notice this is the very first RPC to MDS2
26861         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26862         ret=$?
26863         echo $out
26864         # With SSK, this situation can lead to -EPERM being returned.
26865         # In that case, simply retry.
26866         if [ $ret -ne 0 ] && $SHARED_KEY; then
26867                 if echo "$out" | grep -q "not permitted"; then
26868                         cp /etc/services $DIR/$tdir/mds2
26869                         ret=$?
26870                 fi
26871         fi
26872         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26873 }
26874 run_test 820 "update max EA from open intent"
26875
26876 test_822() {
26877         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26878
26879         save_lustre_params mds1 \
26880                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26881         do_facet $SINGLEMDS "$LCTL set_param -n \
26882                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26883         do_facet $SINGLEMDS "$LCTL set_param -n \
26884                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26885
26886         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26887         local maxage=$(do_facet mds1 $LCTL get_param -n \
26888                        osp.$FSNAME-OST0000*MDT0000.maxage)
26889         sleep $((maxage + 1))
26890
26891         #define OBD_FAIL_NET_ERROR_RPC          0x532
26892         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26893
26894         stack_trap "restore_lustre_params < $p; rm $p"
26895
26896         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26897                       osp.$FSNAME-OST0000*MDT0000.create_count")
26898         for i in $(seq 1 $count); do
26899                 touch $DIR/$tfile.${i} || error "touch failed"
26900         done
26901 }
26902 run_test 822 "test precreate failure"
26903
26904 #
26905 # tests that do cleanup/setup should be run at the end
26906 #
26907
26908 test_900() {
26909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26910         local ls
26911
26912         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26913         $LCTL set_param fail_loc=0x903
26914
26915         cancel_lru_locks MGC
26916
26917         FAIL_ON_ERROR=true cleanup
26918         FAIL_ON_ERROR=true setup
26919 }
26920 run_test 900 "umount should not race with any mgc requeue thread"
26921
26922 # LUS-6253/LU-11185
26923 test_901() {
26924         local oldc
26925         local newc
26926         local olds
26927         local news
26928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26929
26930         # some get_param have a bug to handle dot in param name
26931         cancel_lru_locks MGC
26932         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26933         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26934         umount_client $MOUNT || error "umount failed"
26935         mount_client $MOUNT || error "mount failed"
26936         cancel_lru_locks MGC
26937         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26938         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26939
26940         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26941         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26942
26943         return 0
26944 }
26945 run_test 901 "don't leak a mgc lock on client umount"
26946
26947 # LU-13377
26948 test_902() {
26949         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26950                 skip "client does not have LU-13377 fix"
26951         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26952         $LCTL set_param fail_loc=0x1415
26953         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26954         cancel_lru_locks osc
26955         rm -f $DIR/$tfile
26956 }
26957 run_test 902 "test short write doesn't hang lustre"
26958
26959 complete $SECONDS
26960 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26961 check_and_cleanup_lustre
26962 if [ "$I_MOUNTED" != "yes" ]; then
26963         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26964 fi
26965 exit_status