Whamcloud - gitweb
LU-13982 tests: fix infinite loop in sanity test_184c
[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-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
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 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_swap_layout_no_dom()
148 {
149         local FOLDER=$1
150         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
151         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
152 }
153
154 check_and_setup_lustre
155 DIR=${DIR:-$MOUNT}
156 assert_DIR
157
158 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
159
160 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
161 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
162 rm -rf $DIR/[Rdfs][0-9]*
163
164 # $RUNAS_ID may get set incorrectly somewhere else
165 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
166         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
167
168 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
169
170 if [ "${ONLY}" = "MOUNT" ] ; then
171         echo "Lustre is up, please go on"
172         exit
173 fi
174
175 echo "preparing for tests involving mounts"
176 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
177 touch $EXT2_DEV
178 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
179 echo # add a newline after mke2fs.
180
181 umask 077
182
183 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
184 lctl set_param debug=-1 2> /dev/null || true
185 test_0a() {
186         touch $DIR/$tfile
187         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
188         rm $DIR/$tfile
189         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
190 }
191 run_test 0a "touch; rm ====================="
192
193 test_0b() {
194         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
195         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
196 }
197 run_test 0b "chmod 0755 $DIR ============================="
198
199 test_0c() {
200         $LCTL get_param mdc.*.import | grep "state: FULL" ||
201                 error "import not FULL"
202         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
203                 error "bad target"
204 }
205 run_test 0c "check import proc"
206
207 test_0d() { # LU-3397
208         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
209                 skip "proc exports not supported before 2.10.57"
210
211         local mgs_exp="mgs.MGS.exports"
212         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
213         local exp_client_nid
214         local exp_client_version
215         local exp_val
216         local imp_val
217         local temp_imp=$DIR/$tfile.import
218         local temp_exp=$DIR/$tfile.export
219
220         # save mgc import file to $temp_imp
221         $LCTL get_param mgc.*.import | tee $temp_imp
222         # Check if client uuid is found in MGS export
223         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
224                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
225                         $client_uuid ] &&
226                         break;
227         done
228         # save mgs export file to $temp_exp
229         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
230
231         # Compare the value of field "connect_flags"
232         imp_val=$(grep "connect_flags" $temp_imp)
233         exp_val=$(grep "connect_flags" $temp_exp)
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export flags '$exp_val' != import flags '$imp_val'"
236
237         # Compare the value of client version
238         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
239         exp_val=$(version_code $exp_client_version)
240         imp_val=$CLIENT_VERSION
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export client version '$exp_val' != '$imp_val'"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_1() {
247         test_mkdir $DIR/$tdir
248         test_mkdir $DIR/$tdir/d2
249         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
250         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
251         rmdir $DIR/$tdir/d2
252         rmdir $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
254 }
255 run_test 1 "mkdir; remkdir; rmdir"
256
257 test_2() {
258         test_mkdir $DIR/$tdir
259         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
260         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
261         rm -r $DIR/$tdir
262         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
263 }
264 run_test 2 "mkdir; touch; rmdir; check file"
265
266 test_3() {
267         test_mkdir $DIR/$tdir
268         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
269         touch $DIR/$tdir/$tfile
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
273 }
274 run_test 3 "mkdir; touch; rmdir; check dir"
275
276 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
277 test_4() {
278         test_mkdir -i 1 $DIR/$tdir
279
280         touch $DIR/$tdir/$tfile ||
281                 error "Create file under remote directory failed"
282
283         rmdir $DIR/$tdir &&
284                 error "Expect error removing in-use dir $DIR/$tdir"
285
286         test -d $DIR/$tdir || error "Remote directory disappeared"
287
288         rm -rf $DIR/$tdir || error "remove remote dir error"
289 }
290 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
291
292 test_5() {
293         test_mkdir $DIR/$tdir
294         test_mkdir $DIR/$tdir/d2
295         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
296         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
297         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
298 }
299 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
300
301 test_6a() {
302         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
303         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile does not have perm 0666 or UID $UID"
306         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
307         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
308                 error "$tfile should be 0666 and owned by UID $UID"
309 }
310 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
311
312 test_6c() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $RUNAS_ID"
322 }
323 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
324
325 test_6e() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         touch $DIR/$tfile
329         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by GID $UID"
332         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
333         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
335 }
336 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
337
338 test_6g() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         test_mkdir $DIR/$tdir
342         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
343         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
344         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
345         test_mkdir $DIR/$tdir/d/subdir
346         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
347                 error "$tdir/d/subdir should be GID $RUNAS_GID"
348         if [[ $MDSCOUNT -gt 1 ]]; then
349                 # check remote dir sgid inherite
350                 $LFS mkdir -i 0 $DIR/$tdir.local ||
351                         error "mkdir $tdir.local failed"
352                 chmod g+s $DIR/$tdir.local ||
353                         error "chmod $tdir.local failed"
354                 chgrp $RUNAS_GID $DIR/$tdir.local ||
355                         error "chgrp $tdir.local failed"
356                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
357                         error "mkdir $tdir.remote failed"
358                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
359                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
360                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be mode 02755"
362         fi
363 }
364 run_test 6g "verify new dir in sgid dir inherits group"
365
366 test_6h() { # bug 7331
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         touch $DIR/$tfile || error "touch failed"
370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
371         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
372                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
373         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
374                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
375 }
376 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
377
378 test_7a() {
379         test_mkdir $DIR/$tdir
380         $MCREATE $DIR/$tdir/$tfile
381         chmod 0666 $DIR/$tdir/$tfile
382         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
383                 error "$tdir/$tfile should be mode 0666"
384 }
385 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
386
387 test_7b() {
388         if [ ! -d $DIR/$tdir ]; then
389                 test_mkdir $DIR/$tdir
390         fi
391         $MCREATE $DIR/$tdir/$tfile
392         echo -n foo > $DIR/$tdir/$tfile
393         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
394         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
395 }
396 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
397
398 test_8() {
399         test_mkdir $DIR/$tdir
400         touch $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tfile mode not 0666"
404 }
405 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
406
407 test_9() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         test_mkdir $DIR/$tdir/d2/d3
411         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
412 }
413 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
414
415 test_10() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         touch $DIR/$tdir/d2/$tfile
419         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
420                 error "$tdir/d2/$tfile not a file"
421 }
422 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
423
424 test_11() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         chmod 0666 $DIR/$tdir/d2
428         chmod 0705 $DIR/$tdir/d2
429         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
430                 error "$tdir/d2 mode not 0705"
431 }
432 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
433
434 test_12() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         chmod 0654 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
440                 error "$tdir/d2 mode not 0654"
441 }
442 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
443
444 test_13() {
445         test_mkdir $DIR/$tdir
446         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
447         >  $DIR/$tdir/$tfile
448         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
449                 error "$tdir/$tfile size not 0 after truncate"
450 }
451 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
452
453 test_14() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         rm $DIR/$tdir/$tfile
457         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
458 }
459 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
460
461 test_15() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
465         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
466                 error "$tdir/${tfile_2} not a file after rename"
467         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
468 }
469 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
470
471 test_16() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm -rf $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
478
479 test_17a() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
485                 error "$tdir/l-exist not a symlink"
486         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not referencing a file"
488         rm -f $DIR/$tdir/l-exist
489         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
490 }
491 run_test 17a "symlinks: create, remove (real)"
492
493 test_17b() {
494         test_mkdir $DIR/$tdir
495         ln -s no-such-file $DIR/$tdir/l-dangle
496         ls -l $DIR/$tdir
497         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
498                 error "$tdir/l-dangle not referencing no-such-file"
499         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing non-existent file"
501         rm -f $DIR/$tdir/l-dangle
502         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
503 }
504 run_test 17b "symlinks: create, remove (dangling)"
505
506 test_17c() { # bug 3440 - don't save failed open RPC for replay
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
510 }
511 run_test 17c "symlinks: open dangling (should return error)"
512
513 test_17d() {
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         touch $DIR/$tdir/$tfile || error "creating to new symlink"
517 }
518 run_test 17d "symlinks: create dangling"
519
520 test_17e() {
521         test_mkdir $DIR/$tdir
522         local foo=$DIR/$tdir/$tfile
523         ln -s $foo $foo || error "create symlink failed"
524         ls -l $foo || error "ls -l failed"
525         ls $foo && error "ls not failed" || true
526 }
527 run_test 17e "symlinks: create recursive symlink (should return error)"
528
529 test_17f() {
530         test_mkdir $DIR/$tdir
531         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
533         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
536         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
537         ls -l  $DIR/$tdir
538 }
539 run_test 17f "symlinks: long and very long symlink name"
540
541 # str_repeat(S, N) generate a string that is string S repeated N times
542 str_repeat() {
543         local s=$1
544         local n=$2
545         local ret=''
546         while [ $((n -= 1)) -ge 0 ]; do
547                 ret=$ret$s
548         done
549         echo $ret
550 }
551
552 # Long symlinks and LU-2241
553 test_17g() {
554         test_mkdir $DIR/$tdir
555         local TESTS="59 60 61 4094 4095"
556
557         # Fix for inode size boundary in 2.1.4
558         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
559                 TESTS="4094 4095"
560
561         # Patch not applied to 2.2 or 2.3 branches
562         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
563         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
564                 TESTS="4094 4095"
565
566         for i in $TESTS; do
567                 local SYMNAME=$(str_repeat 'x' $i)
568                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
569                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
570         done
571 }
572 run_test 17g "symlinks: really long symlink name and inode boundaries"
573
574 test_17h() { #bug 17378
575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
576         remote_mds_nodsh && skip "remote MDS with nodsh"
577
578         local mdt_idx
579
580         test_mkdir $DIR/$tdir
581         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
582         $LFS setstripe -c -1 $DIR/$tdir
583         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
584         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
585         touch $DIR/$tdir/$tfile || true
586 }
587 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
588
589 test_17i() { #bug 20018
590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
591         remote_mds_nodsh && skip "remote MDS with nodsh"
592
593         local foo=$DIR/$tdir/$tfile
594         local mdt_idx
595
596         test_mkdir -c1 $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         ln -s $foo $foo || error "create symlink failed"
599 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
601         ls -l $foo && error "error not detected"
602         return 0
603 }
604 run_test 17i "don't panic on short symlink (should return error)"
605
606 test_17k() { #bug 22301
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         [[ -z "$(which rsync 2>/dev/null)" ]] &&
609                 skip "no rsync command"
610         rsync --help | grep -q xattr ||
611                 skip_env "$(rsync --version | head -n1) does not support xattrs"
612         test_mkdir $DIR/$tdir
613         test_mkdir $DIR/$tdir.new
614         touch $DIR/$tdir/$tfile
615         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
616         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
617                 error "rsync failed with xattrs enabled"
618 }
619 run_test 17k "symlinks: rsync with xattrs enabled"
620
621 test_17l() { # LU-279
622         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
623                 skip "no getfattr command"
624
625         test_mkdir $DIR/$tdir
626         touch $DIR/$tdir/$tfile
627         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
628         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
629                 # -h to not follow symlinks. -m '' to list all the xattrs.
630                 # grep to remove first line: '# file: $path'.
631                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
632                 do
633                         lgetxattr_size_check $path $xattr ||
634                                 error "lgetxattr_size_check $path $xattr failed"
635                 done
636         done
637 }
638 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
639
640 # LU-1540
641 test_17m() {
642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
643         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
644         remote_mds_nodsh && skip "remote MDS with nodsh"
645         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
646         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
647                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
648
649         local short_sym="0123456789"
650         local wdir=$DIR/$tdir
651         local i
652
653         test_mkdir $wdir
654         long_sym=$short_sym
655         # create a long symlink file
656         for ((i = 0; i < 4; ++i)); do
657                 long_sym=${long_sym}${long_sym}
658         done
659
660         echo "create 512 short and long symlink files under $wdir"
661         for ((i = 0; i < 256; ++i)); do
662                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
663                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
664         done
665
666         echo "erase them"
667         rm -f $wdir/*
668         sync
669         wait_delete_completed
670
671         echo "recreate the 512 symlink files with a shorter string"
672         for ((i = 0; i < 512; ++i)); do
673                 # rewrite the symlink file with a shorter string
674                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
675                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
676         done
677
678         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
679         local devname=$(mdsdevname $mds_index)
680
681         echo "stop and checking mds${mds_index}:"
682         # e2fsck should not return error
683         stop mds${mds_index}
684         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
685         rc=$?
686
687         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
688                 error "start mds${mds_index} failed"
689         df $MOUNT > /dev/null 2>&1
690         [ $rc -eq 0 ] ||
691                 error "e2fsck detected error for short/long symlink: rc=$rc"
692         rm -f $wdir/*
693 }
694 run_test 17m "run e2fsck against MDT which contains short/long symlink"
695
696 check_fs_consistency_17n() {
697         local mdt_index
698         local rc=0
699
700         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
701         # so it only check MDT1/MDT2 instead of all of MDTs.
702         for mdt_index in 1 2; do
703                 local devname=$(mdsdevname $mdt_index)
704                 # e2fsck should not return error
705                 stop mds${mdt_index}
706                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
707                         rc=$((rc + $?))
708
709                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
710                         error "mount mds$mdt_index failed"
711                 df $MOUNT > /dev/null 2>&1
712         done
713         return $rc
714 }
715
716 test_17n() {
717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
719         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
720         remote_mds_nodsh && skip "remote MDS with nodsh"
721         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
722         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
723                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
724
725         local i
726
727         test_mkdir $DIR/$tdir
728         for ((i=0; i<10; i++)); do
729                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
730                         error "create remote dir error $i"
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after create files under remote dir"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after unlink files under remote dir"
745
746         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
747                 skip "lustre < 2.4.50 does not support migrate mv"
748
749         for ((i = 0; i < 10; i++)); do
750                 mkdir -p $DIR/$tdir/remote_dir_${i}
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
754                         error "migrate remote dir error $i"
755         done
756         check_fs_consistency_17n || error "e2fsck report error after migration"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n || error "e2fsck report error after unlink"
764 }
765 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
766
767 test_17o() {
768         remote_mds_nodsh && skip "remote MDS with nodsh"
769         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
770                 skip "Need MDS version at least 2.3.64"
771
772         local wdir=$DIR/${tdir}o
773         local mdt_index
774         local rc=0
775
776         test_mkdir $wdir
777         touch $wdir/$tfile
778         mdt_index=$($LFS getstripe -m $wdir/$tfile)
779         mdt_index=$((mdt_index + 1))
780
781         cancel_lru_locks mdc
782         #fail mds will wait the failover finish then set
783         #following fail_loc to avoid interfer the recovery process.
784         fail mds${mdt_index}
785
786         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
787         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
788         ls -l $wdir/$tfile && rc=1
789         do_facet mds${mdt_index} lctl set_param fail_loc=0
790         [[ $rc -eq 0 ]] || error "stat file should fail"
791 }
792 run_test 17o "stat file with incompat LMA feature"
793
794 test_18() {
795         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
796         ls $DIR || error "Failed to ls $DIR: $?"
797 }
798 run_test 18 "touch .../f ; ls ... =============================="
799
800 test_19a() {
801         touch $DIR/$tfile
802         ls -l $DIR
803         rm $DIR/$tfile
804         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
805 }
806 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
807
808 test_19b() {
809         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
810 }
811 run_test 19b "ls -l .../f19 (should return error) =============="
812
813 test_19c() {
814         [ $RUNAS_ID -eq $UID ] &&
815                 skip_env "RUNAS_ID = UID = $UID -- skipping"
816
817         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
818 }
819 run_test 19c "$RUNAS touch .../f19 (should return error) =="
820
821 test_19d() {
822         cat $DIR/f19 && error || true
823 }
824 run_test 19d "cat .../f19 (should return error) =============="
825
826 test_20() {
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 20 "touch .../f ; ls -l ..."
836
837 test_21() {
838         test_mkdir $DIR/$tdir
839         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
840         ln -s dangle $DIR/$tdir/link
841         echo foo >> $DIR/$tdir/link
842         cat $DIR/$tdir/dangle
843         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
844         $CHECKSTAT -f -t file $DIR/$tdir/link ||
845                 error "$tdir/link not linked to a file"
846 }
847 run_test 21 "write to dangling link"
848
849 test_22() {
850         local wdir=$DIR/$tdir
851         test_mkdir $wdir
852         chown $RUNAS_ID:$RUNAS_GID $wdir
853         (cd $wdir || error "cd $wdir failed";
854                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
855                 $RUNAS tar xf -)
856         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
857         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
858         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
859                 error "checkstat -u failed"
860 }
861 run_test 22 "unpack tar archive as non-root user"
862
863 # was test_23
864 test_23a() {
865         test_mkdir $DIR/$tdir
866         local file=$DIR/$tdir/$tfile
867
868         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
869         openfile -f O_CREAT:O_EXCL $file &&
870                 error "$file recreate succeeded" || true
871 }
872 run_test 23a "O_CREAT|O_EXCL in subdir"
873
874 test_23b() { # bug 18988
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         rm -f $file
879         echo foo > $file || error "write filed"
880         echo bar >> $file || error "append filed"
881         $CHECKSTAT -s 8 $file || error "wrong size"
882         rm $file
883 }
884 run_test 23b "O_APPEND check"
885
886 # LU-9409, size with O_APPEND and tiny writes
887 test_23c() {
888         local file=$DIR/$tfile
889
890         # single dd
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
892         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
893         rm -f $file
894
895         # racing tiny writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
898         wait
899         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
900         rm -f $file
901
902         #racing tiny & normal writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
905         wait
906         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
907         rm -f $file
908
909         #racing tiny & normal writes 2, ugly numbers
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
912         wait
913         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
914         rm -f $file
915 }
916 run_test 23c "O_APPEND size checks for tiny writes"
917
918 # LU-11069 file offset is correct after appending writes
919 test_23d() {
920         local file=$DIR/$tfile
921         local offset
922
923         echo CentaurHauls > $file
924         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
925         if ((offset != 26)); then
926                 error "wrong offset, expected 26, got '$offset'"
927         fi
928 }
929 run_test 23d "file offset is correct after appending writes"
930
931 # rename sanity
932 test_24a() {
933         echo '-- same directory rename'
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.1
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
938 }
939 run_test 24a "rename file to non-existent target"
940
941 test_24b() {
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.{1,2}
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
946         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
947 }
948 run_test 24b "rename file to existing target"
949
950 test_24c() {
951         test_mkdir $DIR/$tdir
952         test_mkdir $DIR/$tdir/d$testnum.1
953         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
954         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
955         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
956 }
957 run_test 24c "rename directory to non-existent target"
958
959 test_24d() {
960         test_mkdir -c1 $DIR/$tdir
961         test_mkdir -c1 $DIR/$tdir/d$testnum.1
962         test_mkdir -c1 $DIR/$tdir/d$testnum.2
963         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24d "rename directory to existing target"
968
969 test_24e() {
970         echo '-- cross directory renames --'
971         test_mkdir $DIR/R5a
972         test_mkdir $DIR/R5b
973         touch $DIR/R5a/f
974         mv $DIR/R5a/f $DIR/R5b/g
975         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
976         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
977 }
978 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
979
980 test_24f() {
981         test_mkdir $DIR/R6a
982         test_mkdir $DIR/R6b
983         touch $DIR/R6a/f $DIR/R6b/g
984         mv $DIR/R6a/f $DIR/R6b/g
985         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
986         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
987 }
988 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
989
990 test_24g() {
991         test_mkdir $DIR/R7a
992         test_mkdir $DIR/R7b
993         test_mkdir $DIR/R7a/d
994         mv $DIR/R7a/d $DIR/R7b/e
995         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
996         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
997 }
998 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
999
1000 test_24h() {
1001         test_mkdir -c1 $DIR/R8a
1002         test_mkdir -c1 $DIR/R8b
1003         test_mkdir -c1 $DIR/R8a/d
1004         test_mkdir -c1 $DIR/R8b/e
1005         mrename $DIR/R8a/d $DIR/R8b/e
1006         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1007         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1008 }
1009 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1010
1011 test_24i() {
1012         echo "-- rename error cases"
1013         test_mkdir $DIR/R9
1014         test_mkdir $DIR/R9/a
1015         touch $DIR/R9/f
1016         mrename $DIR/R9/f $DIR/R9/a
1017         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1018         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1019         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1020 }
1021 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1022
1023 test_24j() {
1024         test_mkdir $DIR/R10
1025         mrename $DIR/R10/f $DIR/R10/g
1026         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1027         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1028         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1029 }
1030 run_test 24j "source does not exist ============================"
1031
1032 test_24k() {
1033         test_mkdir $DIR/R11a
1034         test_mkdir $DIR/R11a/d
1035         touch $DIR/R11a/f
1036         mv $DIR/R11a/f $DIR/R11a/d
1037         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1038         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1039 }
1040 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1041
1042 # bug 2429 - rename foo foo foo creates invalid file
1043 test_24l() {
1044         f="$DIR/f24l"
1045         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1046 }
1047 run_test 24l "Renaming a file to itself ========================"
1048
1049 test_24m() {
1050         f="$DIR/f24m"
1051         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1052         # on ext3 this does not remove either the source or target files
1053         # though the "expected" operation would be to remove the source
1054         $CHECKSTAT -t file ${f} || error "${f} missing"
1055         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1056 }
1057 run_test 24m "Renaming a file to a hard link to itself ========="
1058
1059 test_24n() {
1060     f="$DIR/f24n"
1061     # this stats the old file after it was renamed, so it should fail
1062     touch ${f}
1063     $CHECKSTAT ${f} || error "${f} missing"
1064     mv ${f} ${f}.rename
1065     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1066     $CHECKSTAT -a ${f} || error "${f} exists"
1067 }
1068 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1069
1070 test_24o() {
1071         test_mkdir $DIR/$tdir
1072         rename_many -s random -v -n 10 $DIR/$tdir
1073 }
1074 run_test 24o "rename of files during htree split"
1075
1076 test_24p() {
1077         test_mkdir $DIR/R12a
1078         test_mkdir $DIR/R12b
1079         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1080         mrename $DIR/R12a $DIR/R12b
1081         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1082         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1083         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1084         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1085 }
1086 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1087
1088 cleanup_multiop_pause() {
1089         trap 0
1090         kill -USR1 $MULTIPID
1091 }
1092
1093 test_24q() {
1094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1095
1096         test_mkdir $DIR/R13a
1097         test_mkdir $DIR/R13b
1098         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1099         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1100         MULTIPID=$!
1101
1102         trap cleanup_multiop_pause EXIT
1103         mrename $DIR/R13a $DIR/R13b
1104         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1105         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1106         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1108         cleanup_multiop_pause
1109         wait $MULTIPID || error "multiop close failed"
1110 }
1111 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1112
1113 test_24r() { #bug 3789
1114         test_mkdir $DIR/R14a
1115         test_mkdir $DIR/R14a/b
1116         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1117         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1118         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1119 }
1120 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1121
1122 test_24s() {
1123         test_mkdir $DIR/R15a
1124         test_mkdir $DIR/R15a/b
1125         test_mkdir $DIR/R15a/b/c
1126         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1128         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1129 }
1130 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1131 test_24t() {
1132         test_mkdir $DIR/R16a
1133         test_mkdir $DIR/R16a/b
1134         test_mkdir $DIR/R16a/b/c
1135         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1137         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1138 }
1139 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1140
1141 test_24u() { # bug12192
1142         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1143         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1144 }
1145 run_test 24u "create stripe file"
1146
1147 simple_cleanup_common() {
1148         local rc=0
1149         trap 0
1150         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1151
1152         local start=$SECONDS
1153         rm -rf $DIR/$tdir
1154         rc=$?
1155         wait_delete_completed
1156         echo "cleanup time $((SECONDS - start))"
1157         return $rc
1158 }
1159
1160 max_pages_per_rpc() {
1161         local mdtname="$(printf "MDT%04x" ${1:-0})"
1162         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1163 }
1164
1165 test_24v() {
1166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1167
1168         local nrfiles=${COUNT:-100000}
1169         local fname="$DIR/$tdir/$tfile"
1170
1171         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1172         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1173
1174         test_mkdir "$(dirname $fname)"
1175         # assume MDT0000 has the fewest inodes
1176         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1177         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1178         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1179
1180         trap simple_cleanup_common EXIT
1181
1182         createmany -m "$fname" $nrfiles
1183
1184         cancel_lru_locks mdc
1185         lctl set_param mdc.*.stats clear
1186
1187         # was previously test_24D: LU-6101
1188         # readdir() returns correct number of entries after cursor reload
1189         local num_ls=$(ls $DIR/$tdir | wc -l)
1190         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1191         local num_all=$(ls -a $DIR/$tdir | wc -l)
1192         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1193                 [ $num_all -ne $((nrfiles + 2)) ]; then
1194                         error "Expected $nrfiles files, got $num_ls " \
1195                                 "($num_uniq unique $num_all .&..)"
1196         fi
1197         # LU-5 large readdir
1198         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1199         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1200         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1201         # take into account of overhead in lu_dirpage header and end mark in
1202         # each page, plus one in rpc_num calculation.
1203         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1204         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1205         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1206         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1207         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1208         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1209         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1210         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1211                 error "large readdir doesn't take effect: " \
1212                       "$mds_readpage should be about $rpc_max"
1213
1214         simple_cleanup_common
1215 }
1216 run_test 24v "list large directory (test hash collision, b=17560)"
1217
1218 test_24w() { # bug21506
1219         SZ1=234852
1220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1221         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1222         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1223         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1224         [[ "$SZ1" -eq "$SZ2" ]] ||
1225                 error "Error reading at the end of the file $tfile"
1226 }
1227 run_test 24w "Reading a file larger than 4Gb"
1228
1229 test_24x() {
1230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1232         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1233                 skip "Need MDS version at least 2.7.56"
1234
1235         local MDTIDX=1
1236         local remote_dir=$DIR/$tdir/remote_dir
1237
1238         test_mkdir $DIR/$tdir
1239         $LFS mkdir -i $MDTIDX $remote_dir ||
1240                 error "create remote directory failed"
1241
1242         test_mkdir $DIR/$tdir/src_dir
1243         touch $DIR/$tdir/src_file
1244         test_mkdir $remote_dir/tgt_dir
1245         touch $remote_dir/tgt_file
1246
1247         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1248                 error "rename dir cross MDT failed!"
1249
1250         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1251                 error "rename file cross MDT failed!"
1252
1253         touch $DIR/$tdir/ln_file
1254         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1255                 error "ln file cross MDT failed"
1256
1257         rm -rf $DIR/$tdir || error "Can not delete directories"
1258 }
1259 run_test 24x "cross MDT rename/link"
1260
1261 test_24y() {
1262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1264
1265         local remote_dir=$DIR/$tdir/remote_dir
1266         local mdtidx=1
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $mdtidx $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $remote_dir/src_dir
1273         touch $remote_dir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename subdir in the same remote dir failed!"
1279
1280         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1281                 error "rename files in the same remote dir failed!"
1282
1283         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1284                 error "link files in the same remote dir failed!"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24y "rename/link on the same dir should succeed"
1289
1290 test_24z() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1293                 skip "Need MDS version at least 2.12.51"
1294
1295         local index
1296
1297         for index in 0 1; do
1298                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1299                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1300         done
1301
1302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1303
1304         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1305         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1306
1307         local mdts=$(comma_list $(mdts_nodes))
1308
1309         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1310         stack_trap "do_nodes $mdts $LCTL \
1311                 set_param mdt.*.enable_remote_rename=1" EXIT
1312
1313         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1314
1315         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1316         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1317 }
1318 run_test 24z "cross-MDT rename is done as cp"
1319
1320 test_24A() { # LU-3182
1321         local NFILES=5000
1322
1323         rm -rf $DIR/$tdir
1324         test_mkdir $DIR/$tdir
1325         trap simple_cleanup_common EXIT
1326         createmany -m $DIR/$tdir/$tfile $NFILES
1327         local t=$(ls $DIR/$tdir | wc -l)
1328         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1329         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1330         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1331            [ $v -ne $((NFILES + 2)) ] ; then
1332                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1333         fi
1334
1335         simple_cleanup_common || error "Can not delete directories"
1336 }
1337 run_test 24A "readdir() returns correct number of entries."
1338
1339 test_24B() { # LU-4805
1340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1341
1342         local count
1343
1344         test_mkdir $DIR/$tdir
1345         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1346                 error "create striped dir failed"
1347
1348         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1349         [ $count -eq 2 ] || error "Expected 2, got $count"
1350
1351         touch $DIR/$tdir/striped_dir/a
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 3 ] || error "Expected 3, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/.f
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 4 ] || error "Expected 4, got $count"
1360
1361         rm -rf $DIR/$tdir || error "Can not delete directories"
1362 }
1363 run_test 24B "readdir for striped dir return correct number of entries"
1364
1365 test_24C() {
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         mkdir $DIR/$tdir
1369         mkdir $DIR/$tdir/d0
1370         mkdir $DIR/$tdir/d1
1371
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1373                 error "create striped dir failed"
1374
1375         cd $DIR/$tdir/d0/striped_dir
1376
1377         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1378         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1379         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d0_ino" = "$parent_ino" ] ||
1382                 error ".. wrong, expect $d0_ino, get $parent_ino"
1383
1384         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1385                 error "mv striped dir failed"
1386
1387         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d1_ino" = "$parent_ino" ] ||
1390                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1391 }
1392 run_test 24C "check .. in striped dir"
1393
1394 test_24E() {
1395         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1397
1398         mkdir -p $DIR/$tdir
1399         mkdir $DIR/$tdir/src_dir
1400         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1401                 error "create remote source failed"
1402
1403         touch $DIR/$tdir/src_dir/src_child/a
1404
1405         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1406                 error "create remote target dir failed"
1407
1408         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "create remote target child failed"
1410
1411         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1412                 error "rename dir cross MDT failed!"
1413
1414         find $DIR/$tdir
1415
1416         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1417                 error "src_child still exists after rename"
1418
1419         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1420                 error "missing file(a) after rename"
1421
1422         rm -rf $DIR/$tdir || error "Can not delete directories"
1423 }
1424 run_test 24E "cross MDT rename/link"
1425
1426 test_24F () {
1427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1428
1429         local repeats=1000
1430         [ "$SLOW" = "no" ] && repeats=100
1431
1432         mkdir -p $DIR/$tdir
1433
1434         echo "$repeats repeats"
1435         for ((i = 0; i < repeats; i++)); do
1436                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1437                 touch $DIR/$tdir/test/a || error "touch fails"
1438                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1439                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1440         done
1441
1442         true
1443 }
1444 run_test 24F "hash order vs readdir (LU-11330)"
1445
1446 test_25a() {
1447         echo '== symlink sanity ============================================='
1448
1449         test_mkdir $DIR/d25
1450         ln -s d25 $DIR/s25
1451         touch $DIR/s25/foo ||
1452                 error "File creation in symlinked directory failed"
1453 }
1454 run_test 25a "create file in symlinked directory ==============="
1455
1456 test_25b() {
1457         [ ! -d $DIR/d25 ] && test_25a
1458         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1459 }
1460 run_test 25b "lookup file in symlinked directory ==============="
1461
1462 test_26a() {
1463         test_mkdir $DIR/d26
1464         test_mkdir $DIR/d26/d26-2
1465         ln -s d26/d26-2 $DIR/s26
1466         touch $DIR/s26/foo || error "File creation failed"
1467 }
1468 run_test 26a "multiple component symlink ======================="
1469
1470 test_26b() {
1471         test_mkdir -p $DIR/$tdir/d26-2
1472         ln -s $tdir/d26-2/foo $DIR/s26-2
1473         touch $DIR/s26-2 || error "File creation failed"
1474 }
1475 run_test 26b "multiple component symlink at end of lookup ======"
1476
1477 test_26c() {
1478         test_mkdir $DIR/d26.2
1479         touch $DIR/d26.2/foo
1480         ln -s d26.2 $DIR/s26.2-1
1481         ln -s s26.2-1 $DIR/s26.2-2
1482         ln -s s26.2-2 $DIR/s26.2-3
1483         chmod 0666 $DIR/s26.2-3/foo
1484 }
1485 run_test 26c "chain of symlinks"
1486
1487 # recursive symlinks (bug 439)
1488 test_26d() {
1489         ln -s d26-3/foo $DIR/d26-3
1490 }
1491 run_test 26d "create multiple component recursive symlink"
1492
1493 test_26e() {
1494         [ ! -h $DIR/d26-3 ] && test_26d
1495         rm $DIR/d26-3
1496 }
1497 run_test 26e "unlink multiple component recursive symlink"
1498
1499 # recursive symlinks (bug 7022)
1500 test_26f() {
1501         test_mkdir $DIR/$tdir
1502         test_mkdir $DIR/$tdir/$tfile
1503         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1504         test_mkdir -p lndir/bar1
1505         test_mkdir $DIR/$tdir/$tfile/$tfile
1506         cd $tfile                || error "cd $tfile failed"
1507         ln -s .. dotdot          || error "ln dotdot failed"
1508         ln -s dotdot/lndir lndir || error "ln lndir failed"
1509         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1510         output=`ls $tfile/$tfile/lndir/bar1`
1511         [ "$output" = bar1 ] && error "unexpected output"
1512         rm -r $tfile             || error "rm $tfile failed"
1513         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1514 }
1515 run_test 26f "rm -r of a directory which has recursive symlink"
1516
1517 test_27a() {
1518         test_mkdir $DIR/$tdir
1519         $LFS getstripe $DIR/$tdir
1520         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1522         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1523 }
1524 run_test 27a "one stripe file"
1525
1526 test_27b() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1528
1529         test_mkdir $DIR/$tdir
1530         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1531         $LFS getstripe -c $DIR/$tdir/$tfile
1532         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1533                 error "two-stripe file doesn't have two stripes"
1534
1535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1536 }
1537 run_test 27b "create and write to two stripe file"
1538
1539 # 27c family tests specific striping, setstripe -o
1540 test_27ca() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1"
1544
1545         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1546         $LFS getstripe -i $DIR/$tdir/$tfile
1547         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1548                 error "stripe not on specified OST"
1549
1550         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1551 }
1552 run_test 27ca "one stripe on specified OST"
1553
1554 test_27cb() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1,0"
1558         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1559         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1560         echo "$getstripe"
1561
1562         # Strip getstripe output to a space separated list of OSTs
1563         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1564                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1565         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1566                 error "stripes not on specified OSTs"
1567
1568         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1569 }
1570 run_test 27cb "two stripes on specified OSTs"
1571
1572 test_27cc() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1574         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1575                 skip "server does not support overstriping"
1576
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cc "two stripes on the same OST"
1592
1593 test_27cd() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1596                 skip "server does not support overstriping"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="0,1,1,0"
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1600         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1601         echo "$getstripe"
1602
1603         # Strip getstripe output to a space separated list of OSTs
1604         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1605                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1606         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1607                 error "stripes not on specified OSTs"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27cd "four stripes on two OSTs"
1612
1613 test_27ce() {
1614         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1615                 skip_env "too many osts, skipping"
1616         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1617                 skip "server does not support overstriping"
1618         # We do one more stripe than we have OSTs
1619         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1620                 skip_env "ea_inode feature disabled"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts=""
1624         for i in $(seq 0 $OSTCOUNT);
1625         do
1626                 osts=$osts"0"
1627                 if [ $i -ne $OSTCOUNT ]; then
1628                         osts=$osts","
1629                 fi
1630         done
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27ce "more stripes than OSTs with -o"
1644
1645 test_27cf() {
1646         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1647         local pid=0
1648
1649         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1650         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1651         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1653                 error "failed to set $osp_proc=0"
1654
1655         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1656         pid=$!
1657         sleep 1
1658         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1660                 error "failed to set $osp_proc=1"
1661         wait $pid
1662         [[ $pid -ne 0 ]] ||
1663                 error "should return error due to $osp_proc=0"
1664 }
1665 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1666
1667 test_27d() {
1668         test_mkdir $DIR/$tdir
1669         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1670                 error "setstripe failed"
1671         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1673 }
1674 run_test 27d "create file with default settings"
1675
1676 test_27e() {
1677         # LU-5839 adds check for existed layout before setting it
1678         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1679                 skip "Need MDS version at least 2.7.56"
1680
1681         test_mkdir $DIR/$tdir
1682         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1683         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1684         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1685 }
1686 run_test 27e "setstripe existing file (should return error)"
1687
1688 test_27f() {
1689         test_mkdir $DIR/$tdir
1690         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1691                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1692         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1693                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1695         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1696 }
1697 run_test 27f "setstripe with bad stripe size (should return error)"
1698
1699 test_27g() {
1700         test_mkdir $DIR/$tdir
1701         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1702         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1703                 error "$DIR/$tdir/$tfile has object"
1704 }
1705 run_test 27g "$LFS getstripe with no objects"
1706
1707 test_27ga() {
1708         test_mkdir $DIR/$tdir
1709         touch $DIR/$tdir/$tfile || error "touch failed"
1710         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1711         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1712         local rc=$?
1713         (( rc == 2 )) || error "getstripe did not return ENOENT"
1714 }
1715 run_test 27ga "$LFS getstripe with missing file (should return error)"
1716
1717 test_27i() {
1718         test_mkdir $DIR/$tdir
1719         touch $DIR/$tdir/$tfile || error "touch failed"
1720         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1721                 error "missing objects"
1722 }
1723 run_test 27i "$LFS getstripe with some objects"
1724
1725 test_27j() {
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1728                 error "setstripe failed" || true
1729 }
1730 run_test 27j "setstripe with bad stripe offset (should return error)"
1731
1732 test_27k() { # bug 2844
1733         test_mkdir $DIR/$tdir
1734         local file=$DIR/$tdir/$tfile
1735         local ll_max_blksize=$((4 * 1024 * 1024))
1736         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1737         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1738         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1739         dd if=/dev/zero of=$file bs=4k count=1
1740         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1741         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1742 }
1743 run_test 27k "limit i_blksize for broken user apps"
1744
1745 test_27l() {
1746         mcreate $DIR/$tfile || error "creating file"
1747         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1748                 error "setstripe should have failed" || true
1749 }
1750 run_test 27l "check setstripe permissions (should return error)"
1751
1752 test_27m() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754
1755         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1756                 skip_env "multiple clients -- skipping"
1757
1758         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1759                    head -n1)
1760         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1761                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1762         fi
1763         trap simple_cleanup_common EXIT
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1767                 error "dd should fill OST0"
1768         i=2
1769         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1770                 i=$((i + 1))
1771                 [ $i -gt 256 ] && break
1772         done
1773         i=$((i + 1))
1774         touch $DIR/$tdir/$tfile.$i
1775         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1776             awk '{print $1}'| grep -w "0") ] &&
1777                 error "OST0 was full but new created file still use it"
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         simple_cleanup_common
1784 }
1785 run_test 27m "create file while OST0 was full"
1786
1787 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1788 # if the OST isn't full anymore.
1789 reset_enospc() {
1790         local ostidx=${1:-""}
1791         local delay
1792         local ready
1793         local get_prealloc
1794
1795         local list=$(comma_list $(osts_nodes))
1796         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1797
1798         do_nodes $list lctl set_param fail_loc=0
1799         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1800         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1801                 awk '{print $1 * 2;exit;}')
1802         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1803                         grep -v \"^0$\""
1804         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1805 }
1806
1807 __exhaust_precreations() {
1808         local OSTIDX=$1
1809         local FAILLOC=$2
1810         local FAILIDX=${3:-$OSTIDX}
1811         local ofacet=ost$((OSTIDX + 1))
1812
1813         test_mkdir -p -c1 $DIR/$tdir
1814         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1815         local mfacet=mds$((mdtidx + 1))
1816         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1817
1818         local OST=$(ostname_from_index $OSTIDX)
1819
1820         # on the mdt's osc
1821         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1822         local last_id=$(do_facet $mfacet lctl get_param -n \
1823                         osp.$mdtosc_proc1.prealloc_last_id)
1824         local next_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_next_id)
1826
1827         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1828         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1829
1830         test_mkdir -p $DIR/$tdir/${OST}
1831         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1832 #define OBD_FAIL_OST_ENOSPC              0x215
1833         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1834         echo "Creating to objid $last_id on ost $OST..."
1835         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1836         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1837         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1838 }
1839
1840 exhaust_precreations() {
1841         __exhaust_precreations $1 $2 $3
1842         sleep_maxage
1843 }
1844
1845 exhaust_all_precreations() {
1846         local i
1847         for (( i=0; i < OSTCOUNT; i++ )) ; do
1848                 __exhaust_precreations $i $1 -1
1849         done
1850         sleep_maxage
1851 }
1852
1853 test_27n() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1856         remote_mds_nodsh && skip "remote MDS with nodsh"
1857         remote_ost_nodsh && skip "remote OST with nodsh"
1858
1859         reset_enospc
1860         rm -f $DIR/$tdir/$tfile
1861         exhaust_precreations 0 0x80000215
1862         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1863         touch $DIR/$tdir/$tfile || error "touch failed"
1864         $LFS getstripe $DIR/$tdir/$tfile
1865         reset_enospc
1866 }
1867 run_test 27n "create file with some full OSTs"
1868
1869 test_27o() {
1870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1872         remote_mds_nodsh && skip "remote MDS with nodsh"
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874
1875         reset_enospc
1876         rm -f $DIR/$tdir/$tfile
1877         exhaust_all_precreations 0x215
1878
1879         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1880
1881         reset_enospc
1882         rm -rf $DIR/$tdir/*
1883 }
1884 run_test 27o "create file with all full OSTs (should error)"
1885
1886 test_27p() {
1887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1889         remote_mds_nodsh && skip "remote MDS with nodsh"
1890         remote_ost_nodsh && skip "remote OST with nodsh"
1891
1892         reset_enospc
1893         rm -f $DIR/$tdir/$tfile
1894         test_mkdir $DIR/$tdir
1895
1896         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1897         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1898         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1899
1900         exhaust_precreations 0 0x80000215
1901         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1902         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1903         $LFS getstripe $DIR/$tdir/$tfile
1904
1905         reset_enospc
1906 }
1907 run_test 27p "append to a truncated file with some full OSTs"
1908
1909 test_27q() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917
1918         test_mkdir $DIR/$tdir
1919         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1920         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1921                 error "truncate $DIR/$tdir/$tfile failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_all_precreations 0x215
1925
1926         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1928
1929         reset_enospc
1930 }
1931 run_test 27q "append to truncated file with all OSTs full (should error)"
1932
1933 test_27r() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941         exhaust_precreations 0 0x80000215
1942
1943         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1944
1945         reset_enospc
1946 }
1947 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1948
1949 test_27s() { # bug 10725
1950         test_mkdir $DIR/$tdir
1951         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1952         local stripe_count=0
1953         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1954         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1955                 error "stripe width >= 2^32 succeeded" || true
1956
1957 }
1958 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1959
1960 test_27t() { # bug 10864
1961         WDIR=$(pwd)
1962         WLFS=$(which lfs)
1963         cd $DIR
1964         touch $tfile
1965         $WLFS getstripe $tfile
1966         cd $WDIR
1967 }
1968 run_test 27t "check that utils parse path correctly"
1969
1970 test_27u() { # bug 4900
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973
1974         local index
1975         local list=$(comma_list $(mdts_nodes))
1976
1977 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1978         do_nodes $list $LCTL set_param fail_loc=0x139
1979         test_mkdir -p $DIR/$tdir
1980         trap simple_cleanup_common EXIT
1981         createmany -o $DIR/$tdir/t- 1000
1982         do_nodes $list $LCTL set_param fail_loc=0
1983
1984         TLOG=$TMP/$tfile.getstripe
1985         $LFS getstripe $DIR/$tdir > $TLOG
1986         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1987         unlinkmany $DIR/$tdir/t- 1000
1988         trap 0
1989         [[ $OBJS -gt 0 ]] &&
1990                 error "$OBJS objects created on OST-0. See $TLOG" ||
1991                 rm -f $TLOG
1992 }
1993 run_test 27u "skip object creation on OSC w/o objects"
1994
1995 test_27v() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         exhaust_all_precreations 0x215
2002         reset_enospc
2003
2004         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2005
2006         touch $DIR/$tdir/$tfile
2007         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2008         # all except ost1
2009         for (( i=1; i < OSTCOUNT; i++ )); do
2010                 do_facet ost$i lctl set_param fail_loc=0x705
2011         done
2012         local START=`date +%s`
2013         createmany -o $DIR/$tdir/$tfile 32
2014
2015         local FINISH=`date +%s`
2016         local TIMEOUT=`lctl get_param -n timeout`
2017         local PROCESS=$((FINISH - START))
2018         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2019                error "$FINISH - $START >= $TIMEOUT / 2"
2020         sleep $((TIMEOUT / 2 - PROCESS))
2021         reset_enospc
2022 }
2023 run_test 27v "skip object creation on slow OST"
2024
2025 test_27w() { # bug 10997
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2028         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2029                 error "stripe size $size != 65536" || true
2030         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2031                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2032 }
2033 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2034
2035 test_27wa() {
2036         [[ $OSTCOUNT -lt 2 ]] &&
2037                 skip_env "skipping multiple stripe count/offset test"
2038
2039         test_mkdir $DIR/$tdir
2040         for i in $(seq 1 $OSTCOUNT); do
2041                 offset=$((i - 1))
2042                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2043                         error "setstripe -c $i -i $offset failed"
2044                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2045                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2046                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2047                 [ $index -ne $offset ] &&
2048                         error "stripe offset $index != $offset" || true
2049         done
2050 }
2051 run_test 27wa "check $LFS setstripe -c -i options"
2052
2053 test_27x() {
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057
2058         OFFSET=$(($OSTCOUNT - 1))
2059         OSTIDX=0
2060         local OST=$(ostname_from_index $OSTIDX)
2061
2062         test_mkdir $DIR/$tdir
2063         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2064         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2065         sleep_maxage
2066         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2067         for i in $(seq 0 $OFFSET); do
2068                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2069                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2070                 error "OST0 was degraded but new created file still use it"
2071         done
2072         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2073 }
2074 run_test 27x "create files while OST0 is degraded"
2075
2076 test_27y() {
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         remote_mds_nodsh && skip "remote MDS with nodsh"
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2083         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2084                 osp.$mdtosc.prealloc_last_id)
2085         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_next_id)
2087         local fcount=$((last_id - next_id))
2088         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2089         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2090
2091         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2092                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2093         local OST_DEACTIVE_IDX=-1
2094         local OSC
2095         local OSTIDX
2096         local OST
2097
2098         for OSC in $MDS_OSCS; do
2099                 OST=$(osc_to_ost $OSC)
2100                 OSTIDX=$(index_from_ostuuid $OST)
2101                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2102                         OST_DEACTIVE_IDX=$OSTIDX
2103                 fi
2104                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2105                         echo $OSC "is Deactivated:"
2106                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2107                 fi
2108         done
2109
2110         OSTIDX=$(index_from_ostuuid $OST)
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2113
2114         for OSC in $MDS_OSCS; do
2115                 OST=$(osc_to_ost $OSC)
2116                 OSTIDX=$(index_from_ostuuid $OST)
2117                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2118                         echo $OST "is degraded:"
2119                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2120                                                 obdfilter.$OST.degraded=1
2121                 fi
2122         done
2123
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $fcount
2126
2127         for OSC in $MDS_OSCS; do
2128                 OST=$(osc_to_ost $OSC)
2129                 OSTIDX=$(index_from_ostuuid $OST)
2130                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2131                         echo $OST "is recovered from degraded:"
2132                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2133                                                 obdfilter.$OST.degraded=0
2134                 else
2135                         do_facet $SINGLEMDS lctl --device %$OSC activate
2136                 fi
2137         done
2138
2139         # all osp devices get activated, hence -1 stripe count restored
2140         local stripe_count=0
2141
2142         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2143         # devices get activated.
2144         sleep_maxage
2145         $LFS setstripe -c -1 $DIR/$tfile
2146         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2147         rm -f $DIR/$tfile
2148         [ $stripe_count -ne $OSTCOUNT ] &&
2149                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2150         return 0
2151 }
2152 run_test 27y "create files while OST0 is degraded and the rest inactive"
2153
2154 check_seq_oid()
2155 {
2156         log "check file $1"
2157
2158         lmm_count=$($LFS getstripe -c $1)
2159         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2160         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2161
2162         local old_ifs="$IFS"
2163         IFS=$'[:]'
2164         fid=($($LFS path2fid $1))
2165         IFS="$old_ifs"
2166
2167         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2168         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2169
2170         # compare lmm_seq and lu_fid->f_seq
2171         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2172         # compare lmm_object_id and lu_fid->oid
2173         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2174
2175         # check the trusted.fid attribute of the OST objects of the file
2176         local have_obdidx=false
2177         local stripe_nr=0
2178         $LFS getstripe $1 | while read obdidx oid hex seq; do
2179                 # skip lines up to and including "obdidx"
2180                 [ -z "$obdidx" ] && break
2181                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2182                 $have_obdidx || continue
2183
2184                 local ost=$((obdidx + 1))
2185                 local dev=$(ostdevname $ost)
2186                 local oid_hex
2187
2188                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2189
2190                 seq=$(echo $seq | sed -e "s/^0x//g")
2191                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2192                         oid_hex=$(echo $oid)
2193                 else
2194                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2195                 fi
2196                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2197
2198                 local ff=""
2199                 #
2200                 # Don't unmount/remount the OSTs if we don't need to do that.
2201                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2202                 # update too, until that use mount/ll_decode_filter_fid/mount.
2203                 # Re-enable when debugfs will understand new filter_fid.
2204                 #
2205                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2206                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2207                                 $dev 2>/dev/null" | grep "parent=")
2208                 fi
2209                 if [ -z "$ff" ]; then
2210                         stop ost$ost
2211                         mount_fstype ost$ost
2212                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2213                                 $(facet_mntpt ost$ost)/$obj_file)
2214                         unmount_fstype ost$ost
2215                         start ost$ost $dev $OST_MOUNT_OPTS
2216                         clients_up
2217                 fi
2218
2219                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2220
2221                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2222
2223                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2224                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2225                 #
2226                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2227                 #       stripe_size=1048576 component_id=1 component_start=0 \
2228                 #       component_end=33554432
2229                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2230                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2231                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2232                 local ff_pstripe
2233                 if grep -q 'stripe=' <<<$ff; then
2234                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2235                 else
2236                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2237                         # into f_ver in this case.  See comment on ff_parent.
2238                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2239                 fi
2240
2241                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2242                 [ $ff_pseq = $lmm_seq ] ||
2243                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2244                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2245                 [ $ff_poid = $lmm_oid ] ||
2246                         error "FF parent OID $ff_poid != $lmm_oid"
2247                 (($ff_pstripe == $stripe_nr)) ||
2248                         error "FF stripe $ff_pstripe != $stripe_nr"
2249
2250                 stripe_nr=$((stripe_nr + 1))
2251                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2252                         continue
2253                 if grep -q 'stripe_count=' <<<$ff; then
2254                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2255                                             -e 's/ .*//' <<<$ff)
2256                         [ $lmm_count = $ff_scnt ] ||
2257                                 error "FF stripe count $lmm_count != $ff_scnt"
2258                 fi
2259         done
2260 }
2261
2262 test_27z() {
2263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2264         remote_ost_nodsh && skip "remote OST with nodsh"
2265
2266         test_mkdir $DIR/$tdir
2267         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2268                 { error "setstripe -c -1 failed"; return 1; }
2269         # We need to send a write to every object to get parent FID info set.
2270         # This _should_ also work for setattr, but does not currently.
2271         # touch $DIR/$tdir/$tfile-1 ||
2272         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2273                 { error "dd $tfile-1 failed"; return 2; }
2274         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2275                 { error "setstripe -c -1 failed"; return 3; }
2276         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2277                 { error "dd $tfile-2 failed"; return 4; }
2278
2279         # make sure write RPCs have been sent to OSTs
2280         sync; sleep 5; sync
2281
2282         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2283         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2284 }
2285 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2286
2287 test_27A() { # b=19102
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289
2290         save_layout_restore_at_exit $MOUNT
2291         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2292         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2293                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2294         local default_size=$($LFS getstripe -S $MOUNT)
2295         local default_offset=$($LFS getstripe -i $MOUNT)
2296         local dsize=$(do_facet $SINGLEMDS \
2297                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2298         [ $default_size -eq $dsize ] ||
2299                 error "stripe size $default_size != $dsize"
2300         [ $default_offset -eq -1 ] ||
2301                 error "stripe offset $default_offset != -1"
2302 }
2303 run_test 27A "check filesystem-wide default LOV EA values"
2304
2305 test_27B() { # LU-2523
2306         test_mkdir $DIR/$tdir
2307         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2308         touch $DIR/$tdir/f0
2309         # open f1 with O_LOV_DELAY_CREATE
2310         # rename f0 onto f1
2311         # call setstripe ioctl on open file descriptor for f1
2312         # close
2313         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2314                 $DIR/$tdir/f0
2315
2316         rm -f $DIR/$tdir/f1
2317         # open f1 with O_LOV_DELAY_CREATE
2318         # unlink f1
2319         # call setstripe ioctl on open file descriptor for f1
2320         # close
2321         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2322
2323         # Allow multiop to fail in imitation of NFS's busted semantics.
2324         true
2325 }
2326 run_test 27B "call setstripe on open unlinked file/rename victim"
2327
2328 # 27C family tests full striping and overstriping
2329 test_27Ca() { #LU-2871
2330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2331
2332         declare -a ost_idx
2333         local index
2334         local found
2335         local i
2336         local j
2337
2338         test_mkdir $DIR/$tdir
2339         cd $DIR/$tdir
2340         for i in $(seq 0 $((OSTCOUNT - 1))); do
2341                 # set stripe across all OSTs starting from OST$i
2342                 $LFS setstripe -i $i -c -1 $tfile$i
2343                 # get striping information
2344                 ost_idx=($($LFS getstripe $tfile$i |
2345                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2346                 echo ${ost_idx[@]}
2347
2348                 # check the layout
2349                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2350                         error "${#ost_idx[@]} != $OSTCOUNT"
2351
2352                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2353                         found=0
2354                         for j in $(echo ${ost_idx[@]}); do
2355                                 if [ $index -eq $j ]; then
2356                                         found=1
2357                                         break
2358                                 fi
2359                         done
2360                         [ $found = 1 ] ||
2361                                 error "Can not find $index in ${ost_idx[@]}"
2362                 done
2363         done
2364 }
2365 run_test 27Ca "check full striping across all OSTs"
2366
2367 test_27Cb() {
2368         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2369                 skip "server does not support overstriping"
2370         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2371                 skip_env "too many osts, skipping"
2372
2373         test_mkdir -p $DIR/$tdir
2374         local setcount=$(($OSTCOUNT * 2))
2375         [ $setcount -ge 160 ] || large_xattr_enabled ||
2376                 skip_env "ea_inode feature disabled"
2377
2378         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2379                 error "setstripe failed"
2380
2381         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2382         [ $count -eq $setcount ] ||
2383                 error "stripe count $count, should be $setcount"
2384
2385         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2386                 error "overstriped should be set in pattern"
2387
2388         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2389                 error "dd failed"
2390 }
2391 run_test 27Cb "more stripes than OSTs with -C"
2392
2393 test_27Cc() {
2394         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2395                 skip "server does not support overstriping"
2396         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT - 1))
2400
2401         [ $setcount -ge 160 ] || large_xattr_enabled ||
2402                 skip_env "ea_inode feature disabled"
2403
2404         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2405                 error "setstripe failed"
2406
2407         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2408         [ $count -eq $setcount ] ||
2409                 error "stripe count $count, should be $setcount"
2410
2411         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2412                 error "overstriped should not be set in pattern"
2413
2414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2415                 error "dd failed"
2416 }
2417 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2418
2419 test_27Cd() {
2420         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2421                 skip "server does not support overstriping"
2422         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2423         large_xattr_enabled || skip_env "ea_inode feature disabled"
2424
2425         test_mkdir -p $DIR/$tdir
2426         local setcount=$LOV_MAX_STRIPE_COUNT
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2436                 error "overstriped should be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440
2441         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2442 }
2443 run_test 27Cd "test maximum stripe count"
2444
2445 test_27Ce() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         test_mkdir -p $DIR/$tdir
2449
2450         pool_add $TESTNAME || error "Pool creation failed"
2451         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2452
2453         local setcount=8
2454
2455         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2456                 error "setstripe failed"
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Ce "test pool with overstriping"
2471
2472 test_27Cf() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2476                 skip_env "too many osts, skipping"
2477
2478         test_mkdir -p $DIR/$tdir
2479
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -ge 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2485                 error "setstripe failed"
2486
2487         echo 1 > $DIR/$tdir/$tfile
2488
2489         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2490         [ $count -eq $setcount ] ||
2491                 error "stripe count $count, should be $setcount"
2492
2493         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2494                 error "overstriped should be set in pattern"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2497                 error "dd failed"
2498
2499         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2500 }
2501 run_test 27Cf "test default inheritance with overstriping"
2502
2503 test_27D() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2506         remote_mds_nodsh && skip "remote MDS with nodsh"
2507
2508         local POOL=${POOL:-testpool}
2509         local first_ost=0
2510         local last_ost=$(($OSTCOUNT - 1))
2511         local ost_step=1
2512         local ost_list=$(seq $first_ost $ost_step $last_ost)
2513         local ost_range="$first_ost $last_ost $ost_step"
2514
2515         test_mkdir $DIR/$tdir
2516         pool_add $POOL || error "pool_add failed"
2517         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2518
2519         local skip27D
2520         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2521                 skip27D+="-s 29"
2522         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2523                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2524                         skip27D+=" -s 30,31"
2525         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2526           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2527                 skip27D+=" -s 32,33"
2528         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2529                 skip27D+=" -s 34"
2530         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2531                 error "llapi_layout_test failed"
2532
2533         destroy_test_pools || error "destroy test pools failed"
2534 }
2535 run_test 27D "validate llapi_layout API"
2536
2537 # Verify that default_easize is increased from its initial value after
2538 # accessing a widely striped file.
2539 test_27E() {
2540         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2541         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2542                 skip "client does not have LU-3338 fix"
2543
2544         # 72 bytes is the minimum space required to store striping
2545         # information for a file striped across one OST:
2546         # (sizeof(struct lov_user_md_v3) +
2547         #  sizeof(struct lov_user_ost_data_v1))
2548         local min_easize=72
2549         $LCTL set_param -n llite.*.default_easize $min_easize ||
2550                 error "lctl set_param failed"
2551         local easize=$($LCTL get_param -n llite.*.default_easize)
2552
2553         [ $easize -eq $min_easize ] ||
2554                 error "failed to set default_easize"
2555
2556         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2557                 error "setstripe failed"
2558         # In order to ensure stat() call actually talks to MDS we need to
2559         # do something drastic to this file to shake off all lock, e.g.
2560         # rename it (kills lookup lock forcing cache cleaning)
2561         mv $DIR/$tfile $DIR/${tfile}-1
2562         ls -l $DIR/${tfile}-1
2563         rm $DIR/${tfile}-1
2564
2565         easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -gt $min_easize ] ||
2568                 error "default_easize not updated"
2569 }
2570 run_test 27E "check that default extended attribute size properly increases"
2571
2572 test_27F() { # LU-5346/LU-7975
2573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2574         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2575         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2576                 skip "Need MDS version at least 2.8.51"
2577         remote_ost_nodsh && skip "remote OST with nodsh"
2578
2579         test_mkdir $DIR/$tdir
2580         rm -f $DIR/$tdir/f0
2581         $LFS setstripe -c 2 $DIR/$tdir
2582
2583         # stop all OSTs to reproduce situation for LU-7975 ticket
2584         for num in $(seq $OSTCOUNT); do
2585                 stop ost$num
2586         done
2587
2588         # open/create f0 with O_LOV_DELAY_CREATE
2589         # truncate f0 to a non-0 size
2590         # close
2591         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2592
2593         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2594         # open/write it again to force delayed layout creation
2595         cat /etc/hosts > $DIR/$tdir/f0 &
2596         catpid=$!
2597
2598         # restart OSTs
2599         for num in $(seq $OSTCOUNT); do
2600                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2601                         error "ost$num failed to start"
2602         done
2603
2604         wait $catpid || error "cat failed"
2605
2606         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2607         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2608                 error "wrong stripecount"
2609
2610 }
2611 run_test 27F "Client resend delayed layout creation with non-zero size"
2612
2613 test_27G() { #LU-10629
2614         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2615                 skip "Need MDS version at least 2.11.51"
2616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2617         remote_mds_nodsh && skip "remote MDS with nodsh"
2618         local POOL=${POOL:-testpool}
2619         local ostrange="0 0 1"
2620
2621         test_mkdir $DIR/$tdir
2622         touch $DIR/$tdir/$tfile.nopool
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2625         $LFS setstripe -p $POOL $DIR/$tdir
2626
2627         local pool=$($LFS getstripe -p $DIR/$tdir)
2628
2629         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2630         touch $DIR/$tdir/$tfile.default
2631         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2632         $LFS find $DIR/$tdir -type f --pool $POOL
2633         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2634         [[ "$found" == "2" ]] ||
2635                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2636
2637         $LFS setstripe -d $DIR/$tdir
2638
2639         pool=$($LFS getstripe -p -d $DIR/$tdir)
2640
2641         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2642 }
2643 run_test 27G "Clear OST pool from stripe"
2644
2645 test_27H() {
2646         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2647                 skip "Need MDS version newer than 2.11.54"
2648         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2649         test_mkdir $DIR/$tdir
2650         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2651         touch $DIR/$tdir/$tfile
2652         $LFS getstripe -c $DIR/$tdir/$tfile
2653         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2654                 error "two-stripe file doesn't have two stripes"
2655
2656         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2657         $LFS getstripe -y $DIR/$tdir/$tfile
2658         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2659              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2660                 error "expected l_ost_idx: [02]$ not matched"
2661
2662         # make sure ost list has been cleared
2663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2666         touch $DIR/$tdir/f3
2667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2668 }
2669 run_test 27H "Set specific OSTs stripe"
2670
2671 test_27I() {
2672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2674         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2675                 skip "Need MDS version newer than 2.12.52"
2676         local pool=$TESTNAME
2677         local ostrange="1 1 1"
2678
2679         save_layout_restore_at_exit $MOUNT
2680         $LFS setstripe -c 2 -i 0 $MOUNT
2681         pool_add $pool || error "pool_add failed"
2682         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2683         test_mkdir $DIR/$tdir
2684         $LFS setstripe -p $pool $DIR/$tdir
2685         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2686         $LFS getstripe $DIR/$tdir/$tfile
2687 }
2688 run_test 27I "check that root dir striping does not break parent dir one"
2689
2690 test_27J() {
2691         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2692                 skip "Need MDS version newer than 2.12.51"
2693
2694         test_mkdir $DIR/$tdir
2695         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2696         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2697
2698         # create foreign file (raw way)
2699         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2700                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2701
2702         # verify foreign file (raw way)
2703         parse_foreign_file -f $DIR/$tdir/$tfile |
2704                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2705                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2706         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_size: 73" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2711         parse_foreign_file -f $DIR/$tdir/$tfile |
2712                 grep "lov_foreign_type: 1" ||
2713                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2714         parse_foreign_file -f $DIR/$tdir/$tfile |
2715                 grep "lov_foreign_flags: 0x0000DA08" ||
2716                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2717         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_value: 0x" |
2719                 sed -e 's/lov_foreign_value: 0x//')
2720         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2721         [[ $lov = ${lov2// /} ]] ||
2722                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2723
2724         # create foreign file (lfs + API)
2725         $LFS setstripe --foreign=daos --flags 0xda08 \
2726                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: create failed"
2728
2729         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2730                 grep "lfm_magic:.*0x0BD70BD0" ||
2731                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2732         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2733         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2734                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2738                 grep "lfm_flags:.*0x0000DA08" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2740         $LFS getstripe $DIR/$tdir/${tfile}2 |
2741                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2742                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2743
2744         # modify striping should fail
2745         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2746                 error "$DIR/$tdir/$tfile: setstripe should fail"
2747         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2748                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2749
2750         # R/W should fail
2751         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2752         cat $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: read should fail"
2754         cat /etc/passwd > $DIR/$tdir/$tfile &&
2755                 error "$DIR/$tdir/$tfile: write should fail"
2756         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2757                 error "$DIR/$tdir/${tfile}2: write should fail"
2758
2759         # chmod should work
2760         chmod 222 $DIR/$tdir/$tfile ||
2761                 error "$DIR/$tdir/$tfile: chmod failed"
2762         chmod 222 $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: chmod failed"
2764
2765         # chown should work
2766         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2767                 error "$DIR/$tdir/$tfile: chown failed"
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2769                 error "$DIR/$tdir/${tfile}2: chown failed"
2770
2771         # rename should work
2772         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2773                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2774         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2775                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2776
2777         #remove foreign file
2778         rm $DIR/$tdir/${tfile}.new ||
2779                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2780         rm $DIR/$tdir/${tfile}2.new ||
2781                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2782 }
2783 run_test 27J "basic ops on file with foreign LOV"
2784
2785 test_27K() {
2786         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2787                 skip "Need MDS version newer than 2.12.49"
2788
2789         test_mkdir $DIR/$tdir
2790         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2791         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2792
2793         # create foreign dir (raw way)
2794         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2795                 error "create_foreign_dir FAILED"
2796
2797         # verify foreign dir (raw way)
2798         parse_foreign_dir -d $DIR/$tdir/$tdir |
2799                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2800                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2801         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2802                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2807         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2808                 grep "lmv_foreign_value: 0x" |
2809                 sed 's/lmv_foreign_value: 0x//')
2810         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2811                 sed 's/ //g')
2812         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2813
2814         # create foreign dir (lfs + API)
2815         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2816                 $DIR/$tdir/${tdir}2 ||
2817                 error "$DIR/$tdir/${tdir}2: create failed"
2818
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2820                 grep "lfm_magic:.*0x0CD50CD0" ||
2821                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2822         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         # - sizeof(lfm_type) - sizeof(lfm_flags)
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2825                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2829                 grep "lfm_flags:.*0x0000DA05" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2831         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2832                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2833                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2834
2835         # file create in dir should fail
2836         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2837         touch $DIR/$tdir/${tdir}2/$tfile &&
2838                 "$DIR/${tdir}2: file create should fail"
2839
2840         # chmod should work
2841         chmod 777 $DIR/$tdir/$tdir ||
2842                 error "$DIR/$tdir: chmod failed"
2843         chmod 777 $DIR/$tdir/${tdir}2 ||
2844                 error "$DIR/${tdir}2: chmod failed"
2845
2846         # chown should work
2847         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2848                 error "$DIR/$tdir: chown failed"
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2850                 error "$DIR/${tdir}2: chown failed"
2851
2852         # rename should work
2853         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2854                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2855         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2856                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2857
2858         #remove foreign dir
2859         rmdir $DIR/$tdir/${tdir}.new ||
2860                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2861         rmdir $DIR/$tdir/${tdir}2.new ||
2862                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2863 }
2864 run_test 27K "basic ops on dir with foreign LMV"
2865
2866 test_27L() {
2867         remote_mds_nodsh && skip "remote MDS with nodsh"
2868
2869         local POOL=${POOL:-$TESTNAME}
2870
2871         pool_add $POOL || error "pool_add failed"
2872
2873         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2874                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2875                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2876 }
2877 run_test 27L "lfs pool_list gives correct pool name"
2878
2879 test_27M() {
2880         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2881                 skip "Need MDS version >= than 2.12.57"
2882         remote_mds_nodsh && skip "remote MDS with nodsh"
2883         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2884
2885         test_mkdir $DIR/$tdir
2886
2887         # Set default striping on directory
2888         $LFS setstripe -C 4 $DIR/$tdir
2889
2890         echo 1 > $DIR/$tdir/${tfile}.1
2891         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2892         local setcount=4
2893         [ $count -eq $setcount ] ||
2894                 error "(1) stripe count $count, should be $setcount"
2895
2896         # Capture existing append_stripe_count setting for restore
2897         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2898         local mdts=$(comma_list $(mdts_nodes))
2899         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2900
2901         local appendcount=$orig_count
2902         echo 1 >> $DIR/$tdir/${tfile}.2_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(2)stripe count $count, should be $appendcount for append"
2906
2907         # Disable O_APPEND striping, verify it works
2908         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2909
2910         # Should now get the default striping, which is 4
2911         setcount=4
2912         echo 1 >> $DIR/$tdir/${tfile}.3_append
2913         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2914         [ $count -eq $setcount ] ||
2915                 error "(3) stripe count $count, should be $setcount"
2916
2917         # Try changing the stripe count for append files
2918         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2919
2920         # Append striping is now 2 (directory default is still 4)
2921         appendcount=2
2922         echo 1 >> $DIR/$tdir/${tfile}.4_append
2923         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2924         [ $count -eq $appendcount ] ||
2925                 error "(4) stripe count $count, should be $appendcount for append"
2926
2927         # Test append stripe count of -1
2928         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2929         appendcount=$OSTCOUNT
2930         echo 1 >> $DIR/$tdir/${tfile}.5
2931         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2932         [ $count -eq $appendcount ] ||
2933                 error "(5) stripe count $count, should be $appendcount for append"
2934
2935         # Set append striping back to default of 1
2936         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2937
2938         # Try a new default striping, PFL + DOM
2939         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2940
2941         # Create normal DOM file, DOM returns stripe count == 0
2942         setcount=0
2943         touch $DIR/$tdir/${tfile}.6
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2945         [ $count -eq $setcount ] ||
2946                 error "(6) stripe count $count, should be $setcount"
2947
2948         # Show
2949         appendcount=1
2950         echo 1 >> $DIR/$tdir/${tfile}.7_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(7) stripe count $count, should be $appendcount for append"
2954
2955         # Clean up DOM layout
2956         $LFS setstripe -d $DIR/$tdir
2957
2958         # Now test that append striping works when layout is from root
2959         $LFS setstripe -c 2 $MOUNT
2960         # Make a special directory for this
2961         mkdir $DIR/${tdir}/${tdir}.2
2962         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2963
2964         # Verify for normal file
2965         setcount=2
2966         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2967         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2968         [ $count -eq $setcount ] ||
2969                 error "(8) stripe count $count, should be $setcount"
2970
2971         appendcount=1
2972         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2973         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2974         [ $count -eq $appendcount ] ||
2975                 error "(9) stripe count $count, should be $appendcount for append"
2976
2977         # Now test O_APPEND striping with pools
2978         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2980
2981         # Create the pool
2982         pool_add $TESTNAME || error "pool creation failed"
2983         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2984
2985         echo 1 >> $DIR/$tdir/${tfile}.10_append
2986
2987         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2988         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2989
2990         # Check that count is still correct
2991         appendcount=1
2992         echo 1 >> $DIR/$tdir/${tfile}.11_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(11) stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND stripe count, verify pool works separately
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         echo 1 >> $DIR/$tdir/${tfile}.12_append
3001
3002         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3003         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3004
3005         # Remove pool setting, verify it's not applied
3006         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3007
3008         echo 1 >> $DIR/$tdir/${tfile}.13_append
3009
3010         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3011         [ "$pool" = "" ] || error "(13) pool found: $pool"
3012 }
3013 run_test 27M "test O_APPEND striping"
3014
3015 test_27N() {
3016         combined_mgs_mds && skip "needs separate MGS/MDT"
3017
3018         pool_add $TESTNAME || error "pool_add failed"
3019         do_facet mgs "$LCTL pool_list $FSNAME" |
3020                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3021                 error "lctl pool_list on MGS failed"
3022 }
3023 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3024
3025 # createtest also checks that device nodes are created and
3026 # then visible correctly (#2091)
3027 test_28() { # bug 2091
3028         test_mkdir $DIR/d28
3029         $CREATETEST $DIR/d28/ct || error "createtest failed"
3030 }
3031 run_test 28 "create/mknod/mkdir with bad file types ============"
3032
3033 test_29() {
3034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3035
3036         sync; sleep 1; sync # flush out any dirty pages from previous tests
3037         cancel_lru_locks
3038         test_mkdir $DIR/d29
3039         touch $DIR/d29/foo
3040         log 'first d29'
3041         ls -l $DIR/d29
3042
3043         declare -i LOCKCOUNTORIG=0
3044         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3045                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3046         done
3047         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3048
3049         declare -i LOCKUNUSEDCOUNTORIG=0
3050         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3051                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3052         done
3053
3054         log 'second d29'
3055         ls -l $DIR/d29
3056         log 'done'
3057
3058         declare -i LOCKCOUNTCURRENT=0
3059         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3060                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3061         done
3062
3063         declare -i LOCKUNUSEDCOUNTCURRENT=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3066         done
3067
3068         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3069                 $LCTL set_param -n ldlm.dump_namespaces ""
3070                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3071                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3072                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3073                 return 2
3074         fi
3075         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3076                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3077                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3078                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3079                 return 3
3080         fi
3081 }
3082 run_test 29 "IT_GETATTR regression  ============================"
3083
3084 test_30a() { # was test_30
3085         cp $(which ls) $DIR || cp /bin/ls $DIR
3086         $DIR/ls / || error "Can't execute binary from lustre"
3087         rm $DIR/ls
3088 }
3089 run_test 30a "execute binary from Lustre (execve) =============="
3090
3091 test_30b() {
3092         cp `which ls` $DIR || cp /bin/ls $DIR
3093         chmod go+rx $DIR/ls
3094         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3095         rm $DIR/ls
3096 }
3097 run_test 30b "execute binary from Lustre as non-root ==========="
3098
3099 test_30c() { # b=22376
3100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3101
3102         cp $(which ls) $DIR || cp /bin/ls $DIR
3103         chmod a-rw $DIR/ls
3104         cancel_lru_locks mdc
3105         cancel_lru_locks osc
3106         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3107         rm -f $DIR/ls
3108 }
3109 run_test 30c "execute binary from Lustre without read perms ===="
3110
3111 test_30d() {
3112         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3113
3114         for i in {1..10}; do
3115                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3116                 local PID=$!
3117                 sleep 1
3118                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3119                 wait $PID || error "executing dd from Lustre failed"
3120                 rm -f $DIR/$tfile
3121         done
3122
3123         rm -f $DIR/dd
3124 }
3125 run_test 30d "execute binary from Lustre while clear locks"
3126
3127 test_31a() {
3128         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3129         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3130 }
3131 run_test 31a "open-unlink file =================================="
3132
3133 test_31b() {
3134         touch $DIR/f31 || error "touch $DIR/f31 failed"
3135         ln $DIR/f31 $DIR/f31b || error "ln failed"
3136         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3137         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3138 }
3139 run_test 31b "unlink file with multiple links while open ======="
3140
3141 test_31c() {
3142         touch $DIR/f31 || error "touch $DIR/f31 failed"
3143         ln $DIR/f31 $DIR/f31c || error "ln failed"
3144         multiop_bg_pause $DIR/f31 O_uc ||
3145                 error "multiop_bg_pause for $DIR/f31 failed"
3146         MULTIPID=$!
3147         $MULTIOP $DIR/f31c Ouc
3148         kill -USR1 $MULTIPID
3149         wait $MULTIPID
3150 }
3151 run_test 31c "open-unlink file with multiple links ============="
3152
3153 test_31d() {
3154         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3155         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3156 }
3157 run_test 31d "remove of open directory ========================="
3158
3159 test_31e() { # bug 2904
3160         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3161 }
3162 run_test 31e "remove of open non-empty directory ==============="
3163
3164 test_31f() { # bug 4554
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         set -vx
3168         test_mkdir $DIR/d31f
3169         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3170         cp /etc/hosts $DIR/d31f
3171         ls -l $DIR/d31f
3172         $LFS getstripe $DIR/d31f/hosts
3173         multiop_bg_pause $DIR/d31f D_c || return 1
3174         MULTIPID=$!
3175
3176         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3177         test_mkdir $DIR/d31f
3178         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3179         cp /etc/hosts $DIR/d31f
3180         ls -l $DIR/d31f
3181         $LFS getstripe $DIR/d31f/hosts
3182         multiop_bg_pause $DIR/d31f D_c || return 1
3183         MULTIPID2=$!
3184
3185         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3186         wait $MULTIPID || error "first opendir $MULTIPID failed"
3187
3188         sleep 6
3189
3190         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3191         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3192         set +vx
3193 }
3194 run_test 31f "remove of open directory with open-unlink file ==="
3195
3196 test_31g() {
3197         echo "-- cross directory link --"
3198         test_mkdir -c1 $DIR/${tdir}ga
3199         test_mkdir -c1 $DIR/${tdir}gb
3200         touch $DIR/${tdir}ga/f
3201         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3202         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3203         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3204         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3205         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3206 }
3207 run_test 31g "cross directory link==============="
3208
3209 test_31h() {
3210         echo "-- cross directory link --"
3211         test_mkdir -c1 $DIR/${tdir}
3212         test_mkdir -c1 $DIR/${tdir}/dir
3213         touch $DIR/${tdir}/f
3214         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3215         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3216         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3217         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3218         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3219 }
3220 run_test 31h "cross directory link under child==============="
3221
3222 test_31i() {
3223         echo "-- cross directory link --"
3224         test_mkdir -c1 $DIR/$tdir
3225         test_mkdir -c1 $DIR/$tdir/dir
3226         touch $DIR/$tdir/dir/f
3227         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3228         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3229         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3230         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3231         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3232 }
3233 run_test 31i "cross directory link under parent==============="
3234
3235 test_31j() {
3236         test_mkdir -c1 -p $DIR/$tdir
3237         test_mkdir -c1 -p $DIR/$tdir/dir1
3238         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3239         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3240         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3241         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3242         return 0
3243 }
3244 run_test 31j "link for directory==============="
3245
3246 test_31k() {
3247         test_mkdir -c1 -p $DIR/$tdir
3248         touch $DIR/$tdir/s
3249         touch $DIR/$tdir/exist
3250         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3251         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3252         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3253         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3254         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3255         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3256         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3257         return 0
3258 }
3259 run_test 31k "link to file: the same, non-existing, dir==============="
3260
3261 test_31m() {
3262         mkdir $DIR/d31m
3263         touch $DIR/d31m/s
3264         mkdir $DIR/d31m2
3265         touch $DIR/d31m2/exist
3266         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3267         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3268         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3269         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3270         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3271         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3272         return 0
3273 }
3274 run_test 31m "link to file: the same, non-existing, dir==============="
3275
3276 test_31n() {
3277         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3278         nlink=$(stat --format=%h $DIR/$tfile)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         local fd=$(free_fd)
3281         local cmd="exec $fd<$DIR/$tfile"
3282         eval $cmd
3283         cmd="exec $fd<&-"
3284         trap "eval $cmd" EXIT
3285         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3288         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3289         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3290         eval $cmd
3291 }
3292 run_test 31n "check link count of unlinked file"
3293
3294 link_one() {
3295         local tempfile=$(mktemp $1_XXXXXX)
3296         mlink $tempfile $1 2> /dev/null &&
3297                 echo "$BASHPID: link $tempfile to $1 succeeded"
3298         munlink $tempfile
3299 }
3300
3301 test_31o() { # LU-2901
3302         test_mkdir $DIR/$tdir
3303         for LOOP in $(seq 100); do
3304                 rm -f $DIR/$tdir/$tfile*
3305                 for THREAD in $(seq 8); do
3306                         link_one $DIR/$tdir/$tfile.$LOOP &
3307                 done
3308                 wait
3309                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3310                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3311                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3312                         break || true
3313         done
3314 }
3315 run_test 31o "duplicate hard links with same filename"
3316
3317 test_31p() {
3318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3319
3320         test_mkdir $DIR/$tdir
3321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3322         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3323
3324         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3325                 error "open unlink test1 failed"
3326         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3327                 error "open unlink test2 failed"
3328
3329         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3330                 error "test1 still exists"
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3332                 error "test2 still exists"
3333 }
3334 run_test 31p "remove of open striped directory"
3335
3336 cleanup_test32_mount() {
3337         local rc=0
3338         trap 0
3339         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3340         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3341         losetup -d $loopdev || true
3342         rm -rf $DIR/$tdir
3343         return $rc
3344 }
3345
3346 test_32a() {
3347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3348
3349         echo "== more mountpoints and symlinks ================="
3350         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3351         trap cleanup_test32_mount EXIT
3352         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3353         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3354                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3355         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3356                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3357         cleanup_test32_mount
3358 }
3359 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3360
3361 test_32b() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3371         cleanup_test32_mount
3372 }
3373 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3374
3375 test_32c() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         test_mkdir -p $DIR/$tdir/d2/test_dir
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3389
3390 test_32d() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         test_mkdir -p $DIR/$tdir/d2/test_dir
3399         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3400                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3401         cleanup_test32_mount
3402 }
3403 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3404
3405 test_32e() {
3406         rm -fr $DIR/$tdir
3407         test_mkdir -p $DIR/$tdir/tmp
3408         local tmp_dir=$DIR/$tdir/tmp
3409         ln -s $DIR/$tdir $tmp_dir/symlink11
3410         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3411         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3412         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3413 }
3414 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3415
3416 test_32f() {
3417         rm -fr $DIR/$tdir
3418         test_mkdir -p $DIR/$tdir/tmp
3419         local tmp_dir=$DIR/$tdir/tmp
3420         ln -s $DIR/$tdir $tmp_dir/symlink11
3421         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3422         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3423         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3424 }
3425 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3426
3427 test_32g() {
3428         local tmp_dir=$DIR/$tdir/tmp
3429         test_mkdir -p $tmp_dir
3430         test_mkdir $DIR/${tdir}2
3431         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3432         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3433         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3434         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3435         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3436         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3437 }
3438 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3439
3440 test_32h() {
3441         rm -fr $DIR/$tdir $DIR/${tdir}2
3442         tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         ls $tmp_dir/symlink12 || error "listing symlink12"
3448         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3449 }
3450 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3451
3452 test_32i() {
3453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3454
3455         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3456         trap cleanup_test32_mount EXIT
3457         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3458         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3459                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3460         touch $DIR/$tdir/test_file
3461         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3462                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3463         cleanup_test32_mount
3464 }
3465 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3466
3467 test_32j() {
3468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3469
3470         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3471         trap cleanup_test32_mount EXIT
3472         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3473         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3474                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3475         touch $DIR/$tdir/test_file
3476         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3477                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3478         cleanup_test32_mount
3479 }
3480 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3481
3482 test_32k() {
3483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3484
3485         rm -fr $DIR/$tdir
3486         trap cleanup_test32_mount EXIT
3487         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3488         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3489                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3490         test_mkdir -p $DIR/$tdir/d2
3491         touch $DIR/$tdir/d2/test_file || error "touch failed"
3492         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3493                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3494         cleanup_test32_mount
3495 }
3496 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3497
3498 test_32l() {
3499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3500
3501         rm -fr $DIR/$tdir
3502         trap cleanup_test32_mount EXIT
3503         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3504         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3505                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3506         test_mkdir -p $DIR/$tdir/d2
3507         touch $DIR/$tdir/d2/test_file || error "touch failed"
3508         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3509                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3510         cleanup_test32_mount
3511 }
3512 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3513
3514 test_32m() {
3515         rm -fr $DIR/d32m
3516         test_mkdir -p $DIR/d32m/tmp
3517         TMP_DIR=$DIR/d32m/tmp
3518         ln -s $DIR $TMP_DIR/symlink11
3519         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3520         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3521                 error "symlink11 not a link"
3522         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3523                 error "symlink01 not a link"
3524 }
3525 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3526
3527 test_32n() {
3528         rm -fr $DIR/d32n
3529         test_mkdir -p $DIR/d32n/tmp
3530         TMP_DIR=$DIR/d32n/tmp
3531         ln -s $DIR $TMP_DIR/symlink11
3532         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3533         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3534         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3535 }
3536 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3537
3538 test_32o() {
3539         touch $DIR/$tfile
3540         test_mkdir -p $DIR/d32o/tmp
3541         TMP_DIR=$DIR/d32o/tmp
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3544         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3545                 error "symlink12 not a link"
3546         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3547         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3548                 error "$DIR/d32o/tmp/symlink12 not file type"
3549         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3550                 error "$DIR/d32o/symlink02 not file type"
3551 }
3552 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32p() {
3555         log 32p_1
3556         rm -fr $DIR/d32p
3557         log 32p_2
3558         rm -f $DIR/$tfile
3559         log 32p_3
3560         touch $DIR/$tfile
3561         log 32p_4
3562         test_mkdir -p $DIR/d32p/tmp
3563         log 32p_5
3564         TMP_DIR=$DIR/d32p/tmp
3565         log 32p_6
3566         ln -s $DIR/$tfile $TMP_DIR/symlink12
3567         log 32p_7
3568         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3569         log 32p_8
3570         cat $DIR/d32p/tmp/symlink12 ||
3571                 error "Can't open $DIR/d32p/tmp/symlink12"
3572         log 32p_9
3573         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3574         log 32p_10
3575 }
3576 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3577
3578 test_32q() {
3579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3580
3581         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3582         trap cleanup_test32_mount EXIT
3583         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3584         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3585         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3586                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3587         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3588         cleanup_test32_mount
3589 }
3590 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3591
3592 test_32r() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3602         cleanup_test32_mount
3603 }
3604 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3605
3606 test_33aa() {
3607         rm -f $DIR/$tfile
3608         touch $DIR/$tfile
3609         chmod 444 $DIR/$tfile
3610         chown $RUNAS_ID $DIR/$tfile
3611         log 33_1
3612         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3613         log 33_2
3614 }
3615 run_test 33aa "write file with mode 444 (should return error)"
3616
3617 test_33a() {
3618         rm -fr $DIR/$tdir
3619         test_mkdir $DIR/$tdir
3620         chown $RUNAS_ID $DIR/$tdir
3621         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3622                 error "$RUNAS create $tdir/$tfile failed"
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3624                 error "open RDWR" || true
3625 }
3626 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3627
3628 test_33b() {
3629         rm -fr $DIR/$tdir
3630         test_mkdir $DIR/$tdir
3631         chown $RUNAS_ID $DIR/$tdir
3632         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3633 }
3634 run_test 33b "test open file with malformed flags (No panic)"
3635
3636 test_33c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638         remote_ost_nodsh && skip "remote OST with nodsh"
3639
3640         local ostnum
3641         local ostname
3642         local write_bytes
3643         local all_zeros
3644
3645         all_zeros=:
3646         rm -fr $DIR/$tdir
3647         test_mkdir $DIR/$tdir
3648         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3649
3650         sync
3651         for ostnum in $(seq $OSTCOUNT); do
3652                 # test-framework's OST numbering is one-based, while Lustre's
3653                 # is zero-based
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 # Parsing llobdstat's output sucks; we could grep the /proc
3656                 # path, but that's likely to not be as portable as using the
3657                 # llobdstat utility.  So we parse lctl output instead.
3658                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3659                         obdfilter/$ostname/stats |
3660                         awk '/^write_bytes/ {print $7}' )
3661                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3662                 if (( ${write_bytes:-0} > 0 ))
3663                 then
3664                         all_zeros=false
3665                         break;
3666                 fi
3667         done
3668
3669         $all_zeros || return 0
3670
3671         # Write four bytes
3672         echo foo > $DIR/$tdir/bar
3673         # Really write them
3674         sync
3675
3676         # Total up write_bytes after writing.  We'd better find non-zeros.
3677         for ostnum in $(seq $OSTCOUNT); do
3678                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3679                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3680                         obdfilter/$ostname/stats |
3681                         awk '/^write_bytes/ {print $7}' )
3682                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3683                 if (( ${write_bytes:-0} > 0 ))
3684                 then
3685                         all_zeros=false
3686                         break;
3687                 fi
3688         done
3689
3690         if $all_zeros
3691         then
3692                 for ostnum in $(seq $OSTCOUNT); do
3693                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3695                         do_facet ost$ostnum lctl get_param -n \
3696                                 obdfilter/$ostname/stats
3697                 done
3698                 error "OST not keeping write_bytes stats (b22312)"
3699         fi
3700 }
3701 run_test 33c "test llobdstat and write_bytes"
3702
3703 test_33d() {
3704         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local MDTIDX=1
3708         local remote_dir=$DIR/$tdir/remote_dir
3709
3710         test_mkdir $DIR/$tdir
3711         $LFS mkdir -i $MDTIDX $remote_dir ||
3712                 error "create remote directory failed"
3713
3714         touch $remote_dir/$tfile
3715         chmod 444 $remote_dir/$tfile
3716         chown $RUNAS_ID $remote_dir/$tfile
3717
3718         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3719
3720         chown $RUNAS_ID $remote_dir
3721         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3722                                         error "create" || true
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3724                                     error "open RDWR" || true
3725         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3726 }
3727 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3728
3729 test_33e() {
3730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3731
3732         mkdir $DIR/$tdir
3733
3734         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3735         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3736         mkdir $DIR/$tdir/local_dir
3737
3738         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3739         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3740         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3741
3742         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3743                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3744
3745         rmdir $DIR/$tdir/* || error "rmdir failed"
3746
3747         umask 777
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3760
3761         umask 000
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3772 }
3773 run_test 33e "mkdir and striped directory should have same mode"
3774
3775 cleanup_33f() {
3776         trap 0
3777         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3778 }
3779
3780 test_33f() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782         remote_mds_nodsh && skip "remote MDS with nodsh"
3783
3784         mkdir $DIR/$tdir
3785         chmod go+rwx $DIR/$tdir
3786         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3787         trap cleanup_33f EXIT
3788
3789         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3790                 error "cannot create striped directory"
3791
3792         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3793                 error "cannot create files in striped directory"
3794
3795         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3796                 error "cannot remove files in striped directory"
3797
3798         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3799                 error "cannot remove striped directory"
3800
3801         cleanup_33f
3802 }
3803 run_test 33f "nonroot user can create, access, and remove a striped directory"
3804
3805 test_33g() {
3806         mkdir -p $DIR/$tdir/dir2
3807
3808         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3809         echo $err
3810         [[ $err =~ "exists" ]] || error "Not exists error"
3811 }
3812 run_test 33g "nonroot user create already existing root created file"
3813
3814 test_33h() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3817                 skip "Need MDS version at least 2.13.50"
3818
3819         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3820                 error "mkdir $tdir failed"
3821         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3822
3823         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3824         local index2
3825
3826         for fname in $DIR/$tdir/$tfile.bak \
3827                      $DIR/$tdir/$tfile.SAV \
3828                      $DIR/$tdir/$tfile.orig \
3829                      $DIR/$tdir/$tfile~; do
3830                 touch $fname  || error "touch $fname failed"
3831                 index2=$($LFS getstripe -m $fname)
3832                 [ $index -eq $index2 ] ||
3833                         error "$fname MDT index mismatch $index != $index2"
3834         done
3835
3836         local failed=0
3837         for i in {1..250}; do
3838                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3839                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3840                         touch $fname  || error "touch $fname failed"
3841                         index2=$($LFS getstripe -m $fname)
3842                         if [[ $index != $index2 ]]; then
3843                                 failed=$((failed + 1))
3844                                 echo "$fname MDT index mismatch $index != $index2"
3845                         fi
3846                 done
3847         done
3848         echo "$failed MDT index mismatches"
3849         (( failed < 20 )) || error "MDT index mismatch $failed times"
3850
3851 }
3852 run_test 33h "temp file is located on the same MDT as target"
3853
3854 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3855 test_34a() {
3856         rm -f $DIR/f34
3857         $MCREATE $DIR/f34 || error "mcreate failed"
3858         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3859                 error "getstripe failed"
3860         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3862                 error "getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34a "truncate file that has not been opened ==========="
3867
3868 test_34b() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872         $OPENFILE -f O_RDONLY $DIR/f34
3873         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3874                 error "getstripe failed"
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877 }
3878 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3879
3880 test_34c() {
3881         [ ! -f $DIR/f34 ] && test_34a
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34
3885         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3886                 error "$LFS getstripe failed"
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889 }
3890 run_test 34c "O_RDWR opening file-with-size works =============="
3891
3892 test_34d() {
3893         [ ! -f $DIR/f34 ] && test_34a
3894         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3895                 error "dd failed"
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         rm $DIR/f34
3899 }
3900 run_test 34d "write to sparse file ============================="
3901
3902 test_34e() {
3903         rm -f $DIR/f34e
3904         $MCREATE $DIR/f34e || error "mcreate failed"
3905         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3906         $CHECKSTAT -s 1000 $DIR/f34e ||
3907                 error "Size of $DIR/f34e not equal to 1000 bytes"
3908         $OPENFILE -f O_RDWR $DIR/f34e
3909         $CHECKSTAT -s 1000 $DIR/f34e ||
3910                 error "Size of $DIR/f34e not equal to 1000 bytes"
3911 }
3912 run_test 34e "create objects, some with size and some without =="
3913
3914 test_34f() { # bug 6242, 6243
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         SIZE34F=48000
3918         rm -f $DIR/f34f
3919         $MCREATE $DIR/f34f || error "mcreate failed"
3920         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3921         dd if=$DIR/f34f of=$TMP/f34f
3922         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3923         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3924         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3925         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3926         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3927 }
3928 run_test 34f "read from a file with no objects until EOF ======="
3929
3930 test_34g() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3934                 error "dd failed"
3935         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3936         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3937                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3940                 error "wrong size after lock cancel"
3941
3942         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3943         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3944                 error "expanding truncate failed"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3947                 error "wrong expanded size after lock cancel"
3948 }
3949 run_test 34g "truncate long file ==============================="
3950
3951 test_34h() {
3952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3953
3954         local gid=10
3955         local sz=1000
3956
3957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3958         sync # Flush the cache so that multiop below does not block on cache
3959              # flush when getting the group lock
3960         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3961         MULTIPID=$!
3962
3963         # Since just timed wait is not good enough, let's do a sync write
3964         # that way we are sure enough time for a roundtrip + processing
3965         # passed + 2 seconds of extra margin.
3966         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3967         rm $DIR/${tfile}-1
3968         sleep 2
3969
3970         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3971                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3972                 kill -9 $MULTIPID
3973         fi
3974         wait $MULTIPID
3975         local nsz=`stat -c %s $DIR/$tfile`
3976         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3977 }
3978 run_test 34h "ftruncate file under grouplock should not block"
3979
3980 test_35a() {
3981         cp /bin/sh $DIR/f35a
3982         chmod 444 $DIR/f35a
3983         chown $RUNAS_ID $DIR/f35a
3984         $RUNAS $DIR/f35a && error || true
3985         rm $DIR/f35a
3986 }
3987 run_test 35a "exec file with mode 444 (should return and not leak)"
3988
3989 test_36a() {
3990         rm -f $DIR/f36
3991         utime $DIR/f36 || error "utime failed for MDS"
3992 }
3993 run_test 36a "MDS utime check (mknod, utime)"
3994
3995 test_36b() {
3996         echo "" > $DIR/f36
3997         utime $DIR/f36 || error "utime failed for OST"
3998 }
3999 run_test 36b "OST utime check (open, utime)"
4000
4001 test_36c() {
4002         rm -f $DIR/d36/f36
4003         test_mkdir $DIR/d36
4004         chown $RUNAS_ID $DIR/d36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4006 }
4007 run_test 36c "non-root MDS utime check (mknod, utime)"
4008
4009 test_36d() {
4010         [ ! -d $DIR/d36 ] && test_36c
4011         echo "" > $DIR/d36/f36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4013 }
4014 run_test 36d "non-root OST utime check (open, utime)"
4015
4016 test_36e() {
4017         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4018
4019         test_mkdir $DIR/$tdir
4020         touch $DIR/$tdir/$tfile
4021         $RUNAS utime $DIR/$tdir/$tfile &&
4022                 error "utime worked, expected failure" || true
4023 }
4024 run_test 36e "utime on non-owned file (should return error)"
4025
4026 subr_36fh() {
4027         local fl="$1"
4028         local LANG_SAVE=$LANG
4029         local LC_LANG_SAVE=$LC_LANG
4030         export LANG=C LC_LANG=C # for date language
4031
4032         DATESTR="Dec 20  2000"
4033         test_mkdir $DIR/$tdir
4034         lctl set_param fail_loc=$fl
4035         date; date +%s
4036         cp /etc/hosts $DIR/$tdir/$tfile
4037         sync & # write RPC generated with "current" inode timestamp, but delayed
4038         sleep 1
4039         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4040         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4041         cancel_lru_locks $OSC
4042         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4043         date; date +%s
4044         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4045                 echo "BEFORE: $LS_BEFORE" && \
4046                 echo "AFTER : $LS_AFTER" && \
4047                 echo "WANT  : $DATESTR" && \
4048                 error "$DIR/$tdir/$tfile timestamps changed" || true
4049
4050         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4051 }
4052
4053 test_36f() {
4054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4055
4056         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4057         subr_36fh "0x80000214"
4058 }
4059 run_test 36f "utime on file racing with OST BRW write =========="
4060
4061 test_36g() {
4062         remote_ost_nodsh && skip "remote OST with nodsh"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4065                 skip "Need MDS version at least 2.12.51"
4066
4067         local fmd_max_age
4068         local fmd
4069         local facet="ost1"
4070         local tgt="obdfilter"
4071
4072         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4073
4074         test_mkdir $DIR/$tdir
4075         fmd_max_age=$(do_facet $facet \
4076                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4077                 head -n 1")
4078
4079         echo "FMD max age: ${fmd_max_age}s"
4080         touch $DIR/$tdir/$tfile
4081         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4082                 gawk '{cnt=cnt+$1}  END{print cnt}')
4083         echo "FMD before: $fmd"
4084         [[ $fmd == 0 ]] &&
4085                 error "FMD wasn't create by touch"
4086         sleep $((fmd_max_age + 12))
4087         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4088                 gawk '{cnt=cnt+$1}  END{print cnt}')
4089         echo "FMD after: $fmd"
4090         [[ $fmd == 0 ]] ||
4091                 error "FMD wasn't expired by ping"
4092 }
4093 run_test 36g "FMD cache expiry ====================="
4094
4095 test_36h() {
4096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4097
4098         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4099         subr_36fh "0x80000227"
4100 }
4101 run_test 36h "utime on file racing with OST BRW write =========="
4102
4103 test_36i() {
4104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4105
4106         test_mkdir $DIR/$tdir
4107         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4108
4109         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4110         local new_mtime=$((mtime + 200))
4111
4112         #change Modify time of striped dir
4113         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4114                         error "change mtime failed"
4115
4116         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4117
4118         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4119 }
4120 run_test 36i "change mtime on striped directory"
4121
4122 # test_37 - duplicate with tests 32q 32r
4123
4124 test_38() {
4125         local file=$DIR/$tfile
4126         touch $file
4127         openfile -f O_DIRECTORY $file
4128         local RC=$?
4129         local ENOTDIR=20
4130         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4131         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4132 }
4133 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4134
4135 test_39a() { # was test_39
4136         touch $DIR/$tfile
4137         touch $DIR/${tfile}2
4138 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4139 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4140 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4141         sleep 2
4142         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4143         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4144                 echo "mtime"
4145                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4146                 echo "atime"
4147                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "ctime"
4149                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4150                 error "O_TRUNC didn't change timestamps"
4151         fi
4152 }
4153 run_test 39a "mtime changed on create"
4154
4155 test_39b() {
4156         test_mkdir -c1 $DIR/$tdir
4157         cp -p /etc/passwd $DIR/$tdir/fopen
4158         cp -p /etc/passwd $DIR/$tdir/flink
4159         cp -p /etc/passwd $DIR/$tdir/funlink
4160         cp -p /etc/passwd $DIR/$tdir/frename
4161         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4162
4163         sleep 1
4164         echo "aaaaaa" >> $DIR/$tdir/fopen
4165         echo "aaaaaa" >> $DIR/$tdir/flink
4166         echo "aaaaaa" >> $DIR/$tdir/funlink
4167         echo "aaaaaa" >> $DIR/$tdir/frename
4168
4169         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4170         local link_new=`stat -c %Y $DIR/$tdir/flink`
4171         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4172         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4173
4174         cat $DIR/$tdir/fopen > /dev/null
4175         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4176         rm -f $DIR/$tdir/funlink2
4177         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4181                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4182                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4183                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4184
4185                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4186                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4187                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4188                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39b "mtime change on open, link, unlink, rename  ======"
4195
4196 # this should be set to past
4197 TEST_39_MTIME=`date -d "1 year ago" +%s`
4198
4199 # bug 11063
4200 test_39c() {
4201         touch $DIR1/$tfile
4202         sleep 2
4203         local mtime0=`stat -c %Y $DIR1/$tfile`
4204
4205         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4206         local mtime1=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime1" = $TEST_39_MTIME ] || \
4208                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4209
4210         local d1=`date +%s`
4211         echo hello >> $DIR1/$tfile
4212         local d2=`date +%s`
4213         local mtime2=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4215                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4216
4217         mv $DIR1/$tfile $DIR1/$tfile-1
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4221                 [ "$mtime2" = "$mtime3" ] || \
4222                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39c "mtime change on rename ==========================="
4229
4230 # bug 21114
4231 test_39d() {
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         touch $DIR1/$tfile
4235         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime=`stat -c %Y $DIR1/$tfile`
4239                 [ $mtime = $TEST_39_MTIME ] || \
4240                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39d "create, utime, stat =============================="
4247
4248 # bug 21114
4249 test_39e() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         local mtime1=`stat -c %Y $DIR1/$tfile`
4254
4255         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4256
4257         for (( i=0; i < 2; i++ )) ; do
4258                 local mtime2=`stat -c %Y $DIR1/$tfile`
4259                 [ $mtime2 = $TEST_39_MTIME ] || \
4260                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4261
4262                 cancel_lru_locks $OSC
4263                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4264         done
4265 }
4266 run_test 39e "create, stat, utime, stat ========================"
4267
4268 # bug 21114
4269 test_39f() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         touch $DIR1/$tfile
4273         mtime1=`stat -c %Y $DIR1/$tfile`
4274
4275         sleep 2
4276         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4277
4278         for (( i=0; i < 2; i++ )) ; do
4279                 local mtime2=`stat -c %Y $DIR1/$tfile`
4280                 [ $mtime2 = $TEST_39_MTIME ] || \
4281                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4282
4283                 cancel_lru_locks $OSC
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286 }
4287 run_test 39f "create, stat, sleep, utime, stat ================="
4288
4289 # bug 11063
4290 test_39g() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         echo hello >> $DIR1/$tfile
4294         local mtime1=`stat -c %Y $DIR1/$tfile`
4295
4296         sleep 2
4297         chmod o+r $DIR1/$tfile
4298
4299         for (( i=0; i < 2; i++ )) ; do
4300                 local mtime2=`stat -c %Y $DIR1/$tfile`
4301                 [ "$mtime1" = "$mtime2" ] || \
4302                         error "lost mtime: $mtime2, should be $mtime1"
4303
4304                 cancel_lru_locks $OSC
4305                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4306         done
4307 }
4308 run_test 39g "write, chmod, stat ==============================="
4309
4310 # bug 11063
4311 test_39h() {
4312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4313
4314         touch $DIR1/$tfile
4315         sleep 1
4316
4317         local d1=`date`
4318         echo hello >> $DIR1/$tfile
4319         local mtime1=`stat -c %Y $DIR1/$tfile`
4320
4321         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4322         local d2=`date`
4323         if [ "$d1" != "$d2" ]; then
4324                 echo "write and touch not within one second"
4325         else
4326                 for (( i=0; i < 2; i++ )) ; do
4327                         local mtime2=`stat -c %Y $DIR1/$tfile`
4328                         [ "$mtime2" = $TEST_39_MTIME ] || \
4329                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4330
4331                         cancel_lru_locks $OSC
4332                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333                 done
4334         fi
4335 }
4336 run_test 39h "write, utime within one second, stat ============="
4337
4338 test_39i() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         echo hello >> $DIR1/$tfile
4345         local mtime1=`stat -c %Y $DIR1/$tfile`
4346
4347         mv $DIR1/$tfile $DIR1/$tfile-1
4348
4349         for (( i=0; i < 2; i++ )) ; do
4350                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4351
4352                 [ "$mtime1" = "$mtime2" ] || \
4353                         error "lost mtime: $mtime2, should be $mtime1"
4354
4355                 cancel_lru_locks $OSC
4356                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4357         done
4358 }
4359 run_test 39i "write, rename, stat =============================="
4360
4361 test_39j() {
4362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4363
4364         start_full_debug_logging
4365         touch $DIR1/$tfile
4366         sleep 1
4367
4368         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4369         lctl set_param fail_loc=0x80000412
4370         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4371                 error "multiop failed"
4372         local multipid=$!
4373         local mtime1=`stat -c %Y $DIR1/$tfile`
4374
4375         mv $DIR1/$tfile $DIR1/$tfile-1
4376
4377         kill -USR1 $multipid
4378         wait $multipid || error "multiop close failed"
4379
4380         for (( i=0; i < 2; i++ )) ; do
4381                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4382                 [ "$mtime1" = "$mtime2" ] ||
4383                         error "mtime is lost on close: $mtime2, " \
4384                               "should be $mtime1"
4385
4386                 cancel_lru_locks
4387                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4388         done
4389         lctl set_param fail_loc=0
4390         stop_full_debug_logging
4391 }
4392 run_test 39j "write, rename, close, stat ======================="
4393
4394 test_39k() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         touch $DIR1/$tfile
4398         sleep 1
4399
4400         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile`
4411
4412                 [ "$mtime2" = $TEST_39_MTIME ] || \
4413                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418 }
4419 run_test 39k "write, utime, close, stat ========================"
4420
4421 # this should be set to future
4422 TEST_39_ATIME=`date -d "1 year" +%s`
4423
4424 test_39l() {
4425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4426         remote_mds_nodsh && skip "remote MDS with nodsh"
4427
4428         local atime_diff=$(do_facet $SINGLEMDS \
4429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4430         rm -rf $DIR/$tdir
4431         mkdir -p $DIR/$tdir
4432
4433         # test setting directory atime to future
4434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4435         local atime=$(stat -c %X $DIR/$tdir)
4436         [ "$atime" = $TEST_39_ATIME ] ||
4437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4438
4439         # test setting directory atime from future to now
4440         local now=$(date +%s)
4441         touch -a -d @$now $DIR/$tdir
4442
4443         atime=$(stat -c %X $DIR/$tdir)
4444         [ "$atime" -eq "$now"  ] ||
4445                 error "atime is not updated from future: $atime, $now"
4446
4447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4448         sleep 3
4449
4450         # test setting directory atime when now > dir atime + atime_diff
4451         local d1=$(date +%s)
4452         ls $DIR/$tdir
4453         local d2=$(date +%s)
4454         cancel_lru_locks mdc
4455         atime=$(stat -c %X $DIR/$tdir)
4456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4457                 error "atime is not updated  : $atime, should be $d2"
4458
4459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4460         sleep 3
4461
4462         # test not setting directory atime when now < dir atime + atime_diff
4463         ls $DIR/$tdir
4464         cancel_lru_locks mdc
4465         atime=$(stat -c %X $DIR/$tdir)
4466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4468
4469         do_facet $SINGLEMDS \
4470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4471 }
4472 run_test 39l "directory atime update ==========================="
4473
4474 test_39m() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         touch $DIR1/$tfile
4478         sleep 2
4479         local far_past_mtime=$(date -d "May 29 1953" +%s)
4480         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4481
4482         touch -m -d @$far_past_mtime $DIR1/$tfile
4483         touch -a -d @$far_past_atime $DIR1/$tfile
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4487                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4488                         error "atime or mtime set incorrectly"
4489
4490                 cancel_lru_locks $OSC
4491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4492         done
4493 }
4494 run_test 39m "test atime and mtime before 1970"
4495
4496 test_39n() { # LU-3832
4497         remote_mds_nodsh && skip "remote MDS with nodsh"
4498
4499         local atime_diff=$(do_facet $SINGLEMDS \
4500                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4501         local atime0
4502         local atime1
4503         local atime2
4504
4505         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4506
4507         rm -rf $DIR/$tfile
4508         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4509         atime0=$(stat -c %X $DIR/$tfile)
4510
4511         sleep 5
4512         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4513         atime1=$(stat -c %X $DIR/$tfile)
4514
4515         sleep 5
4516         cancel_lru_locks mdc
4517         cancel_lru_locks osc
4518         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4519         atime2=$(stat -c %X $DIR/$tfile)
4520
4521         do_facet $SINGLEMDS \
4522                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4523
4524         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4525         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4526 }
4527 run_test 39n "check that O_NOATIME is honored"
4528
4529 test_39o() {
4530         TESTDIR=$DIR/$tdir/$tfile
4531         [ -e $TESTDIR ] && rm -rf $TESTDIR
4532         mkdir -p $TESTDIR
4533         cd $TESTDIR
4534         links1=2
4535         ls
4536         mkdir a b
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir b
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39o "directory cached attributes updated after create"
4548
4549 test_39p() {
4550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4551
4552         local MDTIDX=1
4553         TESTDIR=$DIR/$tdir/$tdir
4554         [ -e $TESTDIR ] && rm -rf $TESTDIR
4555         test_mkdir -p $TESTDIR
4556         cd $TESTDIR
4557         links1=2
4558         ls
4559         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4560         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4561         ls
4562         links2=$(stat -c %h .)
4563         [ $(($links1 + 2)) != $links2 ] &&
4564                 error "wrong links count $(($links1 + 2)) != $links2"
4565         rmdir remote_dir2
4566         links3=$(stat -c %h .)
4567         [ $(($links1 + 1)) != $links3 ] &&
4568                 error "wrong links count $links1 != $links3"
4569         return 0
4570 }
4571 run_test 39p "remote directory cached attributes updated after create ========"
4572
4573 test_39r() {
4574         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4575                 skip "no atime update on old OST"
4576         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4577                 skip_env "ldiskfs only test"
4578         fi
4579
4580         local saved_adiff
4581         saved_adiff=$(do_facet ost1 \
4582                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4583         stack_trap "do_facet ost1 \
4584                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4585
4586         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4587
4588         $LFS setstripe -i 0 $DIR/$tfile
4589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4590                 error "can't write initial file"
4591         cancel_lru_locks osc
4592
4593         # exceed atime_diff and access file
4594         sleep 6
4595         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4596
4597         local atime_cli=$(stat -c %X $DIR/$tfile)
4598         echo "client atime: $atime_cli"
4599         # allow atime update to be written to device
4600         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4601         sleep 5
4602
4603         local ostdev=$(ostdevname 1)
4604         local fid=($(lfs getstripe -y $DIR/$tfile |
4605                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4606         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4607         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4608
4609         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4610         local atime_ost=$(do_facet ost1 "$cmd" |&
4611                           awk -F'[: ]' '/atime:/ { print $4 }')
4612         (( atime_cli == atime_ost )) ||
4613                 error "atime on client $atime_cli != ost $atime_ost"
4614 }
4615 run_test 39r "lazy atime update on OST"
4616
4617 test_39q() { # LU-8041
4618         local testdir=$DIR/$tdir
4619         mkdir -p $testdir
4620         multiop_bg_pause $testdir D_c || error "multiop failed"
4621         local multipid=$!
4622         cancel_lru_locks mdc
4623         kill -USR1 $multipid
4624         local atime=$(stat -c %X $testdir)
4625         [ "$atime" -ne 0 ] || error "atime is zero"
4626 }
4627 run_test 39q "close won't zero out atime"
4628
4629 test_40() {
4630         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4631         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4632                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4633         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4634                 error "$tfile is not 4096 bytes in size"
4635 }
4636 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4637
4638 test_41() {
4639         # bug 1553
4640         small_write $DIR/f41 18
4641 }
4642 run_test 41 "test small file write + fstat ====================="
4643
4644 count_ost_writes() {
4645         lctl get_param -n ${OSC}.*.stats |
4646                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4647                         END { printf("%0.0f", writes) }'
4648 }
4649
4650 # decent default
4651 WRITEBACK_SAVE=500
4652 DIRTY_RATIO_SAVE=40
4653 MAX_DIRTY_RATIO=50
4654 BG_DIRTY_RATIO_SAVE=10
4655 MAX_BG_DIRTY_RATIO=25
4656
4657 start_writeback() {
4658         trap 0
4659         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4660         # dirty_ratio, dirty_background_ratio
4661         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4662                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4663                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4664                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4665         else
4666                 # if file not here, we are a 2.4 kernel
4667                 kill -CONT `pidof kupdated`
4668         fi
4669 }
4670
4671 stop_writeback() {
4672         # setup the trap first, so someone cannot exit the test at the
4673         # exact wrong time and mess up a machine
4674         trap start_writeback EXIT
4675         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4676         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4677                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4678                 sysctl -w vm.dirty_writeback_centisecs=0
4679                 sysctl -w vm.dirty_writeback_centisecs=0
4680                 # save and increase /proc/sys/vm/dirty_ratio
4681                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4682                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4683                 # save and increase /proc/sys/vm/dirty_background_ratio
4684                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4685                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4686         else
4687                 # if file not here, we are a 2.4 kernel
4688                 kill -STOP `pidof kupdated`
4689         fi
4690 }
4691
4692 # ensure that all stripes have some grant before we test client-side cache
4693 setup_test42() {
4694         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4695                 dd if=/dev/zero of=$i bs=4k count=1
4696                 rm $i
4697         done
4698 }
4699
4700 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4701 # file truncation, and file removal.
4702 test_42a() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         setup_test42
4706         cancel_lru_locks $OSC
4707         stop_writeback
4708         sync; sleep 1; sync # just to be safe
4709         BEFOREWRITES=`count_ost_writes`
4710         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4711         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4712         AFTERWRITES=`count_ost_writes`
4713         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4714                 error "$BEFOREWRITES < $AFTERWRITES"
4715         start_writeback
4716 }
4717 run_test 42a "ensure that we don't flush on close"
4718
4719 test_42b() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         setup_test42
4723         cancel_lru_locks $OSC
4724         stop_writeback
4725         sync
4726         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4727         BEFOREWRITES=$(count_ost_writes)
4728         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4729         AFTERWRITES=$(count_ost_writes)
4730         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4731                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4732         fi
4733         BEFOREWRITES=$(count_ost_writes)
4734         sync || error "sync: $?"
4735         AFTERWRITES=$(count_ost_writes)
4736         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4737                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4738         fi
4739         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4740         start_writeback
4741         return 0
4742 }
4743 run_test 42b "test destroy of file with cached dirty data ======"
4744
4745 # if these tests just want to test the effect of truncation,
4746 # they have to be very careful.  consider:
4747 # - the first open gets a {0,EOF}PR lock
4748 # - the first write conflicts and gets a {0, count-1}PW
4749 # - the rest of the writes are under {count,EOF}PW
4750 # - the open for truncate tries to match a {0,EOF}PR
4751 #   for the filesize and cancels the PWs.
4752 # any number of fixes (don't get {0,EOF} on open, match
4753 # composite locks, do smarter file size management) fix
4754 # this, but for now we want these tests to verify that
4755 # the cancellation with truncate intent works, so we
4756 # start the file with a full-file pw lock to match against
4757 # until the truncate.
4758 trunc_test() {
4759         test=$1
4760         file=$DIR/$test
4761         offset=$2
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         # prime the file with 0,EOF PW to match
4765         touch $file
4766         $TRUNCATE $file 0
4767         sync; sync
4768         # now the real test..
4769         dd if=/dev/zero of=$file bs=1024 count=100
4770         BEFOREWRITES=`count_ost_writes`
4771         $TRUNCATE $file $offset
4772         cancel_lru_locks $OSC
4773         AFTERWRITES=`count_ost_writes`
4774         start_writeback
4775 }
4776
4777 test_42c() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         trunc_test 42c 1024
4781         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4782                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4783         rm $file
4784 }
4785 run_test 42c "test partial truncate of file with cached dirty data"
4786
4787 test_42d() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         trunc_test 42d 0
4791         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4792                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4793         rm $file
4794 }
4795 run_test 42d "test complete truncate of file with cached dirty data"
4796
4797 test_42e() { # bug22074
4798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4799
4800         local TDIR=$DIR/${tdir}e
4801         local pages=16 # hardcoded 16 pages, don't change it.
4802         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4803         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4804         local max_dirty_mb
4805         local warmup_files
4806
4807         test_mkdir $DIR/${tdir}e
4808         $LFS setstripe -c 1 $TDIR
4809         createmany -o $TDIR/f $files
4810
4811         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4812
4813         # we assume that with $OSTCOUNT files, at least one of them will
4814         # be allocated on OST0.
4815         warmup_files=$((OSTCOUNT * max_dirty_mb))
4816         createmany -o $TDIR/w $warmup_files
4817
4818         # write a large amount of data into one file and sync, to get good
4819         # avail_grant number from OST.
4820         for ((i=0; i<$warmup_files; i++)); do
4821                 idx=$($LFS getstripe -i $TDIR/w$i)
4822                 [ $idx -ne 0 ] && continue
4823                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4824                 break
4825         done
4826         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4827         sync
4828         $LCTL get_param $proc_osc0/cur_dirty_bytes
4829         $LCTL get_param $proc_osc0/cur_grant_bytes
4830
4831         # create as much dirty pages as we can while not to trigger the actual
4832         # RPCs directly. but depends on the env, VFS may trigger flush during this
4833         # period, hopefully we are good.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4838         done
4839         $LCTL get_param $proc_osc0/cur_dirty_bytes
4840         $LCTL get_param $proc_osc0/cur_grant_bytes
4841
4842         # perform the real test
4843         $LCTL set_param $proc_osc0/rpc_stats 0
4844         for ((;i<$files; i++)); do
4845                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4846                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4847         done
4848         sync
4849         $LCTL get_param $proc_osc0/rpc_stats
4850
4851         local percent=0
4852         local have_ppr=false
4853         $LCTL get_param $proc_osc0/rpc_stats |
4854                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4855                         # skip lines until we are at the RPC histogram data
4856                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4857                         $have_ppr || continue
4858
4859                         # we only want the percent stat for < 16 pages
4860                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4861
4862                         percent=$((percent + WPCT))
4863                         if [[ $percent -gt 15 ]]; then
4864                                 error "less than 16-pages write RPCs" \
4865                                       "$percent% > 15%"
4866                                 break
4867                         fi
4868                 done
4869         rm -rf $TDIR
4870 }
4871 run_test 42e "verify sub-RPC writes are not done synchronously"
4872
4873 test_43A() { # was test_43
4874         test_mkdir $DIR/$tdir
4875         cp -p /bin/ls $DIR/$tdir/$tfile
4876         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4877         pid=$!
4878         # give multiop a chance to open
4879         sleep 1
4880
4881         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4882         kill -USR1 $pid
4883         # Wait for multiop to exit
4884         wait $pid
4885 }
4886 run_test 43A "execution of file opened for write should return -ETXTBSY"
4887
4888 test_43a() {
4889         test_mkdir $DIR/$tdir
4890         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4891         $DIR/$tdir/sleep 60 &
4892         SLEEP_PID=$!
4893         # Make sure exec of $tdir/sleep wins race with truncate
4894         sleep 1
4895         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4896         kill $SLEEP_PID
4897 }
4898 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4899
4900 test_43b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43b "truncate of file being executed should return -ETXTBSY"
4913
4914 test_43c() {
4915         local testdir="$DIR/$tdir"
4916         test_mkdir $testdir
4917         cp $SHELL $testdir/
4918         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4919                 ( cd $testdir && md5sum -c )
4920 }
4921 run_test 43c "md5sum of copy into lustre"
4922
4923 test_44A() { # was test_44
4924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4925
4926         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4927         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4928 }
4929 run_test 44A "zero length read from a sparse stripe"
4930
4931 test_44a() {
4932         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4933                 awk '{ print $2 }')
4934         [ -z "$nstripe" ] && skip "can't get stripe info"
4935         [[ $nstripe -gt $OSTCOUNT ]] &&
4936                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4937
4938         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4939                 awk '{ print $2 }')
4940         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4941                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4942                         awk '{ print $2 }')
4943         fi
4944
4945         OFFSETS="0 $((stride/2)) $((stride-1))"
4946         for offset in $OFFSETS; do
4947                 for i in $(seq 0 $((nstripe-1))); do
4948                         local GLOBALOFFSETS=""
4949                         # size in Bytes
4950                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4951                         local myfn=$DIR/d44a-$size
4952                         echo "--------writing $myfn at $size"
4953                         ll_sparseness_write $myfn $size ||
4954                                 error "ll_sparseness_write"
4955                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4956                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4957                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4958
4959                         for j in $(seq 0 $((nstripe-1))); do
4960                                 # size in Bytes
4961                                 size=$((((j + $nstripe )*$stride + $offset)))
4962                                 ll_sparseness_write $myfn $size ||
4963                                         error "ll_sparseness_write"
4964                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4965                         done
4966                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4967                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4968                         rm -f $myfn
4969                 done
4970         done
4971 }
4972 run_test 44a "test sparse pwrite ==============================="
4973
4974 dirty_osc_total() {
4975         tot=0
4976         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4977                 tot=$(($tot + $d))
4978         done
4979         echo $tot
4980 }
4981 do_dirty_record() {
4982         before=`dirty_osc_total`
4983         echo executing "\"$*\""
4984         eval $*
4985         after=`dirty_osc_total`
4986         echo before $before, after $after
4987 }
4988 test_45() {
4989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4990
4991         f="$DIR/f45"
4992         # Obtain grants from OST if it supports it
4993         echo blah > ${f}_grant
4994         stop_writeback
4995         sync
4996         do_dirty_record "echo blah > $f"
4997         [[ $before -eq $after ]] && error "write wasn't cached"
4998         do_dirty_record "> $f"
4999         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5000         do_dirty_record "echo blah > $f"
5001         [[ $before -eq $after ]] && error "write wasn't cached"
5002         do_dirty_record "sync"
5003         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5004         do_dirty_record "echo blah > $f"
5005         [[ $before -eq $after ]] && error "write wasn't cached"
5006         do_dirty_record "cancel_lru_locks osc"
5007         [[ $before -gt $after ]] ||
5008                 error "lock cancellation didn't lower dirty count"
5009         start_writeback
5010 }
5011 run_test 45 "osc io page accounting ============================"
5012
5013 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5014 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5015 # objects offset and an assert hit when an rpc was built with 1023's mapped
5016 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5017 test_46() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         f="$DIR/f46"
5021         stop_writeback
5022         sync
5023         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5024         sync
5025         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5026         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5027         sync
5028         start_writeback
5029 }
5030 run_test 46 "dirtying a previously written page ================"
5031
5032 # test_47 is removed "Device nodes check" is moved to test_28
5033
5034 test_48a() { # bug 2399
5035         [ "$mds1_FSTYPE" = "zfs" ] &&
5036         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5037                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5038
5039         test_mkdir $DIR/$tdir
5040         cd $DIR/$tdir
5041         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5042         test_mkdir $DIR/$tdir
5043         touch foo || error "'touch foo' failed after recreating cwd"
5044         test_mkdir bar
5045         touch .foo || error "'touch .foo' failed after recreating cwd"
5046         test_mkdir .bar
5047         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5048         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5049         cd . || error "'cd .' failed after recreating cwd"
5050         mkdir . && error "'mkdir .' worked after recreating cwd"
5051         rmdir . && error "'rmdir .' worked after recreating cwd"
5052         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5053         cd .. || error "'cd ..' failed after recreating cwd"
5054 }
5055 run_test 48a "Access renamed working dir (should return errors)="
5056
5057 test_48b() { # bug 2399
5058         rm -rf $DIR/$tdir
5059         test_mkdir $DIR/$tdir
5060         cd $DIR/$tdir
5061         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5062         touch foo && error "'touch foo' worked after removing cwd"
5063         mkdir foo && error "'mkdir foo' worked after removing cwd"
5064         touch .foo && error "'touch .foo' worked after removing cwd"
5065         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5066         ls . > /dev/null && error "'ls .' worked after removing cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         mkdir . && error "'mkdir .' worked after removing cwd"
5069         rmdir . && error "'rmdir .' worked after removing cwd"
5070         ln -s . foo && error "'ln -s .' worked after removing cwd"
5071         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5072 }
5073 run_test 48b "Access removed working dir (should return errors)="
5074
5075 test_48c() { # bug 2350
5076         #lctl set_param debug=-1
5077         #set -vx
5078         rm -rf $DIR/$tdir
5079         test_mkdir -p $DIR/$tdir/dir
5080         cd $DIR/$tdir/dir
5081         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5082         $TRACE touch foo && error "touch foo worked after removing cwd"
5083         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5084         touch .foo && error "touch .foo worked after removing cwd"
5085         mkdir .foo && error "mkdir .foo worked after removing cwd"
5086         $TRACE ls . && error "'ls .' worked after removing cwd"
5087         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5088         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5089         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5090         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5091         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5092 }
5093 run_test 48c "Access removed working subdir (should return errors)"
5094
5095 test_48d() { # bug 2350
5096         #lctl set_param debug=-1
5097         #set -vx
5098         rm -rf $DIR/$tdir
5099         test_mkdir -p $DIR/$tdir/dir
5100         cd $DIR/$tdir/dir
5101         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5102         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5103         $TRACE touch foo && error "'touch foo' worked after removing parent"
5104         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5105         touch .foo && error "'touch .foo' worked after removing parent"
5106         mkdir .foo && error "mkdir .foo worked after removing parent"
5107         $TRACE ls . && error "'ls .' worked after removing parent"
5108         $TRACE ls .. && error "'ls ..' worked after removing parent"
5109         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5110         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5111         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5112         true
5113 }
5114 run_test 48d "Access removed parent subdir (should return errors)"
5115
5116 test_48e() { # bug 4134
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5124         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5125         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5126         # On a buggy kernel addition of "touch foo" after cd .. will
5127         # produce kernel oops in lookup_hash_it
5128         touch ../foo && error "'cd ..' worked after recreate parent"
5129         cd $DIR
5130         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5131 }
5132 run_test 48e "Access to recreated parent subdir (should return errors)"
5133
5134 test_48f() {
5135         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5136                 skip "need MDS >= 2.13.55"
5137         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5138         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5139                 skip "needs different host for mdt1 mdt2"
5140         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5141
5142         $LFS mkdir -i0 $DIR/$tdir
5143         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5144
5145         for d in sub1 sub2 sub3; do
5146                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5147                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5148                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5149         done
5150
5151         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5152 }
5153 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5154
5155 test_49() { # LU-1030
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_ost_nodsh && skip "remote OST with nodsh"
5158
5159         # get ost1 size - $FSNAME-OST0000
5160         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5161                 awk '{ print $4 }')
5162         # write 800M at maximum
5163         [[ $ost1_size -lt 2 ]] && ost1_size=2
5164         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5165
5166         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5167         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5168         local dd_pid=$!
5169
5170         # change max_pages_per_rpc while writing the file
5171         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5172         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5173         # loop until dd process exits
5174         while ps ax -opid | grep -wq $dd_pid; do
5175                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5176                 sleep $((RANDOM % 5 + 1))
5177         done
5178         # restore original max_pages_per_rpc
5179         $LCTL set_param $osc1_mppc=$orig_mppc
5180         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5181 }
5182 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5183
5184 test_50() {
5185         # bug 1485
5186         test_mkdir $DIR/$tdir
5187         cd $DIR/$tdir
5188         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5189 }
5190 run_test 50 "special situations: /proc symlinks  ==============="
5191
5192 test_51a() {    # was test_51
5193         # bug 1516 - create an empty entry right after ".." then split dir
5194         test_mkdir -c1 $DIR/$tdir
5195         touch $DIR/$tdir/foo
5196         $MCREATE $DIR/$tdir/bar
5197         rm $DIR/$tdir/foo
5198         createmany -m $DIR/$tdir/longfile 201
5199         FNUM=202
5200         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5201                 $MCREATE $DIR/$tdir/longfile$FNUM
5202                 FNUM=$(($FNUM + 1))
5203                 echo -n "+"
5204         done
5205         echo
5206         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5207 }
5208 run_test 51a "special situations: split htree with empty entry =="
5209
5210 cleanup_print_lfs_df () {
5211         trap 0
5212         $LFS df
5213         $LFS df -i
5214 }
5215
5216 test_51b() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         local dir=$DIR/$tdir
5220         local nrdirs=$((65536 + 100))
5221
5222         # cleanup the directory
5223         rm -fr $dir
5224
5225         test_mkdir -c1 $dir
5226
5227         $LFS df
5228         $LFS df -i
5229         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5230         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5231         [[ $numfree -lt $nrdirs ]] &&
5232                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5233
5234         # need to check free space for the directories as well
5235         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5236         numfree=$(( blkfree / $(fs_inode_ksize) ))
5237         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5238
5239         trap cleanup_print_lfs_df EXIT
5240
5241         # create files
5242         createmany -d $dir/d $nrdirs || {
5243                 unlinkmany $dir/d $nrdirs
5244                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5245         }
5246
5247         # really created :
5248         nrdirs=$(ls -U $dir | wc -l)
5249
5250         # unlink all but 100 subdirectories, then check it still works
5251         local left=100
5252         local delete=$((nrdirs - left))
5253
5254         $LFS df
5255         $LFS df -i
5256
5257         # for ldiskfs the nlink count should be 1, but this is OSD specific
5258         # and so this is listed for informational purposes only
5259         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5260         unlinkmany -d $dir/d $delete ||
5261                 error "unlink of first $delete subdirs failed"
5262
5263         echo "nlink between: $(stat -c %h $dir)"
5264         local found=$(ls -U $dir | wc -l)
5265         [ $found -ne $left ] &&
5266                 error "can't find subdirs: found only $found, expected $left"
5267
5268         unlinkmany -d $dir/d $delete $left ||
5269                 error "unlink of second $left subdirs failed"
5270         # regardless of whether the backing filesystem tracks nlink accurately
5271         # or not, the nlink count shouldn't be more than "." and ".." here
5272         local after=$(stat -c %h $dir)
5273         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5274                 echo "nlink after: $after"
5275
5276         cleanup_print_lfs_df
5277 }
5278 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5279
5280 test_51d() {
5281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5282         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5283
5284         test_mkdir $DIR/$tdir
5285         createmany -o $DIR/$tdir/t- 1000
5286         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5287         for N in $(seq 0 $((OSTCOUNT - 1))); do
5288                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5289                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5290                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5291                         '($1 == '$N') { objs += 1 } \
5292                         END { printf("%0.0f", objs) }')
5293                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5294         done
5295         unlinkmany $DIR/$tdir/t- 1000
5296
5297         NLAST=0
5298         for N in $(seq 1 $((OSTCOUNT - 1))); do
5299                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5300                         error "OST $N has less objects vs OST $NLAST" \
5301                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5302                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5303                         error "OST $N has less objects vs OST $NLAST" \
5304                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5305
5306                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5307                         error "OST $N has less #0 objects vs OST $NLAST" \
5308                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5309                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5310                         error "OST $N has less #0 objects vs OST $NLAST" \
5311                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5312                 NLAST=$N
5313         done
5314         rm -f $TMP/$tfile
5315 }
5316 run_test 51d "check object distribution"
5317
5318 test_51e() {
5319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5320                 skip_env "ldiskfs only test"
5321         fi
5322
5323         test_mkdir -c1 $DIR/$tdir
5324         test_mkdir -c1 $DIR/$tdir/d0
5325
5326         touch $DIR/$tdir/d0/foo
5327         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5328                 error "file exceed 65000 nlink limit!"
5329         unlinkmany $DIR/$tdir/d0/f- 65001
5330         return 0
5331 }
5332 run_test 51e "check file nlink limit"
5333
5334 test_51f() {
5335         test_mkdir $DIR/$tdir
5336
5337         local max=100000
5338         local ulimit_old=$(ulimit -n)
5339         local spare=20 # number of spare fd's for scripts/libraries, etc.
5340         local mdt=$($LFS getstripe -m $DIR/$tdir)
5341         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5342
5343         echo "MDT$mdt numfree=$numfree, max=$max"
5344         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5345         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5346                 while ! ulimit -n $((numfree + spare)); do
5347                         numfree=$((numfree * 3 / 4))
5348                 done
5349                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5350         else
5351                 echo "left ulimit at $ulimit_old"
5352         fi
5353
5354         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5355                 unlinkmany $DIR/$tdir/f $numfree
5356                 error "create+open $numfree files in $DIR/$tdir failed"
5357         }
5358         ulimit -n $ulimit_old
5359
5360         # if createmany exits at 120s there will be fewer than $numfree files
5361         unlinkmany $DIR/$tdir/f $numfree || true
5362 }
5363 run_test 51f "check many open files limit"
5364
5365 test_52a() {
5366         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5367         test_mkdir $DIR/$tdir
5368         touch $DIR/$tdir/foo
5369         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5370         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5371         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5372         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5373         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5374                                         error "link worked"
5375         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5376         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5377         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5378                                                      error "lsattr"
5379         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5380         cp -r $DIR/$tdir $TMP/
5381         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5382 }
5383 run_test 52a "append-only flag test (should return errors)"
5384
5385 test_52b() {
5386         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5387         test_mkdir $DIR/$tdir
5388         touch $DIR/$tdir/foo
5389         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5390         cat test > $DIR/$tdir/foo && error "cat test worked"
5391         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5392         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5393         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5394                                         error "link worked"
5395         echo foo >> $DIR/$tdir/foo && error "echo worked"
5396         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5397         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5398         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5399         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5400                                                         error "lsattr"
5401         chattr -i $DIR/$tdir/foo || error "chattr failed"
5402
5403         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5404 }
5405 run_test 52b "immutable flag test (should return errors) ======="
5406
5407 test_53() {
5408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5409         remote_mds_nodsh && skip "remote MDS with nodsh"
5410         remote_ost_nodsh && skip "remote OST with nodsh"
5411
5412         local param
5413         local param_seq
5414         local ostname
5415         local mds_last
5416         local mds_last_seq
5417         local ost_last
5418         local ost_last_seq
5419         local ost_last_id
5420         local ostnum
5421         local node
5422         local found=false
5423         local support_last_seq=true
5424
5425         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5426                 support_last_seq=false
5427
5428         # only test MDT0000
5429         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5430         local value
5431         for value in $(do_facet $SINGLEMDS \
5432                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5433                 param=$(echo ${value[0]} | cut -d "=" -f1)
5434                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5435
5436                 if $support_last_seq; then
5437                         param_seq=$(echo $param |
5438                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5439                         mds_last_seq=$(do_facet $SINGLEMDS \
5440                                        $LCTL get_param -n $param_seq)
5441                 fi
5442                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5443
5444                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5445                 node=$(facet_active_host ost$((ostnum+1)))
5446                 param="obdfilter.$ostname.last_id"
5447                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5448                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5449                         ost_last_id=$ost_last
5450
5451                         if $support_last_seq; then
5452                                 ost_last_id=$(echo $ost_last |
5453                                               awk -F':' '{print $2}' |
5454                                               sed -e "s/^0x//g")
5455                                 ost_last_seq=$(echo $ost_last |
5456                                                awk -F':' '{print $1}')
5457                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5458                         fi
5459
5460                         if [[ $ost_last_id != $mds_last ]]; then
5461                                 error "$ost_last_id != $mds_last"
5462                         else
5463                                 found=true
5464                                 break
5465                         fi
5466                 done
5467         done
5468         $found || error "can not match last_seq/last_id for $mdtosc"
5469         return 0
5470 }
5471 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5472
5473 test_54a() {
5474         perl -MSocket -e ';' || skip "no Socket perl module installed"
5475
5476         $SOCKETSERVER $DIR/socket ||
5477                 error "$SOCKETSERVER $DIR/socket failed: $?"
5478         $SOCKETCLIENT $DIR/socket ||
5479                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5480         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5481 }
5482 run_test 54a "unix domain socket test =========================="
5483
5484 test_54b() {
5485         f="$DIR/f54b"
5486         mknod $f c 1 3
5487         chmod 0666 $f
5488         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5489 }
5490 run_test 54b "char device works in lustre ======================"
5491
5492 find_loop_dev() {
5493         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5494         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5495         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5496
5497         for i in $(seq 3 7); do
5498                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5499                 LOOPDEV=$LOOPBASE$i
5500                 LOOPNUM=$i
5501                 break
5502         done
5503 }
5504
5505 cleanup_54c() {
5506         local rc=0
5507         loopdev="$DIR/loop54c"
5508
5509         trap 0
5510         $UMOUNT $DIR/$tdir || rc=$?
5511         losetup -d $loopdev || true
5512         losetup -d $LOOPDEV || true
5513         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5514         return $rc
5515 }
5516
5517 test_54c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         loopdev="$DIR/loop54c"
5521
5522         find_loop_dev
5523         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5524         trap cleanup_54c EXIT
5525         mknod $loopdev b 7 $LOOPNUM
5526         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5527         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5528         losetup $loopdev $DIR/$tfile ||
5529                 error "can't set up $loopdev for $DIR/$tfile"
5530         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5531         test_mkdir $DIR/$tdir
5532         mount -t ext2 $loopdev $DIR/$tdir ||
5533                 error "error mounting $loopdev on $DIR/$tdir"
5534         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5535                 error "dd write"
5536         df $DIR/$tdir
5537         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5538                 error "dd read"
5539         cleanup_54c
5540 }
5541 run_test 54c "block device works in lustre ====================="
5542
5543 test_54d() {
5544         f="$DIR/f54d"
5545         string="aaaaaa"
5546         mknod $f p
5547         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5548 }
5549 run_test 54d "fifo device works in lustre ======================"
5550
5551 test_54e() {
5552         f="$DIR/f54e"
5553         string="aaaaaa"
5554         cp -aL /dev/console $f
5555         echo $string > $f || error "echo $string to $f failed"
5556 }
5557 run_test 54e "console/tty device works in lustre ======================"
5558
5559 test_56a() {
5560         local numfiles=3
5561         local dir=$DIR/$tdir
5562
5563         rm -rf $dir
5564         test_mkdir -p $dir/dir
5565         for i in $(seq $numfiles); do
5566                 touch $dir/file$i
5567                 touch $dir/dir/file$i
5568         done
5569
5570         local numcomp=$($LFS getstripe --component-count $dir)
5571
5572         [[ $numcomp == 0 ]] && numcomp=1
5573
5574         # test lfs getstripe with --recursive
5575         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5576
5577         [[ $filenum -eq $((numfiles * 2)) ]] ||
5578                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5579         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5580         [[ $filenum -eq $numfiles ]] ||
5581                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5582         echo "$LFS getstripe showed obdidx or l_ost_idx"
5583
5584         # test lfs getstripe with file instead of dir
5585         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5586         [[ $filenum -eq 1 ]] ||
5587                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5588         echo "$LFS getstripe file1 passed"
5589
5590         #test lfs getstripe with --verbose
5591         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5592         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5593                 error "$LFS getstripe --verbose $dir: "\
5594                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5595         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5596                 error "$LFS getstripe $dir: showed lmm_magic"
5597
5598         #test lfs getstripe with -v prints lmm_fid
5599         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5600         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5601                 error "$LFS getstripe -v $dir: "\
5602                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5603         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5604                 error "$LFS getstripe $dir: showed lmm_fid by default"
5605         echo "$LFS getstripe --verbose passed"
5606
5607         #check for FID information
5608         local fid1=$($LFS getstripe --fid $dir/file1)
5609         local fid2=$($LFS getstripe --verbose $dir/file1 |
5610                      awk '/lmm_fid: / { print $2; exit; }')
5611         local fid3=$($LFS path2fid $dir/file1)
5612
5613         [ "$fid1" != "$fid2" ] &&
5614                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5615         [ "$fid1" != "$fid3" ] &&
5616                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5617         echo "$LFS getstripe --fid passed"
5618
5619         #test lfs getstripe with --obd
5620         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5621                 error "$LFS getstripe --obd wrong_uuid: should return error"
5622
5623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5624
5625         local ostidx=1
5626         local obduuid=$(ostuuid_from_index $ostidx)
5627         local found=$($LFS getstripe -r --obd $obduuid $dir |
5628                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5629
5630         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5631         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5632                 ((filenum--))
5633         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5634                 ((filenum--))
5635
5636         [[ $found -eq $filenum ]] ||
5637                 error "$LFS getstripe --obd: found $found expect $filenum"
5638         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5639                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5640                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5641                 error "$LFS getstripe --obd: should not show file on other obd"
5642         echo "$LFS getstripe --obd passed"
5643 }
5644 run_test 56a "check $LFS getstripe"
5645
5646 test_56b() {
5647         local dir=$DIR/$tdir
5648         local numdirs=3
5649
5650         test_mkdir $dir
5651         for i in $(seq $numdirs); do
5652                 test_mkdir $dir/dir$i
5653         done
5654
5655         # test lfs getdirstripe default mode is non-recursion, which is
5656         # different from lfs getstripe
5657         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5658
5659         [[ $dircnt -eq 1 ]] ||
5660                 error "$LFS getdirstripe: found $dircnt, not 1"
5661         dircnt=$($LFS getdirstripe --recursive $dir |
5662                 grep -c lmv_stripe_count)
5663         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5664                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5665 }
5666 run_test 56b "check $LFS getdirstripe"
5667
5668 test_56c() {
5669         remote_ost_nodsh && skip "remote OST with nodsh"
5670
5671         local ost_idx=0
5672         local ost_name=$(ostname_from_index $ost_idx)
5673         local old_status=$(ost_dev_status $ost_idx)
5674         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5675
5676         [[ -z "$old_status" ]] ||
5677                 skip_env "OST $ost_name is in $old_status status"
5678
5679         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5680         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5681                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5682         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5683                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5684                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5685         fi
5686
5687         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5688                 error "$LFS df -v showing inactive devices"
5689         sleep_maxage
5690
5691         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5692
5693         [[ "$new_status" =~ "D" ]] ||
5694                 error "$ost_name status is '$new_status', missing 'D'"
5695         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5696                 [[ "$new_status" =~ "N" ]] ||
5697                         error "$ost_name status is '$new_status', missing 'N'"
5698         fi
5699         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5700                 [[ "$new_status" =~ "f" ]] ||
5701                         error "$ost_name status is '$new_status', missing 'f'"
5702         fi
5703
5704         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5705         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5706                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5707         [[ -z "$p" ]] && restore_lustre_params < $p || true
5708         sleep_maxage
5709
5710         new_status=$(ost_dev_status $ost_idx)
5711         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5712                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5713         # can't check 'f' as devices may actually be on flash
5714 }
5715 run_test 56c "check 'lfs df' showing device status"
5716
5717 test_56d() {
5718         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5719         local osts=$($LFS df -v $MOUNT | grep -c OST)
5720
5721         $LFS df $MOUNT
5722
5723         (( mdts == MDSCOUNT )) ||
5724                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5725         (( osts == OSTCOUNT )) ||
5726                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5727 }
5728 run_test 56d "'lfs df -v' prints only configured devices"
5729
5730 NUMFILES=3
5731 NUMDIRS=3
5732 setup_56() {
5733         local local_tdir="$1"
5734         local local_numfiles="$2"
5735         local local_numdirs="$3"
5736         local dir_params="$4"
5737         local dir_stripe_params="$5"
5738
5739         if [ ! -d "$local_tdir" ] ; then
5740                 test_mkdir -p $dir_stripe_params $local_tdir
5741                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5742                 for i in $(seq $local_numfiles) ; do
5743                         touch $local_tdir/file$i
5744                 done
5745                 for i in $(seq $local_numdirs) ; do
5746                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5747                         for j in $(seq $local_numfiles) ; do
5748                                 touch $local_tdir/dir$i/file$j
5749                         done
5750                 done
5751         fi
5752 }
5753
5754 setup_56_special() {
5755         local local_tdir=$1
5756         local local_numfiles=$2
5757         local local_numdirs=$3
5758
5759         setup_56 $local_tdir $local_numfiles $local_numdirs
5760
5761         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5762                 for i in $(seq $local_numfiles) ; do
5763                         mknod $local_tdir/loop${i}b b 7 $i
5764                         mknod $local_tdir/null${i}c c 1 3
5765                         ln -s $local_tdir/file1 $local_tdir/link${i}
5766                 done
5767                 for i in $(seq $local_numdirs) ; do
5768                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5769                         mknod $local_tdir/dir$i/null${i}c c 1 3
5770                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5771                 done
5772         fi
5773 }
5774
5775 test_56g() {
5776         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5777         local expected=$(($NUMDIRS + 2))
5778
5779         setup_56 $dir $NUMFILES $NUMDIRS
5780
5781         # test lfs find with -name
5782         for i in $(seq $NUMFILES) ; do
5783                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5784
5785                 [ $nums -eq $expected ] ||
5786                         error "lfs find -name '*$i' $dir wrong: "\
5787                               "found $nums, expected $expected"
5788         done
5789 }
5790 run_test 56g "check lfs find -name"
5791
5792 test_56h() {
5793         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5794         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5795
5796         setup_56 $dir $NUMFILES $NUMDIRS
5797
5798         # test lfs find with ! -name
5799         for i in $(seq $NUMFILES) ; do
5800                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5801
5802                 [ $nums -eq $expected ] ||
5803                         error "lfs find ! -name '*$i' $dir wrong: "\
5804                               "found $nums, expected $expected"
5805         done
5806 }
5807 run_test 56h "check lfs find ! -name"
5808
5809 test_56i() {
5810         local dir=$DIR/$tdir
5811
5812         test_mkdir $dir
5813
5814         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5815         local out=$($cmd)
5816
5817         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5818 }
5819 run_test 56i "check 'lfs find -ost UUID' skips directories"
5820
5821 test_56j() {
5822         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5823
5824         setup_56_special $dir $NUMFILES $NUMDIRS
5825
5826         local expected=$((NUMDIRS + 1))
5827         local cmd="$LFS find -type d $dir"
5828         local nums=$($cmd | wc -l)
5829
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832 }
5833 run_test 56j "check lfs find -type d"
5834
5835 test_56k() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$(((NUMDIRS + 1) * NUMFILES))
5841         local cmd="$LFS find -type f $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56k "check lfs find -type f"
5848
5849 test_56l() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$((NUMDIRS + NUMFILES))
5855         local cmd="$LFS find -type b $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56l "check lfs find -type b"
5862
5863 test_56m() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type c $dir"
5870         local nums=$($cmd | wc -l)
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56m "check lfs find -type c"
5875
5876 test_56n() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878         setup_56_special $dir $NUMFILES $NUMDIRS
5879
5880         local expected=$((NUMDIRS + NUMFILES))
5881         local cmd="$LFS find -type l $dir"
5882         local nums=$($cmd | wc -l)
5883
5884         [ $nums -eq $expected ] ||
5885                 error "'$cmd' wrong: found $nums, expected $expected"
5886 }
5887 run_test 56n "check lfs find -type l"
5888
5889 test_56o() {
5890         local dir=$DIR/$tdir
5891
5892         setup_56 $dir $NUMFILES $NUMDIRS
5893         utime $dir/file1 > /dev/null || error "utime (1)"
5894         utime $dir/file2 > /dev/null || error "utime (2)"
5895         utime $dir/dir1 > /dev/null || error "utime (3)"
5896         utime $dir/dir2 > /dev/null || error "utime (4)"
5897         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5898         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5899
5900         local expected=4
5901         local nums=$($LFS find -mtime +0 $dir | wc -l)
5902
5903         [ $nums -eq $expected ] ||
5904                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5905
5906         expected=12
5907         cmd="$LFS find -mtime 0 $dir"
5908         nums=$($cmd | wc -l)
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911 }
5912 run_test 56o "check lfs find -mtime for old files"
5913
5914 test_56ob() {
5915         local dir=$DIR/$tdir
5916         local expected=1
5917         local count=0
5918
5919         # just to make sure there is something that won't be found
5920         test_mkdir $dir
5921         touch $dir/$tfile.now
5922
5923         for age in year week day hour min; do
5924                 count=$((count + 1))
5925
5926                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5927                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5928                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5929
5930                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5931                 local nums=$($cmd | wc -l)
5932                 [ $nums -eq $expected ] ||
5933                         error "'$cmd' wrong: found $nums, expected $expected"
5934
5935                 cmd="$LFS find $dir -atime $count${age:0:1}"
5936                 nums=$($cmd | wc -l)
5937                 [ $nums -eq $expected ] ||
5938                         error "'$cmd' wrong: found $nums, expected $expected"
5939         done
5940
5941         sleep 2
5942         cmd="$LFS find $dir -ctime +1s -type f"
5943         nums=$($cmd | wc -l)
5944         (( $nums == $count * 2 + 1)) ||
5945                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5946 }
5947 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5948
5949 test_newerXY_base() {
5950         local x=$1
5951         local y=$2
5952         local dir=$DIR/$tdir
5953         local ref
5954         local negref
5955
5956         if [ $y == "t" ]; then
5957                 if [ $x == "b" ]; then
5958                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5959                 else
5960                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5961                 fi
5962         else
5963                 ref=$DIR/$tfile.newer.$x$y
5964                 touch $ref || error "touch $ref failed"
5965         fi
5966         sleep 2
5967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5968         sleep 2
5969         if [ $y == "t" ]; then
5970                 if [ $x == "b" ]; then
5971                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5972                 else
5973                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5974                 fi
5975         else
5976                 negref=$DIR/$tfile.negnewer.$x$y
5977                 touch $negref || error "touch $negref failed"
5978         fi
5979
5980         local cmd="$LFS find $dir -newer$x$y $ref"
5981         local nums=$(eval $cmd | wc -l)
5982         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5983
5984         [ $nums -eq $expected ] ||
5985                 error "'$cmd' wrong: found $nums, expected $expected"
5986
5987         cmd="$LFS find $dir ! -newer$x$y $negref"
5988         nums=$(eval $cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5993         nums=$(eval $cmd | wc -l)
5994         [ $nums -eq $expected ] ||
5995                 error "'$cmd' wrong: found $nums, expected $expected"
5996
5997         rm -rf $DIR/*
5998 }
5999
6000 test_56oc() {
6001         test_newerXY_base "b" "t"
6002         test_newerXY_base "a" "a"
6003         test_newerXY_base "a" "m"
6004         test_newerXY_base "a" "c"
6005         test_newerXY_base "m" "a"
6006         test_newerXY_base "m" "m"
6007         test_newerXY_base "m" "c"
6008         test_newerXY_base "c" "a"
6009         test_newerXY_base "c" "m"
6010         test_newerXY_base "c" "c"
6011         test_newerXY_base "b" "b"
6012         test_newerXY_base "a" "t"
6013         test_newerXY_base "m" "t"
6014         test_newerXY_base "c" "t"
6015         test_newerXY_base "b" "t"
6016 }
6017 run_test 56oc "check lfs find -newerXY work"
6018
6019 btime_supported() {
6020         local dir=$DIR/$tdir
6021         local rc
6022
6023         mkdir -p $dir
6024         touch $dir/$tfile
6025         $LFS find $dir -btime -1d -type f
6026         rc=$?
6027         rm -rf $dir
6028         return $rc
6029 }
6030
6031 test_56od() {
6032         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6033                 ! btime_supported && skip "btime unsupported on MDS"
6034
6035         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6036                 ! btime_supported && skip "btime unsupported on clients"
6037
6038         local dir=$DIR/$tdir
6039         local ref=$DIR/$tfile.ref
6040         local negref=$DIR/$tfile.negref
6041
6042         mkdir $dir || error "mkdir $dir failed"
6043         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6044         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6045         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6046         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6047         touch $ref || error "touch $ref failed"
6048         # sleep 3 seconds at least
6049         sleep 3
6050
6051         local before=$(do_facet mds1 date +%s)
6052         local skew=$(($(date +%s) - before + 1))
6053
6054         if (( skew < 0 && skew > -5 )); then
6055                 sleep $((0 - skew + 1))
6056                 skew=0
6057         fi
6058
6059         # Set the dir stripe params to limit files all on MDT0,
6060         # otherwise we need to calc the max clock skew between
6061         # the client and MDTs.
6062         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6063         sleep 2
6064         touch $negref || error "touch $negref failed"
6065
6066         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6067         local nums=$($cmd | wc -l)
6068         local expected=$(((NUMFILES + 1) * NUMDIRS))
6069
6070         [ $nums -eq $expected ] ||
6071                 error "'$cmd' wrong: found $nums, expected $expected"
6072
6073         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6074         nums=$($cmd | wc -l)
6075         expected=$((NUMFILES + 1))
6076         [ $nums -eq $expected ] ||
6077                 error "'$cmd' wrong: found $nums, expected $expected"
6078
6079         [ $skew -lt 0 ] && return
6080
6081         local after=$(do_facet mds1 date +%s)
6082         local age=$((after - before + 1 + skew))
6083
6084         cmd="$LFS find $dir -btime -${age}s -type f"
6085         nums=$($cmd | wc -l)
6086         expected=$(((NUMFILES + 1) * NUMDIRS))
6087
6088         echo "Clock skew between client and server: $skew, age:$age"
6089         [ $nums -eq $expected ] ||
6090                 error "'$cmd' wrong: found $nums, expected $expected"
6091
6092         expected=$(($NUMDIRS + 1))
6093         cmd="$LFS find $dir -btime -${age}s -type d"
6094         nums=$($cmd | wc -l)
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097         rm -f $ref $negref || error "Failed to remove $ref $negref"
6098 }
6099 run_test 56od "check lfs find -btime with units"
6100
6101 test_56p() {
6102         [ $RUNAS_ID -eq $UID ] &&
6103                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6104
6105         local dir=$DIR/$tdir
6106
6107         setup_56 $dir $NUMFILES $NUMDIRS
6108         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6109
6110         local expected=$NUMFILES
6111         local cmd="$LFS find -uid $RUNAS_ID $dir"
6112         local nums=$($cmd | wc -l)
6113
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6118         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122 }
6123 run_test 56p "check lfs find -uid and ! -uid"
6124
6125 test_56q() {
6126         [ $RUNAS_ID -eq $UID ] &&
6127                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6128
6129         local dir=$DIR/$tdir
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6133
6134         local expected=$NUMFILES
6135         local cmd="$LFS find -gid $RUNAS_GID $dir"
6136         local nums=$($cmd | wc -l)
6137
6138         [ $nums -eq $expected ] ||
6139                 error "'$cmd' wrong: found $nums, expected $expected"
6140
6141         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6142         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6143         nums=$($cmd | wc -l)
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146 }
6147 run_test 56q "check lfs find -gid and ! -gid"
6148
6149 test_56r() {
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153
6154         local expected=12
6155         local cmd="$LFS find -size 0 -type f -lazy $dir"
6156         local nums=$($cmd | wc -l)
6157
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160         cmd="$LFS find -size 0 -type f $dir"
6161         nums=$($cmd | wc -l)
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164
6165         expected=0
6166         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6167         nums=$($cmd | wc -l)
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170         cmd="$LFS find ! -size 0 -type f $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174
6175         echo "test" > $dir/$tfile
6176         echo "test2" > $dir/$tfile.2 && sync
6177         expected=1
6178         cmd="$LFS find -size 5 -type f -lazy $dir"
6179         nums=$($cmd | wc -l)
6180         [ $nums -eq $expected ] ||
6181                 error "'$cmd' wrong: found $nums, expected $expected"
6182         cmd="$LFS find -size 5 -type f $dir"
6183         nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186
6187         expected=1
6188         cmd="$LFS find -size +5 -type f -lazy $dir"
6189         nums=$($cmd | wc -l)
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192         cmd="$LFS find -size +5 -type f $dir"
6193         nums=$($cmd | wc -l)
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196
6197         expected=2
6198         cmd="$LFS find -size +0 -type f -lazy $dir"
6199         nums=$($cmd | wc -l)
6200         [ $nums -eq $expected ] ||
6201                 error "'$cmd' wrong: found $nums, expected $expected"
6202         cmd="$LFS find -size +0 -type f $dir"
6203         nums=$($cmd | wc -l)
6204         [ $nums -eq $expected ] ||
6205                 error "'$cmd' wrong: found $nums, expected $expected"
6206
6207         expected=2
6208         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6209         nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find ! -size -5 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=12
6218         cmd="$LFS find -size -5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size -5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226 }
6227 run_test 56r "check lfs find -size works"
6228
6229 test_56ra_sub() {
6230         local expected=$1
6231         local glimpses=$2
6232         local cmd="$3"
6233
6234         cancel_lru_locks $OSC
6235
6236         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6237         local nums=$($cmd | wc -l)
6238
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6243
6244         if (( rpcs_before + glimpses != rpcs_after )); then
6245                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6246                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6247
6248                 if [[ $glimpses == 0 ]]; then
6249                         error "'$cmd' should not send glimpse RPCs to OST"
6250                 else
6251                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6252                 fi
6253         fi
6254 }
6255
6256 test_56ra() {
6257         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6258                 skip "MDS < 2.12.58 doesn't return LSOM data"
6259         local dir=$DIR/$tdir
6260         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6261
6262         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6263
6264         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6265         $LCTL set_param -n llite.*.statahead_agl=0
6266         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6267
6268         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6269         # open and close all files to ensure LSOM is updated
6270         cancel_lru_locks $OSC
6271         find $dir -type f | xargs cat > /dev/null
6272
6273         #   expect_found  glimpse_rpcs  command_to_run
6274         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6275         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6276         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6277         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6278
6279         echo "test" > $dir/$tfile
6280         echo "test2" > $dir/$tfile.2 && sync
6281         cancel_lru_locks $OSC
6282         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6283
6284         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6285         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6286         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6287         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6288
6289         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6290         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6291         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6292         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6293         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6294         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6295 }
6296 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6297
6298 test_56rb() {
6299         local dir=$DIR/$tdir
6300         local tmp=$TMP/$tfile.log
6301         local mdt_idx;
6302
6303         test_mkdir -p $dir || error "failed to mkdir $dir"
6304         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6305                 error "failed to setstripe $dir/$tfile"
6306         mdt_idx=$($LFS getdirstripe -i $dir)
6307         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6308
6309         stack_trap "rm -f $tmp" EXIT
6310         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6311         ! grep -q obd_uuid $tmp ||
6312                 error "failed to find --size +100K --ost 0 $dir"
6313         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6314         ! grep -q obd_uuid $tmp ||
6315                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6316 }
6317 run_test 56rb "check lfs find --size --ost/--mdt works"
6318
6319 test_56s() { # LU-611 #LU-9369
6320         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6321
6322         local dir=$DIR/$tdir
6323         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6324
6325         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6326         for i in $(seq $NUMDIRS); do
6327                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6328         done
6329
6330         local expected=$NUMDIRS
6331         local cmd="$LFS find -c $OSTCOUNT $dir"
6332         local nums=$($cmd | wc -l)
6333
6334         [ $nums -eq $expected ] || {
6335                 $LFS getstripe -R $dir
6336                 error "'$cmd' wrong: found $nums, expected $expected"
6337         }
6338
6339         expected=$((NUMDIRS + onestripe))
6340         cmd="$LFS find -stripe-count +0 -type f $dir"
6341         nums=$($cmd | wc -l)
6342         [ $nums -eq $expected ] || {
6343                 $LFS getstripe -R $dir
6344                 error "'$cmd' wrong: found $nums, expected $expected"
6345         }
6346
6347         expected=$onestripe
6348         cmd="$LFS find -stripe-count 1 -type f $dir"
6349         nums=$($cmd | wc -l)
6350         [ $nums -eq $expected ] || {
6351                 $LFS getstripe -R $dir
6352                 error "'$cmd' wrong: found $nums, expected $expected"
6353         }
6354
6355         cmd="$LFS find -stripe-count -2 -type f $dir"
6356         nums=$($cmd | wc -l)
6357         [ $nums -eq $expected ] || {
6358                 $LFS getstripe -R $dir
6359                 error "'$cmd' wrong: found $nums, expected $expected"
6360         }
6361
6362         expected=0
6363         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6364         nums=$($cmd | wc -l)
6365         [ $nums -eq $expected ] || {
6366                 $LFS getstripe -R $dir
6367                 error "'$cmd' wrong: found $nums, expected $expected"
6368         }
6369 }
6370 run_test 56s "check lfs find -stripe-count works"
6371
6372 test_56t() { # LU-611 #LU-9369
6373         local dir=$DIR/$tdir
6374
6375         setup_56 $dir 0 $NUMDIRS
6376         for i in $(seq $NUMDIRS); do
6377                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6378         done
6379
6380         local expected=$NUMDIRS
6381         local cmd="$LFS find -S 8M $dir"
6382         local nums=$($cmd | wc -l)
6383
6384         [ $nums -eq $expected ] || {
6385                 $LFS getstripe -R $dir
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387         }
6388         rm -rf $dir
6389
6390         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6391
6392         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6393
6394         expected=$(((NUMDIRS + 1) * NUMFILES))
6395         cmd="$LFS find -stripe-size 512k -type f $dir"
6396         nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         cmd="$LFS find -stripe-size +320k -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404
6405         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6406         cmd="$LFS find -stripe-size +200k -type f $dir"
6407         nums=$($cmd | wc -l)
6408         [ $nums -eq $expected ] ||
6409                 error "'$cmd' wrong: found $nums, expected $expected"
6410
6411         cmd="$LFS find -stripe-size -640k -type f $dir"
6412         nums=$($cmd | wc -l)
6413         [ $nums -eq $expected ] ||
6414                 error "'$cmd' wrong: found $nums, expected $expected"
6415
6416         expected=4
6417         cmd="$LFS find -stripe-size 256k -type f $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         cmd="$LFS find -stripe-size -320k -type f $dir"
6423         nums=$($cmd | wc -l)
6424         [ $nums -eq $expected ] ||
6425                 error "'$cmd' wrong: found $nums, expected $expected"
6426
6427         expected=0
6428         cmd="$LFS find -stripe-size 1024k -type f $dir"
6429         nums=$($cmd | wc -l)
6430         [ $nums -eq $expected ] ||
6431                 error "'$cmd' wrong: found $nums, expected $expected"
6432 }
6433 run_test 56t "check lfs find -stripe-size works"
6434
6435 test_56u() { # LU-611
6436         local dir=$DIR/$tdir
6437
6438         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6439
6440         if [[ $OSTCOUNT -gt 1 ]]; then
6441                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6442                 onestripe=4
6443         else
6444                 onestripe=0
6445         fi
6446
6447         local expected=$(((NUMDIRS + 1) * NUMFILES))
6448         local cmd="$LFS find -stripe-index 0 -type f $dir"
6449         local nums=$($cmd | wc -l)
6450
6451         [ $nums -eq $expected ] ||
6452                 error "'$cmd' wrong: found $nums, expected $expected"
6453
6454         expected=$onestripe
6455         cmd="$LFS find -stripe-index 1 -type f $dir"
6456         nums=$($cmd | wc -l)
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6461         nums=$($cmd | wc -l)
6462         [ $nums -eq $expected ] ||
6463                 error "'$cmd' wrong: found $nums, expected $expected"
6464
6465         expected=0
6466         # This should produce an error and not return any files
6467         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6468         nums=$($cmd 2>/dev/null | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         if [[ $OSTCOUNT -gt 1 ]]; then
6473                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6474                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6475                 nums=$($cmd | wc -l)
6476                 [ $nums -eq $expected ] ||
6477                         error "'$cmd' wrong: found $nums, expected $expected"
6478         fi
6479 }
6480 run_test 56u "check lfs find -stripe-index works"
6481
6482 test_56v() {
6483         local mdt_idx=0
6484         local dir=$DIR/$tdir
6485
6486         setup_56 $dir $NUMFILES $NUMDIRS
6487
6488         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6489         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6490
6491         for file in $($LFS find -m $UUID $dir); do
6492                 file_midx=$($LFS getstripe -m $file)
6493                 [ $file_midx -eq $mdt_idx ] ||
6494                         error "lfs find -m $UUID != getstripe -m $file_midx"
6495         done
6496 }
6497 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6498
6499 test_56w() {
6500         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6502
6503         local dir=$DIR/$tdir
6504
6505         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6506
6507         local stripe_size=$($LFS getstripe -S -d $dir) ||
6508                 error "$LFS getstripe -S -d $dir failed"
6509         stripe_size=${stripe_size%% *}
6510
6511         local file_size=$((stripe_size * OSTCOUNT))
6512         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6513         local required_space=$((file_num * file_size))
6514         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6515                            head -n1)
6516         [[ $free_space -le $((required_space / 1024)) ]] &&
6517                 skip_env "need $required_space, have $free_space kbytes"
6518
6519         local dd_bs=65536
6520         local dd_count=$((file_size / dd_bs))
6521
6522         # write data into the files
6523         local i
6524         local j
6525         local file
6526
6527         for i in $(seq $NUMFILES); do
6528                 file=$dir/file$i
6529                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6530                         error "write data into $file failed"
6531         done
6532         for i in $(seq $NUMDIRS); do
6533                 for j in $(seq $NUMFILES); do
6534                         file=$dir/dir$i/file$j
6535                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6536                                 error "write data into $file failed"
6537                 done
6538         done
6539
6540         # $LFS_MIGRATE will fail if hard link migration is unsupported
6541         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6542                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6543                         error "creating links to $dir/dir1/file1 failed"
6544         fi
6545
6546         local expected=-1
6547
6548         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6549
6550         # lfs_migrate file
6551         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6552
6553         echo "$cmd"
6554         eval $cmd || error "$cmd failed"
6555
6556         check_stripe_count $dir/file1 $expected
6557
6558         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6559         then
6560                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6561                 # OST 1 if it is on OST 0. This file is small enough to
6562                 # be on only one stripe.
6563                 file=$dir/migr_1_ost
6564                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6565                         error "write data into $file failed"
6566                 local obdidx=$($LFS getstripe -i $file)
6567                 local oldmd5=$(md5sum $file)
6568                 local newobdidx=0
6569
6570                 [[ $obdidx -eq 0 ]] && newobdidx=1
6571                 cmd="$LFS migrate -i $newobdidx $file"
6572                 echo $cmd
6573                 eval $cmd || error "$cmd failed"
6574
6575                 local realobdix=$($LFS getstripe -i $file)
6576                 local newmd5=$(md5sum $file)
6577
6578                 [[ $newobdidx -ne $realobdix ]] &&
6579                         error "new OST is different (was=$obdidx, "\
6580                               "wanted=$newobdidx, got=$realobdix)"
6581                 [[ "$oldmd5" != "$newmd5" ]] &&
6582                         error "md5sum differ: $oldmd5, $newmd5"
6583         fi
6584
6585         # lfs_migrate dir
6586         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6587         echo "$cmd"
6588         eval $cmd || error "$cmd failed"
6589
6590         for j in $(seq $NUMFILES); do
6591                 check_stripe_count $dir/dir1/file$j $expected
6592         done
6593
6594         # lfs_migrate works with lfs find
6595         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6596              $LFS_MIGRATE -y -c $expected"
6597         echo "$cmd"
6598         eval $cmd || error "$cmd failed"
6599
6600         for i in $(seq 2 $NUMFILES); do
6601                 check_stripe_count $dir/file$i $expected
6602         done
6603         for i in $(seq 2 $NUMDIRS); do
6604                 for j in $(seq $NUMFILES); do
6605                 check_stripe_count $dir/dir$i/file$j $expected
6606                 done
6607         done
6608 }
6609 run_test 56w "check lfs_migrate -c stripe_count works"
6610
6611 test_56wb() {
6612         local file1=$DIR/$tdir/file1
6613         local create_pool=false
6614         local initial_pool=$($LFS getstripe -p $DIR)
6615         local pool_list=()
6616         local pool=""
6617
6618         echo -n "Creating test dir..."
6619         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6620         echo "done."
6621
6622         echo -n "Creating test file..."
6623         touch $file1 || error "cannot create file"
6624         echo "done."
6625
6626         echo -n "Detecting existing pools..."
6627         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6628
6629         if [ ${#pool_list[@]} -gt 0 ]; then
6630                 echo "${pool_list[@]}"
6631                 for thispool in "${pool_list[@]}"; do
6632                         if [[ -z "$initial_pool" ||
6633                               "$initial_pool" != "$thispool" ]]; then
6634                                 pool="$thispool"
6635                                 echo "Using existing pool '$pool'"
6636                                 break
6637                         fi
6638                 done
6639         else
6640                 echo "none detected."
6641         fi
6642         if [ -z "$pool" ]; then
6643                 pool=${POOL:-testpool}
6644                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6645                 echo -n "Creating pool '$pool'..."
6646                 create_pool=true
6647                 pool_add $pool &> /dev/null ||
6648                         error "pool_add failed"
6649                 echo "done."
6650
6651                 echo -n "Adding target to pool..."
6652                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6653                         error "pool_add_targets failed"
6654                 echo "done."
6655         fi
6656
6657         echo -n "Setting pool using -p option..."
6658         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6659                 error "migrate failed rc = $?"
6660         echo "done."
6661
6662         echo -n "Verifying test file is in pool after migrating..."
6663         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6664                 error "file was not migrated to pool $pool"
6665         echo "done."
6666
6667         echo -n "Removing test file from pool '$pool'..."
6668         # "lfs migrate $file" won't remove the file from the pool
6669         # until some striping information is changed.
6670         $LFS migrate -c 1 $file1 &> /dev/null ||
6671                 error "cannot remove from pool"
6672         [ "$($LFS getstripe -p $file1)" ] &&
6673                 error "pool still set"
6674         echo "done."
6675
6676         echo -n "Setting pool using --pool option..."
6677         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6678                 error "migrate failed rc = $?"
6679         echo "done."
6680
6681         # Clean up
6682         rm -f $file1
6683         if $create_pool; then
6684                 destroy_test_pools 2> /dev/null ||
6685                         error "destroy test pools failed"
6686         fi
6687 }
6688 run_test 56wb "check lfs_migrate pool support"
6689
6690 test_56wc() {
6691         local file1="$DIR/$tdir/file1"
6692         local parent_ssize
6693         local parent_scount
6694         local cur_ssize
6695         local cur_scount
6696         local orig_ssize
6697
6698         echo -n "Creating test dir..."
6699         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6700         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6701                 error "cannot set stripe by '-S 1M -c 1'"
6702         echo "done"
6703
6704         echo -n "Setting initial stripe for test file..."
6705         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6706                 error "cannot set stripe"
6707         cur_ssize=$($LFS getstripe -S "$file1")
6708         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6709         echo "done."
6710
6711         # File currently set to -S 512K -c 1
6712
6713         # Ensure -c and -S options are rejected when -R is set
6714         echo -n "Verifying incompatible options are detected..."
6715         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6716                 error "incompatible -c and -R options not detected"
6717         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6718                 error "incompatible -S and -R options not detected"
6719         echo "done."
6720
6721         # Ensure unrecognized options are passed through to 'lfs migrate'
6722         echo -n "Verifying -S option is passed through to lfs migrate..."
6723         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6724                 error "migration failed"
6725         cur_ssize=$($LFS getstripe -S "$file1")
6726         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6727         echo "done."
6728
6729         # File currently set to -S 1M -c 1
6730
6731         # Ensure long options are supported
6732         echo -n "Verifying long options supported..."
6733         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6734                 error "long option without argument not supported"
6735         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6736                 error "long option with argument not supported"
6737         cur_ssize=$($LFS getstripe -S "$file1")
6738         [ $cur_ssize -eq 524288 ] ||
6739                 error "migrate --stripe-size $cur_ssize != 524288"
6740         echo "done."
6741
6742         # File currently set to -S 512K -c 1
6743
6744         if [ "$OSTCOUNT" -gt 1 ]; then
6745                 echo -n "Verifying explicit stripe count can be set..."
6746                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6747                         error "migrate failed"
6748                 cur_scount=$($LFS getstripe -c "$file1")
6749                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6750                 echo "done."
6751         fi
6752
6753         # File currently set to -S 512K -c 1 or -S 512K -c 2
6754
6755         # Ensure parent striping is used if -R is set, and no stripe
6756         # count or size is specified
6757         echo -n "Setting stripe for parent directory..."
6758         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6759                 error "cannot set stripe '-S 2M -c 1'"
6760         echo "done."
6761
6762         echo -n "Verifying restripe option uses parent stripe settings..."
6763         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6764         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6765         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6766                 error "migrate failed"
6767         cur_ssize=$($LFS getstripe -S "$file1")
6768         [ $cur_ssize -eq $parent_ssize ] ||
6769                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6770         cur_scount=$($LFS getstripe -c "$file1")
6771         [ $cur_scount -eq $parent_scount ] ||
6772                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6773         echo "done."
6774
6775         # File currently set to -S 1M -c 1
6776
6777         # Ensure striping is preserved if -R is not set, and no stripe
6778         # count or size is specified
6779         echo -n "Verifying striping size preserved when not specified..."
6780         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6781         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6782                 error "cannot set stripe on parent directory"
6783         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6784                 error "migrate failed"
6785         cur_ssize=$($LFS getstripe -S "$file1")
6786         [ $cur_ssize -eq $orig_ssize ] ||
6787                 error "migrate by default $cur_ssize != $orig_ssize"
6788         echo "done."
6789
6790         # Ensure file name properly detected when final option has no argument
6791         echo -n "Verifying file name properly detected..."
6792         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6793                 error "file name interpreted as option argument"
6794         echo "done."
6795
6796         # Clean up
6797         rm -f "$file1"
6798 }
6799 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6800
6801 test_56wd() {
6802         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6803
6804         local file1=$DIR/$tdir/file1
6805
6806         echo -n "Creating test dir..."
6807         test_mkdir $DIR/$tdir || error "cannot create dir"
6808         echo "done."
6809
6810         echo -n "Creating test file..."
6811         touch $file1
6812         echo "done."
6813
6814         # Ensure 'lfs migrate' will fail by using a non-existent option,
6815         # and make sure rsync is not called to recover
6816         echo -n "Make sure --no-rsync option works..."
6817         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6818                 grep -q 'refusing to fall back to rsync' ||
6819                 error "rsync was called with --no-rsync set"
6820         echo "done."
6821
6822         # Ensure rsync is called without trying 'lfs migrate' first
6823         echo -n "Make sure --rsync option works..."
6824         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6825                 grep -q 'falling back to rsync' &&
6826                 error "lfs migrate was called with --rsync set"
6827         echo "done."
6828
6829         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6830         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6831                 grep -q 'at the same time' ||
6832                 error "--rsync and --no-rsync accepted concurrently"
6833         echo "done."
6834
6835         # Clean up
6836         rm -f $file1
6837 }
6838 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6839
6840 test_56we() {
6841         local td=$DIR/$tdir
6842         local tf=$td/$tfile
6843
6844         test_mkdir $td || error "cannot create $td"
6845         touch $tf || error "cannot touch $tf"
6846
6847         echo -n "Make sure --non-direct|-D works..."
6848         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6849                 grep -q "lfs migrate --non-direct" ||
6850                 error "--non-direct option cannot work correctly"
6851         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6852                 grep -q "lfs migrate -D" ||
6853                 error "-D option cannot work correctly"
6854         echo "done."
6855 }
6856 run_test 56we "check lfs_migrate --non-direct|-D support"
6857
6858 test_56x() {
6859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6860         check_swap_layouts_support
6861
6862         local dir=$DIR/$tdir
6863         local ref1=/etc/passwd
6864         local file1=$dir/file1
6865
6866         test_mkdir $dir || error "creating dir $dir"
6867         $LFS setstripe -c 2 $file1
6868         cp $ref1 $file1
6869         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6870         stripe=$($LFS getstripe -c $file1)
6871         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6872         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6873
6874         # clean up
6875         rm -f $file1
6876 }
6877 run_test 56x "lfs migration support"
6878
6879 test_56xa() {
6880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6881         check_swap_layouts_support
6882
6883         local dir=$DIR/$tdir/$testnum
6884
6885         test_mkdir -p $dir
6886
6887         local ref1=/etc/passwd
6888         local file1=$dir/file1
6889
6890         $LFS setstripe -c 2 $file1
6891         cp $ref1 $file1
6892         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6893
6894         local stripe=$($LFS getstripe -c $file1)
6895
6896         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6897         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6898
6899         # clean up
6900         rm -f $file1
6901 }
6902 run_test 56xa "lfs migration --block support"
6903
6904 check_migrate_links() {
6905         local dir="$1"
6906         local file1="$dir/file1"
6907         local begin="$2"
6908         local count="$3"
6909         local runas="$4"
6910         local total_count=$(($begin + $count - 1))
6911         local symlink_count=10
6912         local uniq_count=10
6913
6914         if [ ! -f "$file1" ]; then
6915                 echo -n "creating initial file..."
6916                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6917                         error "cannot setstripe initial file"
6918                 echo "done"
6919
6920                 echo -n "creating symlinks..."
6921                 for s in $(seq 1 $symlink_count); do
6922                         ln -s "$file1" "$dir/slink$s" ||
6923                                 error "cannot create symlinks"
6924                 done
6925                 echo "done"
6926
6927                 echo -n "creating nonlinked files..."
6928                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6929                         error "cannot create nonlinked files"
6930                 echo "done"
6931         fi
6932
6933         # create hard links
6934         if [ ! -f "$dir/file$total_count" ]; then
6935                 echo -n "creating hard links $begin:$total_count..."
6936                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6937                         /dev/null || error "cannot create hard links"
6938                 echo "done"
6939         fi
6940
6941         echo -n "checking number of hard links listed in xattrs..."
6942         local fid=$($LFS getstripe -F "$file1")
6943         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6944
6945         echo "${#paths[*]}"
6946         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6947                         skip "hard link list has unexpected size, skipping test"
6948         fi
6949         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6950                         error "link names should exceed xattrs size"
6951         fi
6952
6953         echo -n "migrating files..."
6954         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6955         local rc=$?
6956         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6957         echo "done"
6958
6959         # make sure all links have been properly migrated
6960         echo -n "verifying files..."
6961         fid=$($LFS getstripe -F "$file1") ||
6962                 error "cannot get fid for file $file1"
6963         for i in $(seq 2 $total_count); do
6964                 local fid2=$($LFS getstripe -F $dir/file$i)
6965
6966                 [ "$fid2" == "$fid" ] ||
6967                         error "migrated hard link has mismatched FID"
6968         done
6969
6970         # make sure hard links were properly detected, and migration was
6971         # performed only once for the entire link set; nonlinked files should
6972         # also be migrated
6973         local actual=$(grep -c 'done' <<< "$migrate_out")
6974         local expected=$(($uniq_count + 1))
6975
6976         [ "$actual" -eq  "$expected" ] ||
6977                 error "hard links individually migrated ($actual != $expected)"
6978
6979         # make sure the correct number of hard links are present
6980         local hardlinks=$(stat -c '%h' "$file1")
6981
6982         [ $hardlinks -eq $total_count ] ||
6983                 error "num hard links $hardlinks != $total_count"
6984         echo "done"
6985
6986         return 0
6987 }
6988
6989 test_56xb() {
6990         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6991                 skip "Need MDS version at least 2.10.55"
6992
6993         local dir="$DIR/$tdir"
6994
6995         test_mkdir "$dir" || error "cannot create dir $dir"
6996
6997         echo "testing lfs migrate mode when all links fit within xattrs"
6998         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6999
7000         echo "testing rsync mode when all links fit within xattrs"
7001         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7002
7003         echo "testing lfs migrate mode when all links do not fit within xattrs"
7004         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7005
7006         echo "testing rsync mode when all links do not fit within xattrs"
7007         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7008
7009         chown -R $RUNAS_ID $dir
7010         echo "testing non-root lfs migrate mode when not all links are in xattr"
7011         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7012
7013         # clean up
7014         rm -rf $dir
7015 }
7016 run_test 56xb "lfs migration hard link support"
7017
7018 test_56xc() {
7019         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7020
7021         local dir="$DIR/$tdir"
7022
7023         test_mkdir "$dir" || error "cannot create dir $dir"
7024
7025         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7026         echo -n "Setting initial stripe for 20MB test file..."
7027         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7028                 error "cannot setstripe 20MB file"
7029         echo "done"
7030         echo -n "Sizing 20MB test file..."
7031         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7032         echo "done"
7033         echo -n "Verifying small file autostripe count is 1..."
7034         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7035                 error "cannot migrate 20MB file"
7036         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7037                 error "cannot get stripe for $dir/20mb"
7038         [ $stripe_count -eq 1 ] ||
7039                 error "unexpected stripe count $stripe_count for 20MB file"
7040         rm -f "$dir/20mb"
7041         echo "done"
7042
7043         # Test 2: File is small enough to fit within the available space on
7044         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7045         # have at least an additional 1KB for each desired stripe for test 3
7046         echo -n "Setting stripe for 1GB test file..."
7047         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7048         echo "done"
7049         echo -n "Sizing 1GB test file..."
7050         # File size is 1GB + 3KB
7051         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7052         echo "done"
7053
7054         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7055         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7056         if (( avail > 524288 * OSTCOUNT )); then
7057                 echo -n "Migrating 1GB file..."
7058                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7059                         error "cannot migrate 1GB file"
7060                 echo "done"
7061                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7062                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7063                         error "cannot getstripe for 1GB file"
7064                 [ $stripe_count -eq 2 ] ||
7065                         error "unexpected stripe count $stripe_count != 2"
7066                 echo "done"
7067         fi
7068
7069         # Test 3: File is too large to fit within the available space on
7070         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7071         if [ $OSTCOUNT -ge 3 ]; then
7072                 # The required available space is calculated as
7073                 # file size (1GB + 3KB) / OST count (3).
7074                 local kb_per_ost=349526
7075
7076                 echo -n "Migrating 1GB file with limit..."
7077                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7078                         error "cannot migrate 1GB file with limit"
7079                 echo "done"
7080
7081                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7082                 echo -n "Verifying 1GB autostripe count with limited space..."
7083                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7084                         error "unexpected stripe count $stripe_count (min 3)"
7085                 echo "done"
7086         fi
7087
7088         # clean up
7089         rm -rf $dir
7090 }
7091 run_test 56xc "lfs migration autostripe"
7092
7093 test_56xd() {
7094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7095
7096         local dir=$DIR/$tdir
7097         local f_mgrt=$dir/$tfile.mgrt
7098         local f_yaml=$dir/$tfile.yaml
7099         local f_copy=$dir/$tfile.copy
7100         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7101         local layout_copy="-c 2 -S 2M -i 1"
7102         local yamlfile=$dir/yamlfile
7103         local layout_before;
7104         local layout_after;
7105
7106         test_mkdir "$dir" || error "cannot create dir $dir"
7107         $LFS setstripe $layout_yaml $f_yaml ||
7108                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7109         $LFS getstripe --yaml $f_yaml > $yamlfile
7110         $LFS setstripe $layout_copy $f_copy ||
7111                 error "cannot setstripe $f_copy with layout $layout_copy"
7112         touch $f_mgrt
7113         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7114
7115         # 1. test option --yaml
7116         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7117                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7118         layout_before=$(get_layout_param $f_yaml)
7119         layout_after=$(get_layout_param $f_mgrt)
7120         [ "$layout_after" == "$layout_before" ] ||
7121                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7122
7123         # 2. test option --copy
7124         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7125                 error "cannot migrate $f_mgrt with --copy $f_copy"
7126         layout_before=$(get_layout_param $f_copy)
7127         layout_after=$(get_layout_param $f_mgrt)
7128         [ "$layout_after" == "$layout_before" ] ||
7129                 error "lfs_migrate --copy: $layout_after != $layout_before"
7130 }
7131 run_test 56xd "check lfs_migrate --yaml and --copy support"
7132
7133 test_56xe() {
7134         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7135
7136         local dir=$DIR/$tdir
7137         local f_comp=$dir/$tfile
7138         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7139         local layout_before=""
7140         local layout_after=""
7141
7142         test_mkdir "$dir" || error "cannot create dir $dir"
7143         $LFS setstripe $layout $f_comp ||
7144                 error "cannot setstripe $f_comp with layout $layout"
7145         layout_before=$(get_layout_param $f_comp)
7146         dd if=/dev/zero of=$f_comp bs=1M count=4
7147
7148         # 1. migrate a comp layout file by lfs_migrate
7149         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7150         layout_after=$(get_layout_param $f_comp)
7151         [ "$layout_before" == "$layout_after" ] ||
7152                 error "lfs_migrate: $layout_before != $layout_after"
7153
7154         # 2. migrate a comp layout file by lfs migrate
7155         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7156         layout_after=$(get_layout_param $f_comp)
7157         [ "$layout_before" == "$layout_after" ] ||
7158                 error "lfs migrate: $layout_before != $layout_after"
7159 }
7160 run_test 56xe "migrate a composite layout file"
7161
7162 test_56xf() {
7163         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7164
7165         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7166                 skip "Need server version at least 2.13.53"
7167
7168         local dir=$DIR/$tdir
7169         local f_comp=$dir/$tfile
7170         local layout="-E 1M -c1 -E -1 -c2"
7171         local fid_before=""
7172         local fid_after=""
7173
7174         test_mkdir "$dir" || error "cannot create dir $dir"
7175         $LFS setstripe $layout $f_comp ||
7176                 error "cannot setstripe $f_comp with layout $layout"
7177         fid_before=$($LFS getstripe --fid $f_comp)
7178         dd if=/dev/zero of=$f_comp bs=1M count=4
7179
7180         # 1. migrate a comp layout file to a comp layout
7181         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7182         fid_after=$($LFS getstripe --fid $f_comp)
7183         [ "$fid_before" == "$fid_after" ] ||
7184                 error "comp-to-comp migrate: $fid_before != $fid_after"
7185
7186         # 2. migrate a comp layout file to a plain layout
7187         $LFS migrate -c2 $f_comp ||
7188                 error "cannot migrate $f_comp by lfs migrate"
7189         fid_after=$($LFS getstripe --fid $f_comp)
7190         [ "$fid_before" == "$fid_after" ] ||
7191                 error "comp-to-plain migrate: $fid_before != $fid_after"
7192
7193         # 3. migrate a plain layout file to a comp layout
7194         $LFS migrate $layout $f_comp ||
7195                 error "cannot migrate $f_comp by lfs migrate"
7196         fid_after=$($LFS getstripe --fid $f_comp)
7197         [ "$fid_before" == "$fid_after" ] ||
7198                 error "plain-to-comp migrate: $fid_before != $fid_after"
7199 }
7200 run_test 56xf "FID is not lost during migration of a composite layout file"
7201
7202 test_56y() {
7203         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7204                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7205
7206         local res=""
7207         local dir=$DIR/$tdir
7208         local f1=$dir/file1
7209         local f2=$dir/file2
7210
7211         test_mkdir -p $dir || error "creating dir $dir"
7212         touch $f1 || error "creating std file $f1"
7213         $MULTIOP $f2 H2c || error "creating released file $f2"
7214
7215         # a directory can be raid0, so ask only for files
7216         res=$($LFS find $dir -L raid0 -type f | wc -l)
7217         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7218
7219         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7220         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7221
7222         # only files can be released, so no need to force file search
7223         res=$($LFS find $dir -L released)
7224         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7225
7226         res=$($LFS find $dir -type f \! -L released)
7227         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7228 }
7229 run_test 56y "lfs find -L raid0|released"
7230
7231 test_56z() { # LU-4824
7232         # This checks to make sure 'lfs find' continues after errors
7233         # There are two classes of errors that should be caught:
7234         # - If multiple paths are provided, all should be searched even if one
7235         #   errors out
7236         # - If errors are encountered during the search, it should not terminate
7237         #   early
7238         local dir=$DIR/$tdir
7239         local i
7240
7241         test_mkdir $dir
7242         for i in d{0..9}; do
7243                 test_mkdir $dir/$i
7244                 touch $dir/$i/$tfile
7245         done
7246         $LFS find $DIR/non_existent_dir $dir &&
7247                 error "$LFS find did not return an error"
7248         # Make a directory unsearchable. This should NOT be the last entry in
7249         # directory order.  Arbitrarily pick the 6th entry
7250         chmod 700 $($LFS find $dir -type d | sed '6!d')
7251
7252         $RUNAS $LFS find $DIR/non_existent $dir
7253         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7254
7255         # The user should be able to see 10 directories and 9 files
7256         (( count == 19 )) ||
7257                 error "$LFS find found $count != 19 entries after error"
7258 }
7259 run_test 56z "lfs find should continue after an error"
7260
7261 test_56aa() { # LU-5937
7262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7263
7264         local dir=$DIR/$tdir
7265
7266         mkdir $dir
7267         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7268
7269         createmany -o $dir/striped_dir/${tfile}- 1024
7270         local dirs=$($LFS find --size +8k $dir/)
7271
7272         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7273 }
7274 run_test 56aa "lfs find --size under striped dir"
7275
7276 test_56ab() { # LU-10705
7277         test_mkdir $DIR/$tdir
7278         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7279         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7280         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7281         # Flush writes to ensure valid blocks.  Need to be more thorough for
7282         # ZFS, since blocks are not allocated/returned to client immediately.
7283         sync_all_data
7284         wait_zfs_commit ost1 2
7285         cancel_lru_locks osc
7286         ls -ls $DIR/$tdir
7287
7288         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7289
7290         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7291
7292         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7293         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7294
7295         rm -f $DIR/$tdir/$tfile.[123]
7296 }
7297 run_test 56ab "lfs find --blocks"
7298
7299 test_56ba() {
7300         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7301                 skip "Need MDS version at least 2.10.50"
7302
7303         # Create composite files with one component
7304         local dir=$DIR/$tdir
7305
7306         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7307         # Create composite files with three components
7308         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7309         # Create non-composite files
7310         createmany -o $dir/${tfile}- 10
7311
7312         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7313
7314         [[ $nfiles == 10 ]] ||
7315                 error "lfs find -E 1M found $nfiles != 10 files"
7316
7317         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7318         [[ $nfiles == 25 ]] ||
7319                 error "lfs find ! -E 1M found $nfiles != 25 files"
7320
7321         # All files have a component that starts at 0
7322         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7323         [[ $nfiles == 35 ]] ||
7324                 error "lfs find --component-start 0 - $nfiles != 35 files"
7325
7326         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7327         [[ $nfiles == 15 ]] ||
7328                 error "lfs find --component-start 2M - $nfiles != 15 files"
7329
7330         # All files created here have a componenet that does not starts at 2M
7331         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7332         [[ $nfiles == 35 ]] ||
7333                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7334
7335         # Find files with a specified number of components
7336         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7337         [[ $nfiles == 15 ]] ||
7338                 error "lfs find --component-count 3 - $nfiles != 15 files"
7339
7340         # Remember non-composite files have a component count of zero
7341         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7342         [[ $nfiles == 10 ]] ||
7343                 error "lfs find --component-count 0 - $nfiles != 10 files"
7344
7345         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7346         [[ $nfiles == 20 ]] ||
7347                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7348
7349         # All files have a flag called "init"
7350         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7351         [[ $nfiles == 35 ]] ||
7352                 error "lfs find --component-flags init - $nfiles != 35 files"
7353
7354         # Multi-component files will have a component not initialized
7355         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7356         [[ $nfiles == 15 ]] ||
7357                 error "lfs find !--component-flags init - $nfiles != 15 files"
7358
7359         rm -rf $dir
7360
7361 }
7362 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7363
7364 test_56ca() {
7365         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7366                 skip "Need MDS version at least 2.10.57"
7367
7368         local td=$DIR/$tdir
7369         local tf=$td/$tfile
7370         local dir
7371         local nfiles
7372         local cmd
7373         local i
7374         local j
7375
7376         # create mirrored directories and mirrored files
7377         mkdir $td || error "mkdir $td failed"
7378         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7379         createmany -o $tf- 10 || error "create $tf- failed"
7380
7381         for i in $(seq 2); do
7382                 dir=$td/dir$i
7383                 mkdir $dir || error "mkdir $dir failed"
7384                 $LFS mirror create -N$((3 + i)) $dir ||
7385                         error "create mirrored dir $dir failed"
7386                 createmany -o $dir/$tfile- 10 ||
7387                         error "create $dir/$tfile- failed"
7388         done
7389
7390         # change the states of some mirrored files
7391         echo foo > $tf-6
7392         for i in $(seq 2); do
7393                 dir=$td/dir$i
7394                 for j in $(seq 4 9); do
7395                         echo foo > $dir/$tfile-$j
7396                 done
7397         done
7398
7399         # find mirrored files with specific mirror count
7400         cmd="$LFS find --mirror-count 3 --type f $td"
7401         nfiles=$($cmd | wc -l)
7402         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7403
7404         cmd="$LFS find ! --mirror-count 3 --type f $td"
7405         nfiles=$($cmd | wc -l)
7406         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7407
7408         cmd="$LFS find --mirror-count +2 --type f $td"
7409         nfiles=$($cmd | wc -l)
7410         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7411
7412         cmd="$LFS find --mirror-count -6 --type f $td"
7413         nfiles=$($cmd | wc -l)
7414         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7415
7416         # find mirrored files with specific file state
7417         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7418         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7419
7420         cmd="$LFS find --mirror-state=ro --type f $td"
7421         nfiles=$($cmd | wc -l)
7422         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7423
7424         cmd="$LFS find ! --mirror-state=ro --type f $td"
7425         nfiles=$($cmd | wc -l)
7426         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7427
7428         cmd="$LFS find --mirror-state=wp --type f $td"
7429         nfiles=$($cmd | wc -l)
7430         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7431
7432         cmd="$LFS find ! --mirror-state=sp --type f $td"
7433         nfiles=$($cmd | wc -l)
7434         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7435 }
7436 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7437
7438 test_57a() {
7439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7440         # note test will not do anything if MDS is not local
7441         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7442                 skip_env "ldiskfs only test"
7443         fi
7444         remote_mds_nodsh && skip "remote MDS with nodsh"
7445
7446         local MNTDEV="osd*.*MDT*.mntdev"
7447         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7448         [ -z "$DEV" ] && error "can't access $MNTDEV"
7449         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7450                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7451                         error "can't access $DEV"
7452                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7453                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7454                 rm $TMP/t57a.dump
7455         done
7456 }
7457 run_test 57a "verify MDS filesystem created with large inodes =="
7458
7459 test_57b() {
7460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7461         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7462                 skip_env "ldiskfs only test"
7463         fi
7464         remote_mds_nodsh && skip "remote MDS with nodsh"
7465
7466         local dir=$DIR/$tdir
7467         local filecount=100
7468         local file1=$dir/f1
7469         local fileN=$dir/f$filecount
7470
7471         rm -rf $dir || error "removing $dir"
7472         test_mkdir -c1 $dir
7473         local mdtidx=$($LFS getstripe -m $dir)
7474         local mdtname=MDT$(printf %04x $mdtidx)
7475         local facet=mds$((mdtidx + 1))
7476
7477         echo "mcreating $filecount files"
7478         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7479
7480         # verify that files do not have EAs yet
7481         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7482                 error "$file1 has an EA"
7483         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7484                 error "$fileN has an EA"
7485
7486         sync
7487         sleep 1
7488         df $dir  #make sure we get new statfs data
7489         local mdsfree=$(do_facet $facet \
7490                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7491         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7492         local file
7493
7494         echo "opening files to create objects/EAs"
7495         for file in $(seq -f $dir/f%g 1 $filecount); do
7496                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7497                         error "opening $file"
7498         done
7499
7500         # verify that files have EAs now
7501         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7502         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7503
7504         sleep 1  #make sure we get new statfs data
7505         df $dir
7506         local mdsfree2=$(do_facet $facet \
7507                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7508         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7509
7510         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7511                 if [ "$mdsfree" != "$mdsfree2" ]; then
7512                         error "MDC before $mdcfree != after $mdcfree2"
7513                 else
7514                         echo "MDC before $mdcfree != after $mdcfree2"
7515                         echo "unable to confirm if MDS has large inodes"
7516                 fi
7517         fi
7518         rm -rf $dir
7519 }
7520 run_test 57b "default LOV EAs are stored inside large inodes ==="
7521
7522 test_58() {
7523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7524         [ -z "$(which wiretest 2>/dev/null)" ] &&
7525                         skip_env "could not find wiretest"
7526
7527         wiretest
7528 }
7529 run_test 58 "verify cross-platform wire constants =============="
7530
7531 test_59() {
7532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7533
7534         echo "touch 130 files"
7535         createmany -o $DIR/f59- 130
7536         echo "rm 130 files"
7537         unlinkmany $DIR/f59- 130
7538         sync
7539         # wait for commitment of removal
7540         wait_delete_completed
7541 }
7542 run_test 59 "verify cancellation of llog records async ========="
7543
7544 TEST60_HEAD="test_60 run $RANDOM"
7545 test_60a() {
7546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7547         remote_mgs_nodsh && skip "remote MGS with nodsh"
7548         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7549                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7550                         skip_env "missing subtest run-llog.sh"
7551
7552         log "$TEST60_HEAD - from kernel mode"
7553         do_facet mgs "$LCTL dk > /dev/null"
7554         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7555         do_facet mgs $LCTL dk > $TMP/$tfile
7556
7557         # LU-6388: test llog_reader
7558         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7559         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7560         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7561                         skip_env "missing llog_reader"
7562         local fstype=$(facet_fstype mgs)
7563         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7564                 skip_env "Only for ldiskfs or zfs type mgs"
7565
7566         local mntpt=$(facet_mntpt mgs)
7567         local mgsdev=$(mgsdevname 1)
7568         local fid_list
7569         local fid
7570         local rec_list
7571         local rec
7572         local rec_type
7573         local obj_file
7574         local path
7575         local seq
7576         local oid
7577         local pass=true
7578
7579         #get fid and record list
7580         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7581                 tail -n 4))
7582         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7583                 tail -n 4))
7584         #remount mgs as ldiskfs or zfs type
7585         stop mgs || error "stop mgs failed"
7586         mount_fstype mgs || error "remount mgs failed"
7587         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7588                 fid=${fid_list[i]}
7589                 rec=${rec_list[i]}
7590                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7591                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7592                 oid=$((16#$oid))
7593
7594                 case $fstype in
7595                         ldiskfs )
7596                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7597                         zfs )
7598                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7599                 esac
7600                 echo "obj_file is $obj_file"
7601                 do_facet mgs $llog_reader $obj_file
7602
7603                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7604                         awk '{ print $3 }' | sed -e "s/^type=//g")
7605                 if [ $rec_type != $rec ]; then
7606                         echo "FAILED test_60a wrong record type $rec_type," \
7607                               "should be $rec"
7608                         pass=false
7609                         break
7610                 fi
7611
7612                 #check obj path if record type is LLOG_LOGID_MAGIC
7613                 if [ "$rec" == "1064553b" ]; then
7614                         path=$(do_facet mgs $llog_reader $obj_file |
7615                                 grep "path=" | awk '{ print $NF }' |
7616                                 sed -e "s/^path=//g")
7617                         if [ $obj_file != $mntpt/$path ]; then
7618                                 echo "FAILED test_60a wrong obj path" \
7619                                       "$montpt/$path, should be $obj_file"
7620                                 pass=false
7621                                 break
7622                         fi
7623                 fi
7624         done
7625         rm -f $TMP/$tfile
7626         #restart mgs before "error", otherwise it will block the next test
7627         stop mgs || error "stop mgs failed"
7628         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7629         $pass || error "test failed, see FAILED test_60a messages for specifics"
7630 }
7631 run_test 60a "llog_test run from kernel module and test llog_reader"
7632
7633 test_60b() { # bug 6411
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635
7636         dmesg > $DIR/$tfile
7637         LLOG_COUNT=$(do_facet mgs dmesg |
7638                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7639                           /llog_[a-z]*.c:[0-9]/ {
7640                                 if (marker)
7641                                         from_marker++
7642                                 from_begin++
7643                           }
7644                           END {
7645                                 if (marker)
7646                                         print from_marker
7647                                 else
7648                                         print from_begin
7649                           }")
7650
7651         [[ $LLOG_COUNT -gt 120 ]] &&
7652                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7653 }
7654 run_test 60b "limit repeated messages from CERROR/CWARN"
7655
7656 test_60c() {
7657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7658
7659         echo "create 5000 files"
7660         createmany -o $DIR/f60c- 5000
7661 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7662         lctl set_param fail_loc=0x80000137
7663         unlinkmany $DIR/f60c- 5000
7664         lctl set_param fail_loc=0
7665 }
7666 run_test 60c "unlink file when mds full"
7667
7668 test_60d() {
7669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7670
7671         SAVEPRINTK=$(lctl get_param -n printk)
7672         # verify "lctl mark" is even working"
7673         MESSAGE="test message ID $RANDOM $$"
7674         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7675         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7676
7677         lctl set_param printk=0 || error "set lnet.printk failed"
7678         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7679         MESSAGE="new test message ID $RANDOM $$"
7680         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7681         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7682         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7683
7684         lctl set_param -n printk="$SAVEPRINTK"
7685 }
7686 run_test 60d "test printk console message masking"
7687
7688 test_60e() {
7689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7690         remote_mds_nodsh && skip "remote MDS with nodsh"
7691
7692         touch $DIR/$tfile
7693 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7694         do_facet mds1 lctl set_param fail_loc=0x15b
7695         rm $DIR/$tfile
7696 }
7697 run_test 60e "no space while new llog is being created"
7698
7699 test_60g() {
7700         local pid
7701         local i
7702
7703         test_mkdir -c $MDSCOUNT $DIR/$tdir
7704
7705         (
7706                 local index=0
7707                 while true; do
7708                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7709                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7710                                 2>/dev/null
7711                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7712                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7713                         index=$((index + 1))
7714                 done
7715         ) &
7716
7717         pid=$!
7718
7719         for i in {0..100}; do
7720                 # define OBD_FAIL_OSD_TXN_START    0x19a
7721                 local index=$((i % MDSCOUNT + 1))
7722
7723                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7724                         > /dev/null
7725                 sleep 0.01
7726         done
7727
7728         kill -9 $pid
7729
7730         for i in $(seq $MDSCOUNT); do
7731                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7732         done
7733
7734         mkdir $DIR/$tdir/new || error "mkdir failed"
7735         rmdir $DIR/$tdir/new || error "rmdir failed"
7736
7737         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7738                 -t namespace
7739         for i in $(seq $MDSCOUNT); do
7740                 wait_update_facet mds$i "$LCTL get_param -n \
7741                         mdd.$(facet_svc mds$i).lfsck_namespace |
7742                         awk '/^status/ { print \\\$2 }'" "completed"
7743         done
7744
7745         ls -R $DIR/$tdir || error "ls failed"
7746         rm -rf $DIR/$tdir || error "rmdir failed"
7747 }
7748 run_test 60g "transaction abort won't cause MDT hung"
7749
7750 test_60h() {
7751         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7752                 skip "Need MDS version at least 2.12.52"
7753         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7754
7755         local f
7756
7757         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7758         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7759         for fail_loc in 0x80000188 0x80000189; do
7760                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7761                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7762                         error "mkdir $dir-$fail_loc failed"
7763                 for i in {0..10}; do
7764                         # create may fail on missing stripe
7765                         echo $i > $DIR/$tdir-$fail_loc/$i
7766                 done
7767                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7768                         error "getdirstripe $tdir-$fail_loc failed"
7769                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7770                         error "migrate $tdir-$fail_loc failed"
7771                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7772                         error "getdirstripe $tdir-$fail_loc failed"
7773                 pushd $DIR/$tdir-$fail_loc
7774                 for f in *; do
7775                         echo $f | cmp $f - || error "$f data mismatch"
7776                 done
7777                 popd
7778                 rm -rf $DIR/$tdir-$fail_loc
7779         done
7780 }
7781 run_test 60h "striped directory with missing stripes can be accessed"
7782
7783 test_61a() {
7784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7785
7786         f="$DIR/f61"
7787         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7788         cancel_lru_locks osc
7789         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7790         sync
7791 }
7792 run_test 61a "mmap() writes don't make sync hang ================"
7793
7794 test_61b() {
7795         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7796 }
7797 run_test 61b "mmap() of unstriped file is successful"
7798
7799 # bug 2330 - insufficient obd_match error checking causes LBUG
7800 test_62() {
7801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7802
7803         f="$DIR/f62"
7804         echo foo > $f
7805         cancel_lru_locks osc
7806         lctl set_param fail_loc=0x405
7807         cat $f && error "cat succeeded, expect -EIO"
7808         lctl set_param fail_loc=0
7809 }
7810 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7811 # match every page all of the time.
7812 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7813
7814 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7815 # Though this test is irrelevant anymore, it helped to reveal some
7816 # other grant bugs (LU-4482), let's keep it.
7817 test_63a() {   # was test_63
7818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7819
7820         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7821
7822         for i in `seq 10` ; do
7823                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7824                 sleep 5
7825                 kill $!
7826                 sleep 1
7827         done
7828
7829         rm -f $DIR/f63 || true
7830 }
7831 run_test 63a "Verify oig_wait interruption does not crash ======="
7832
7833 # bug 2248 - async write errors didn't return to application on sync
7834 # bug 3677 - async write errors left page locked
7835 test_63b() {
7836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7837
7838         debugsave
7839         lctl set_param debug=-1
7840
7841         # ensure we have a grant to do async writes
7842         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7843         rm $DIR/$tfile
7844
7845         sync    # sync lest earlier test intercept the fail_loc
7846
7847         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7848         lctl set_param fail_loc=0x80000406
7849         $MULTIOP $DIR/$tfile Owy && \
7850                 error "sync didn't return ENOMEM"
7851         sync; sleep 2; sync     # do a real sync this time to flush page
7852         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7853                 error "locked page left in cache after async error" || true
7854         debugrestore
7855 }
7856 run_test 63b "async write errors should be returned to fsync ==="
7857
7858 test_64a () {
7859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7860
7861         lfs df $DIR
7862         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7863 }
7864 run_test 64a "verify filter grant calculations (in kernel) ====="
7865
7866 test_64b () {
7867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7868
7869         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7870 }
7871 run_test 64b "check out-of-space detection on client"
7872
7873 test_64c() {
7874         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7875 }
7876 run_test 64c "verify grant shrink"
7877
7878 import_param() {
7879         local tgt=$1
7880         local param=$2
7881
7882         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7883 }
7884
7885 # this does exactly what osc_request.c:osc_announce_cached() does in
7886 # order to calculate max amount of grants to ask from server
7887 want_grant() {
7888         local tgt=$1
7889
7890         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7891         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7892
7893         ((rpc_in_flight++));
7894         nrpages=$((nrpages * rpc_in_flight))
7895
7896         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7897
7898         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7899
7900         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7901         local undirty=$((nrpages * PAGE_SIZE))
7902
7903         local max_extent_pages
7904         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7905         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7906         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7907         local grant_extent_tax
7908         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7909
7910         undirty=$((undirty + nrextents * grant_extent_tax))
7911
7912         echo $undirty
7913 }
7914
7915 # this is size of unit for grant allocation. It should be equal to
7916 # what tgt_grant.c:tgt_grant_chunk() calculates
7917 grant_chunk() {
7918         local tgt=$1
7919         local max_brw_size
7920         local grant_extent_tax
7921
7922         max_brw_size=$(import_param $tgt max_brw_size)
7923
7924         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7925
7926         echo $(((max_brw_size + grant_extent_tax) * 2))
7927 }
7928
7929 test_64d() {
7930         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7931                 skip "OST < 2.10.55 doesn't limit grants enough"
7932
7933         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7934
7935         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7936                 skip "no grant_param connect flag"
7937
7938         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7939
7940         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7941         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7942
7943
7944         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7945         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7946
7947         $LFS setstripe $DIR/$tfile -i 0 -c 1
7948         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7949         ddpid=$!
7950
7951         while kill -0 $ddpid; do
7952                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7953
7954                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7955                         kill $ddpid
7956                         error "cur_grant $cur_grant > $max_cur_granted"
7957                 fi
7958
7959                 sleep 1
7960         done
7961 }
7962 run_test 64d "check grant limit exceed"
7963
7964 check_grants() {
7965         local tgt=$1
7966         local expected=$2
7967         local msg=$3
7968         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7969
7970         ((cur_grants == expected)) ||
7971                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7972 }
7973
7974 round_up_p2() {
7975         echo $((($1 + $2 - 1) & ~($2 - 1)))
7976 }
7977
7978 test_64e() {
7979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7980         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7981                 skip "Need OSS version at least 2.11.56"
7982
7983         # Remount client to reset grant
7984         remount_client $MOUNT || error "failed to remount client"
7985         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7986
7987         local init_grants=$(import_param $osc_tgt initial_grant)
7988
7989         check_grants $osc_tgt $init_grants "init grants"
7990
7991         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7992         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7993         local gbs=$(import_param $osc_tgt grant_block_size)
7994
7995         # write random number of bytes from max_brw_size / 4 to max_brw_size
7996         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7997         # align for direct io
7998         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7999         # round to grant consumption unit
8000         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8001
8002         local grants=$((wb_round_up + extent_tax))
8003
8004         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8005
8006         # define OBD_FAIL_TGT_NO_GRANT 0x725
8007         # make the server not grant more back
8008         do_facet ost1 $LCTL set_param fail_loc=0x725
8009         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8010
8011         do_facet ost1 $LCTL set_param fail_loc=0
8012
8013         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8014
8015         rm -f $DIR/$tfile || error "rm failed"
8016
8017         # Remount client to reset grant
8018         remount_client $MOUNT || error "failed to remount client"
8019         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8020
8021         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8022
8023         # define OBD_FAIL_TGT_NO_GRANT 0x725
8024         # make the server not grant more back
8025         do_facet ost1 $LCTL set_param fail_loc=0x725
8026         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8027         do_facet ost1 $LCTL set_param fail_loc=0
8028
8029         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8030 }
8031 run_test 64e "check grant consumption (no grant allocation)"
8032
8033 test_64f() {
8034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8035
8036         # Remount client to reset grant
8037         remount_client $MOUNT || error "failed to remount client"
8038         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8039
8040         local init_grants=$(import_param $osc_tgt initial_grant)
8041         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8042         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8043         local gbs=$(import_param $osc_tgt grant_block_size)
8044         local chunk=$(grant_chunk $osc_tgt)
8045
8046         # write random number of bytes from max_brw_size / 4 to max_brw_size
8047         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8048         # align for direct io
8049         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8050         # round to grant consumption unit
8051         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8052
8053         local grants=$((wb_round_up + extent_tax))
8054
8055         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8056         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8057                 error "error writing to $DIR/$tfile"
8058
8059         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8060                 "direct io with grant allocation"
8061
8062         rm -f $DIR/$tfile || error "rm failed"
8063
8064         # Remount client to reset grant
8065         remount_client $MOUNT || error "failed to remount client"
8066         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8067
8068         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8069
8070         local cmd="oO_WRONLY:w${write_bytes}_yc"
8071
8072         $MULTIOP $DIR/$tfile $cmd &
8073         MULTIPID=$!
8074         sleep 1
8075
8076         check_grants $osc_tgt $((init_grants - grants)) \
8077                 "buffered io, not write rpc"
8078
8079         kill -USR1 $MULTIPID
8080         wait
8081
8082         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8083                 "buffered io, one RPC"
8084 }
8085 run_test 64f "check grant consumption (with grant allocation)"
8086
8087 # bug 1414 - set/get directories' stripe info
8088 test_65a() {
8089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8090
8091         test_mkdir $DIR/$tdir
8092         touch $DIR/$tdir/f1
8093         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8094 }
8095 run_test 65a "directory with no stripe info"
8096
8097 test_65b() {
8098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8099
8100         test_mkdir $DIR/$tdir
8101         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8102
8103         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8104                                                 error "setstripe"
8105         touch $DIR/$tdir/f2
8106         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8107 }
8108 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8109
8110 test_65c() {
8111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8112         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8113
8114         test_mkdir $DIR/$tdir
8115         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8116
8117         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8118                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8119         touch $DIR/$tdir/f3
8120         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8121 }
8122 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8123
8124 test_65d() {
8125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8126
8127         test_mkdir $DIR/$tdir
8128         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8129         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8130
8131         if [[ $STRIPECOUNT -le 0 ]]; then
8132                 sc=1
8133         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8134                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8135                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8136         else
8137                 sc=$(($STRIPECOUNT - 1))
8138         fi
8139         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8140         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8141         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8142                 error "lverify failed"
8143 }
8144 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8145
8146 test_65e() {
8147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8148
8149         test_mkdir $DIR/$tdir
8150
8151         $LFS setstripe $DIR/$tdir || error "setstripe"
8152         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8153                                         error "no stripe info failed"
8154         touch $DIR/$tdir/f6
8155         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8156 }
8157 run_test 65e "directory setstripe defaults"
8158
8159 test_65f() {
8160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8161
8162         test_mkdir $DIR/${tdir}f
8163         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8164                 error "setstripe succeeded" || true
8165 }
8166 run_test 65f "dir setstripe permission (should return error) ==="
8167
8168 test_65g() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         test_mkdir $DIR/$tdir
8172         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8173
8174         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8175                 error "setstripe -S failed"
8176         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8177         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8178                 error "delete default stripe failed"
8179 }
8180 run_test 65g "directory setstripe -d"
8181
8182 test_65h() {
8183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8184
8185         test_mkdir $DIR/$tdir
8186         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8187
8188         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8189                 error "setstripe -S failed"
8190         test_mkdir $DIR/$tdir/dd1
8191         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8192                 error "stripe info inherit failed"
8193 }
8194 run_test 65h "directory stripe info inherit ===================="
8195
8196 test_65i() {
8197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8198
8199         save_layout_restore_at_exit $MOUNT
8200
8201         # bug6367: set non-default striping on root directory
8202         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8203
8204         # bug12836: getstripe on -1 default directory striping
8205         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8206
8207         # bug12836: getstripe -v on -1 default directory striping
8208         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8209
8210         # bug12836: new find on -1 default directory striping
8211         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8212 }
8213 run_test 65i "various tests to set root directory striping"
8214
8215 test_65j() { # bug6367
8216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8217
8218         sync; sleep 1
8219
8220         # if we aren't already remounting for each test, do so for this test
8221         if [ "$I_MOUNTED" = "yes" ]; then
8222                 cleanup || error "failed to unmount"
8223                 setup
8224         fi
8225
8226         save_layout_restore_at_exit $MOUNT
8227
8228         $LFS setstripe -d $MOUNT || error "setstripe failed"
8229 }
8230 run_test 65j "set default striping on root directory (bug 6367)="
8231
8232 cleanup_65k() {
8233         rm -rf $DIR/$tdir
8234         wait_delete_completed
8235         do_facet $SINGLEMDS "lctl set_param -n \
8236                 osp.$ost*MDT0000.max_create_count=$max_count"
8237         do_facet $SINGLEMDS "lctl set_param -n \
8238                 osp.$ost*MDT0000.create_count=$count"
8239         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8240         echo $INACTIVE_OSC "is Activate"
8241
8242         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8243 }
8244
8245 test_65k() { # bug11679
8246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8247         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8248         remote_mds_nodsh && skip "remote MDS with nodsh"
8249
8250         local disable_precreate=true
8251         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8252                 disable_precreate=false
8253
8254         echo "Check OST status: "
8255         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8256                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8257
8258         for OSC in $MDS_OSCS; do
8259                 echo $OSC "is active"
8260                 do_facet $SINGLEMDS lctl --device %$OSC activate
8261         done
8262
8263         for INACTIVE_OSC in $MDS_OSCS; do
8264                 local ost=$(osc_to_ost $INACTIVE_OSC)
8265                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8266                                lov.*md*.target_obd |
8267                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8268
8269                 mkdir -p $DIR/$tdir
8270                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8271                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8272
8273                 echo "Deactivate: " $INACTIVE_OSC
8274                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8275
8276                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8277                               osp.$ost*MDT0000.create_count")
8278                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8279                                   osp.$ost*MDT0000.max_create_count")
8280                 $disable_precreate &&
8281                         do_facet $SINGLEMDS "lctl set_param -n \
8282                                 osp.$ost*MDT0000.max_create_count=0"
8283
8284                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8285                         [ -f $DIR/$tdir/$idx ] && continue
8286                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8287                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8288                                 { cleanup_65k;
8289                                   error "setstripe $idx should succeed"; }
8290                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8291                 done
8292                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8293                 rmdir $DIR/$tdir
8294
8295                 do_facet $SINGLEMDS "lctl set_param -n \
8296                         osp.$ost*MDT0000.max_create_count=$max_count"
8297                 do_facet $SINGLEMDS "lctl set_param -n \
8298                         osp.$ost*MDT0000.create_count=$count"
8299                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8300                 echo $INACTIVE_OSC "is Activate"
8301
8302                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8303         done
8304 }
8305 run_test 65k "validate manual striping works properly with deactivated OSCs"
8306
8307 test_65l() { # bug 12836
8308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8309
8310         test_mkdir -p $DIR/$tdir/test_dir
8311         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8312         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8313 }
8314 run_test 65l "lfs find on -1 stripe dir ========================"
8315
8316 test_65m() {
8317         local layout=$(save_layout $MOUNT)
8318         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8319                 restore_layout $MOUNT $layout
8320                 error "setstripe should fail by non-root users"
8321         }
8322         true
8323 }
8324 run_test 65m "normal user can't set filesystem default stripe"
8325
8326 test_65n() {
8327         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8328         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8329                 skip "Need MDS version at least 2.12.50"
8330         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8331
8332         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8333         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8334         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8335
8336         local root_layout=$(save_layout $MOUNT)
8337         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8338
8339         # new subdirectory under root directory should not inherit
8340         # the default layout from root
8341         local dir1=$MOUNT/$tdir-1
8342         mkdir $dir1 || error "mkdir $dir1 failed"
8343         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8344                 error "$dir1 shouldn't have LOV EA"
8345
8346         # delete the default layout on root directory
8347         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8348
8349         local dir2=$MOUNT/$tdir-2
8350         mkdir $dir2 || error "mkdir $dir2 failed"
8351         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8352                 error "$dir2 shouldn't have LOV EA"
8353
8354         # set a new striping pattern on root directory
8355         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8356         local new_def_stripe_size=$((def_stripe_size * 2))
8357         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8358                 error "set stripe size on $MOUNT failed"
8359
8360         # new file created in $dir2 should inherit the new stripe size from
8361         # the filesystem default
8362         local file2=$dir2/$tfile-2
8363         touch $file2 || error "touch $file2 failed"
8364
8365         local file2_stripe_size=$($LFS getstripe -S $file2)
8366         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8367                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8368
8369         local dir3=$MOUNT/$tdir-3
8370         mkdir $dir3 || error "mkdir $dir3 failed"
8371         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8372         # the root layout, which is the actual default layout that will be used
8373         # when new files are created in $dir3.
8374         local dir3_layout=$(get_layout_param $dir3)
8375         local root_dir_layout=$(get_layout_param $MOUNT)
8376         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8377                 error "$dir3 should show the default layout from $MOUNT"
8378
8379         # set OST pool on root directory
8380         local pool=$TESTNAME
8381         pool_add $pool || error "add $pool failed"
8382         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8383                 error "add targets to $pool failed"
8384
8385         $LFS setstripe -p $pool $MOUNT ||
8386                 error "set OST pool on $MOUNT failed"
8387
8388         # new file created in $dir3 should inherit the pool from
8389         # the filesystem default
8390         local file3=$dir3/$tfile-3
8391         touch $file3 || error "touch $file3 failed"
8392
8393         local file3_pool=$($LFS getstripe -p $file3)
8394         [[ "$file3_pool" = "$pool" ]] ||
8395                 error "$file3 didn't inherit OST pool $pool"
8396
8397         local dir4=$MOUNT/$tdir-4
8398         mkdir $dir4 || error "mkdir $dir4 failed"
8399         local dir4_layout=$(get_layout_param $dir4)
8400         root_dir_layout=$(get_layout_param $MOUNT)
8401         echo "$LFS getstripe -d $dir4"
8402         $LFS getstripe -d $dir4
8403         echo "$LFS getstripe -d $MOUNT"
8404         $LFS getstripe -d $MOUNT
8405         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8406                 error "$dir4 should show the default layout from $MOUNT"
8407
8408         # new file created in $dir4 should inherit the pool from
8409         # the filesystem default
8410         local file4=$dir4/$tfile-4
8411         touch $file4 || error "touch $file4 failed"
8412
8413         local file4_pool=$($LFS getstripe -p $file4)
8414         [[ "$file4_pool" = "$pool" ]] ||
8415                 error "$file4 didn't inherit OST pool $pool"
8416
8417         # new subdirectory under non-root directory should inherit
8418         # the default layout from its parent directory
8419         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8420                 error "set directory layout on $dir4 failed"
8421
8422         local dir5=$dir4/$tdir-5
8423         mkdir $dir5 || error "mkdir $dir5 failed"
8424
8425         dir4_layout=$(get_layout_param $dir4)
8426         local dir5_layout=$(get_layout_param $dir5)
8427         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8428                 error "$dir5 should inherit the default layout from $dir4"
8429
8430         # though subdir under ROOT doesn't inherit default layout, but
8431         # its sub dir/file should be created with default layout.
8432         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8433         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8434                 skip "Need MDS version at least 2.12.59"
8435
8436         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8437         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8438         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8439
8440         if [ $default_lmv_hash == "none" ]; then
8441                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8442         else
8443                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8444                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8445         fi
8446
8447         $LFS setdirstripe -D -c 2 $MOUNT ||
8448                 error "setdirstripe -D -c 2 failed"
8449         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8450         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8451         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8452 }
8453 run_test 65n "don't inherit default layout from root for new subdirectories"
8454
8455 # bug 2543 - update blocks count on client
8456 test_66() {
8457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8458
8459         COUNT=${COUNT:-8}
8460         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8461         sync; sync_all_data; sync; sync_all_data
8462         cancel_lru_locks osc
8463         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8464         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8465 }
8466 run_test 66 "update inode blocks count on client ==============="
8467
8468 meminfo() {
8469         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8470 }
8471
8472 swap_used() {
8473         swapon -s | awk '($1 == "'$1'") { print $4 }'
8474 }
8475
8476 # bug5265, obdfilter oa2dentry return -ENOENT
8477 # #define OBD_FAIL_SRV_ENOENT 0x217
8478 test_69() {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480         remote_ost_nodsh && skip "remote OST with nodsh"
8481
8482         f="$DIR/$tfile"
8483         $LFS setstripe -c 1 -i 0 $f
8484
8485         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8486
8487         do_facet ost1 lctl set_param fail_loc=0x217
8488         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8489         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8490
8491         do_facet ost1 lctl set_param fail_loc=0
8492         $DIRECTIO write $f 0 2 || error "write error"
8493
8494         cancel_lru_locks osc
8495         $DIRECTIO read $f 0 1 || error "read error"
8496
8497         do_facet ost1 lctl set_param fail_loc=0x217
8498         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8499
8500         do_facet ost1 lctl set_param fail_loc=0
8501         rm -f $f
8502 }
8503 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8504
8505 test_71() {
8506         test_mkdir $DIR/$tdir
8507         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8508         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8509 }
8510 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8511
8512 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514         [ "$RUNAS_ID" = "$UID" ] &&
8515                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8516         # Check that testing environment is properly set up. Skip if not
8517         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8518                 skip_env "User $RUNAS_ID does not exist - skipping"
8519
8520         touch $DIR/$tfile
8521         chmod 777 $DIR/$tfile
8522         chmod ug+s $DIR/$tfile
8523         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8524                 error "$RUNAS dd $DIR/$tfile failed"
8525         # See if we are still setuid/sgid
8526         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8527                 error "S/gid is not dropped on write"
8528         # Now test that MDS is updated too
8529         cancel_lru_locks mdc
8530         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8531                 error "S/gid is not dropped on MDS"
8532         rm -f $DIR/$tfile
8533 }
8534 run_test 72a "Test that remove suid works properly (bug5695) ===="
8535
8536 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8537         local perm
8538
8539         [ "$RUNAS_ID" = "$UID" ] &&
8540                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8541         [ "$RUNAS_ID" -eq 0 ] &&
8542                 skip_env "RUNAS_ID = 0 -- skipping"
8543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8544         # Check that testing environment is properly set up. Skip if not
8545         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8546                 skip_env "User $RUNAS_ID does not exist - skipping"
8547
8548         touch $DIR/${tfile}-f{g,u}
8549         test_mkdir $DIR/${tfile}-dg
8550         test_mkdir $DIR/${tfile}-du
8551         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8552         chmod g+s $DIR/${tfile}-{f,d}g
8553         chmod u+s $DIR/${tfile}-{f,d}u
8554         for perm in 777 2777 4777; do
8555                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8556                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8557                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8558                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8559         done
8560         true
8561 }
8562 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8563
8564 # bug 3462 - multiple simultaneous MDC requests
8565 test_73() {
8566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8567
8568         test_mkdir $DIR/d73-1
8569         test_mkdir $DIR/d73-2
8570         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8571         pid1=$!
8572
8573         lctl set_param fail_loc=0x80000129
8574         $MULTIOP $DIR/d73-1/f73-2 Oc &
8575         sleep 1
8576         lctl set_param fail_loc=0
8577
8578         $MULTIOP $DIR/d73-2/f73-3 Oc &
8579         pid3=$!
8580
8581         kill -USR1 $pid1
8582         wait $pid1 || return 1
8583
8584         sleep 25
8585
8586         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8587         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8588         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8589
8590         rm -rf $DIR/d73-*
8591 }
8592 run_test 73 "multiple MDC requests (should not deadlock)"
8593
8594 test_74a() { # bug 6149, 6184
8595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8596
8597         touch $DIR/f74a
8598         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8599         #
8600         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8601         # will spin in a tight reconnection loop
8602         $LCTL set_param fail_loc=0x8000030e
8603         # get any lock that won't be difficult - lookup works.
8604         ls $DIR/f74a
8605         $LCTL set_param fail_loc=0
8606         rm -f $DIR/f74a
8607         true
8608 }
8609 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8610
8611 test_74b() { # bug 13310
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613
8614         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8615         #
8616         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8617         # will spin in a tight reconnection loop
8618         $LCTL set_param fail_loc=0x8000030e
8619         # get a "difficult" lock
8620         touch $DIR/f74b
8621         $LCTL set_param fail_loc=0
8622         rm -f $DIR/f74b
8623         true
8624 }
8625 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8626
8627 test_74c() {
8628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8629
8630         #define OBD_FAIL_LDLM_NEW_LOCK
8631         $LCTL set_param fail_loc=0x319
8632         touch $DIR/$tfile && error "touch successful"
8633         $LCTL set_param fail_loc=0
8634         true
8635 }
8636 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8637
8638 slab_lic=/sys/kernel/slab/lustre_inode_cache
8639 num_objects() {
8640         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8641         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8642                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8643 }
8644
8645 test_76() { # Now for b=20433, added originally in b=1443
8646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8647
8648         cancel_lru_locks osc
8649         # there may be some slab objects cached per core
8650         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8651         local before=$(num_objects)
8652         local count=$((512 * cpus))
8653         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8654         local margin=$((count / 10))
8655         if [[ -f $slab_lic/aliases ]]; then
8656                 local aliases=$(cat $slab_lic/aliases)
8657                 (( aliases > 0 )) && margin=$((margin * aliases))
8658         fi
8659
8660         echo "before slab objects: $before"
8661         for i in $(seq $count); do
8662                 touch $DIR/$tfile
8663                 rm -f $DIR/$tfile
8664         done
8665         cancel_lru_locks osc
8666         local after=$(num_objects)
8667         echo "created: $count, after slab objects: $after"
8668         # shared slab counts are not very accurate, allow significant margin
8669         # the main goal is that the cache growth is not permanently > $count
8670         while (( after > before + margin )); do
8671                 sleep 1
8672                 after=$(num_objects)
8673                 wait=$((wait + 1))
8674                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8675                 if (( wait > 60 )); then
8676                         error "inode slab grew from $before+$margin to $after"
8677                 fi
8678         done
8679 }
8680 run_test 76 "confirm clients recycle inodes properly ===="
8681
8682
8683 export ORIG_CSUM=""
8684 set_checksums()
8685 {
8686         # Note: in sptlrpc modes which enable its own bulk checksum, the
8687         # original crc32_le bulk checksum will be automatically disabled,
8688         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8689         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8690         # In this case set_checksums() will not be no-op, because sptlrpc
8691         # bulk checksum will be enabled all through the test.
8692
8693         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8694         lctl set_param -n osc.*.checksums $1
8695         return 0
8696 }
8697
8698 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8699                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8700 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8701                              tr -d [] | head -n1)}
8702 set_checksum_type()
8703 {
8704         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8705         rc=$?
8706         log "set checksum type to $1, rc = $rc"
8707         return $rc
8708 }
8709
8710 get_osc_checksum_type()
8711 {
8712         # arugment 1: OST name, like OST0000
8713         ost=$1
8714         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8715                         sed 's/.*\[\(.*\)\].*/\1/g')
8716         rc=$?
8717         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8718         echo $checksum_type
8719 }
8720
8721 F77_TMP=$TMP/f77-temp
8722 F77SZ=8
8723 setup_f77() {
8724         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8725                 error "error writing to $F77_TMP"
8726 }
8727
8728 test_77a() { # bug 10889
8729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8730         $GSS && skip_env "could not run with gss"
8731
8732         [ ! -f $F77_TMP ] && setup_f77
8733         set_checksums 1
8734         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8735         set_checksums 0
8736         rm -f $DIR/$tfile
8737 }
8738 run_test 77a "normal checksum read/write operation"
8739
8740 test_77b() { # bug 10889
8741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8742         $GSS && skip_env "could not run with gss"
8743
8744         [ ! -f $F77_TMP ] && setup_f77
8745         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8746         $LCTL set_param fail_loc=0x80000409
8747         set_checksums 1
8748
8749         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8750                 error "dd error: $?"
8751         $LCTL set_param fail_loc=0
8752
8753         for algo in $CKSUM_TYPES; do
8754                 cancel_lru_locks osc
8755                 set_checksum_type $algo
8756                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8757                 $LCTL set_param fail_loc=0x80000408
8758                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8759                 $LCTL set_param fail_loc=0
8760         done
8761         set_checksums 0
8762         set_checksum_type $ORIG_CSUM_TYPE
8763         rm -f $DIR/$tfile
8764 }
8765 run_test 77b "checksum error on client write, read"
8766
8767 cleanup_77c() {
8768         trap 0
8769         set_checksums 0
8770         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8771         $check_ost &&
8772                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8773         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8774         $check_ost && [ -n "$ost_file_prefix" ] &&
8775                 do_facet ost1 rm -f ${ost_file_prefix}\*
8776 }
8777
8778 test_77c() {
8779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8780         $GSS && skip_env "could not run with gss"
8781         remote_ost_nodsh && skip "remote OST with nodsh"
8782
8783         local bad1
8784         local osc_file_prefix
8785         local osc_file
8786         local check_ost=false
8787         local ost_file_prefix
8788         local ost_file
8789         local orig_cksum
8790         local dump_cksum
8791         local fid
8792
8793         # ensure corruption will occur on first OSS/OST
8794         $LFS setstripe -i 0 $DIR/$tfile
8795
8796         [ ! -f $F77_TMP ] && setup_f77
8797         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8798                 error "dd write error: $?"
8799         fid=$($LFS path2fid $DIR/$tfile)
8800
8801         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8802         then
8803                 check_ost=true
8804                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8805                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8806         else
8807                 echo "OSS do not support bulk pages dump upon error"
8808         fi
8809
8810         osc_file_prefix=$($LCTL get_param -n debug_path)
8811         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8812
8813         trap cleanup_77c EXIT
8814
8815         set_checksums 1
8816         # enable bulk pages dump upon error on Client
8817         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8818         # enable bulk pages dump upon error on OSS
8819         $check_ost &&
8820                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8821
8822         # flush Client cache to allow next read to reach OSS
8823         cancel_lru_locks osc
8824
8825         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8826         $LCTL set_param fail_loc=0x80000408
8827         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8828         $LCTL set_param fail_loc=0
8829
8830         rm -f $DIR/$tfile
8831
8832         # check cksum dump on Client
8833         osc_file=$(ls ${osc_file_prefix}*)
8834         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8835         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8836         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8837         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8838         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8839                      cksum)
8840         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8841         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8842                 error "dump content does not match on Client"
8843
8844         $check_ost || skip "No need to check cksum dump on OSS"
8845
8846         # check cksum dump on OSS
8847         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8848         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8849         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8850         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8851         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8852                 error "dump content does not match on OSS"
8853
8854         cleanup_77c
8855 }
8856 run_test 77c "checksum error on client read with debug"
8857
8858 test_77d() { # bug 10889
8859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8860         $GSS && skip_env "could not run with gss"
8861
8862         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8863         $LCTL set_param fail_loc=0x80000409
8864         set_checksums 1
8865         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8866                 error "direct write: rc=$?"
8867         $LCTL set_param fail_loc=0
8868         set_checksums 0
8869
8870         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8871         $LCTL set_param fail_loc=0x80000408
8872         set_checksums 1
8873         cancel_lru_locks osc
8874         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8875                 error "direct read: rc=$?"
8876         $LCTL set_param fail_loc=0
8877         set_checksums 0
8878 }
8879 run_test 77d "checksum error on OST direct write, read"
8880
8881 test_77f() { # bug 10889
8882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8883         $GSS && skip_env "could not run with gss"
8884
8885         set_checksums 1
8886         for algo in $CKSUM_TYPES; do
8887                 cancel_lru_locks osc
8888                 set_checksum_type $algo
8889                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8890                 $LCTL set_param fail_loc=0x409
8891                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8892                         error "direct write succeeded"
8893                 $LCTL set_param fail_loc=0
8894         done
8895         set_checksum_type $ORIG_CSUM_TYPE
8896         set_checksums 0
8897 }
8898 run_test 77f "repeat checksum error on write (expect error)"
8899
8900 test_77g() { # bug 10889
8901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8902         $GSS && skip_env "could not run with gss"
8903         remote_ost_nodsh && skip "remote OST with nodsh"
8904
8905         [ ! -f $F77_TMP ] && setup_f77
8906
8907         local file=$DIR/$tfile
8908         stack_trap "rm -f $file" EXIT
8909
8910         $LFS setstripe -c 1 -i 0 $file
8911         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8912         do_facet ost1 lctl set_param fail_loc=0x8000021a
8913         set_checksums 1
8914         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8915                 error "write error: rc=$?"
8916         do_facet ost1 lctl set_param fail_loc=0
8917         set_checksums 0
8918
8919         cancel_lru_locks osc
8920         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8921         do_facet ost1 lctl set_param fail_loc=0x8000021b
8922         set_checksums 1
8923         cmp $F77_TMP $file || error "file compare failed"
8924         do_facet ost1 lctl set_param fail_loc=0
8925         set_checksums 0
8926 }
8927 run_test 77g "checksum error on OST write, read"
8928
8929 test_77k() { # LU-10906
8930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8931         $GSS && skip_env "could not run with gss"
8932
8933         local cksum_param="osc.$FSNAME*.checksums"
8934         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8935         local checksum
8936         local i
8937
8938         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8939         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8940         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8941
8942         for i in 0 1; do
8943                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8944                         error "failed to set checksum=$i on MGS"
8945                 wait_update $HOSTNAME "$get_checksum" $i
8946                 #remount
8947                 echo "remount client, checksum should be $i"
8948                 remount_client $MOUNT || error "failed to remount client"
8949                 checksum=$(eval $get_checksum)
8950                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8951         done
8952         # remove persistent param to avoid races with checksum mountopt below
8953         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8954                 error "failed to delete checksum on MGS"
8955
8956         for opt in "checksum" "nochecksum"; do
8957                 #remount with mount option
8958                 echo "remount client with option $opt, checksum should be $i"
8959                 umount_client $MOUNT || error "failed to umount client"
8960                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8961                         error "failed to mount client with option '$opt'"
8962                 checksum=$(eval $get_checksum)
8963                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8964                 i=$((i - 1))
8965         done
8966
8967         remount_client $MOUNT || error "failed to remount client"
8968 }
8969 run_test 77k "enable/disable checksum correctly"
8970
8971 test_77l() {
8972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8973         $GSS && skip_env "could not run with gss"
8974
8975         set_checksums 1
8976         stack_trap "set_checksums $ORIG_CSUM" EXIT
8977         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8978
8979         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8980
8981         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8982         for algo in $CKSUM_TYPES; do
8983                 set_checksum_type $algo || error "fail to set checksum type $algo"
8984                 osc_algo=$(get_osc_checksum_type OST0000)
8985                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8986
8987                 # no locks, no reqs to let the connection idle
8988                 cancel_lru_locks osc
8989                 lru_resize_disable osc
8990                 wait_osc_import_state client ost1 IDLE
8991
8992                 # ensure ost1 is connected
8993                 stat $DIR/$tfile >/dev/null || error "can't stat"
8994                 wait_osc_import_state client ost1 FULL
8995
8996                 osc_algo=$(get_osc_checksum_type OST0000)
8997                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8998         done
8999         return 0
9000 }
9001 run_test 77l "preferred checksum type is remembered after reconnected"
9002
9003 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9004 rm -f $F77_TMP
9005 unset F77_TMP
9006
9007 cleanup_test_78() {
9008         trap 0
9009         rm -f $DIR/$tfile
9010 }
9011
9012 test_78() { # bug 10901
9013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9014         remote_ost || skip_env "local OST"
9015
9016         NSEQ=5
9017         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9018         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9019         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9020         echo "MemTotal: $MEMTOTAL"
9021
9022         # reserve 256MB of memory for the kernel and other running processes,
9023         # and then take 1/2 of the remaining memory for the read/write buffers.
9024         if [ $MEMTOTAL -gt 512 ] ;then
9025                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9026         else
9027                 # for those poor memory-starved high-end clusters...
9028                 MEMTOTAL=$((MEMTOTAL / 2))
9029         fi
9030         echo "Mem to use for directio: $MEMTOTAL"
9031
9032         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9033         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9034         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9035         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9036                 head -n1)
9037         echo "Smallest OST: $SMALLESTOST"
9038         [[ $SMALLESTOST -lt 10240 ]] &&
9039                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9040
9041         trap cleanup_test_78 EXIT
9042
9043         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9044                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9045
9046         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9047         echo "File size: $F78SIZE"
9048         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9049         for i in $(seq 1 $NSEQ); do
9050                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9051                 echo directIO rdwr round $i of $NSEQ
9052                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9053         done
9054
9055         cleanup_test_78
9056 }
9057 run_test 78 "handle large O_DIRECT writes correctly ============"
9058
9059 test_79() { # bug 12743
9060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9061
9062         wait_delete_completed
9063
9064         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9065         BKFREE=$(calc_osc_kbytes kbytesfree)
9066         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9067
9068         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9069         DFTOTAL=`echo $STRING | cut -d, -f1`
9070         DFUSED=`echo $STRING  | cut -d, -f2`
9071         DFAVAIL=`echo $STRING | cut -d, -f3`
9072         DFFREE=$(($DFTOTAL - $DFUSED))
9073
9074         ALLOWANCE=$((64 * $OSTCOUNT))
9075
9076         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9077            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9078                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9079         fi
9080         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9081            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9082                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9083         fi
9084         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9085            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9086                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9087         fi
9088 }
9089 run_test 79 "df report consistency check ======================="
9090
9091 test_80() { # bug 10718
9092         remote_ost_nodsh && skip "remote OST with nodsh"
9093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9094
9095         # relax strong synchronous semantics for slow backends like ZFS
9096         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9097                 local soc="obdfilter.*.sync_lock_cancel"
9098                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9099
9100                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9101                 if [ -z "$save" ]; then
9102                         soc="obdfilter.*.sync_on_lock_cancel"
9103                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9104                 fi
9105
9106                 if [ "$save" != "never" ]; then
9107                         local hosts=$(comma_list $(osts_nodes))
9108
9109                         do_nodes $hosts $LCTL set_param $soc=never
9110                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9111                 fi
9112         fi
9113
9114         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9115         sync; sleep 1; sync
9116         local before=$(date +%s)
9117         cancel_lru_locks osc
9118         local after=$(date +%s)
9119         local diff=$((after - before))
9120         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9121
9122         rm -f $DIR/$tfile
9123 }
9124 run_test 80 "Page eviction is equally fast at high offsets too"
9125
9126 test_81a() { # LU-456
9127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9128         remote_ost_nodsh && skip "remote OST with nodsh"
9129
9130         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9131         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9132         do_facet ost1 lctl set_param fail_loc=0x80000228
9133
9134         # write should trigger a retry and success
9135         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9136         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9137         RC=$?
9138         if [ $RC -ne 0 ] ; then
9139                 error "write should success, but failed for $RC"
9140         fi
9141 }
9142 run_test 81a "OST should retry write when get -ENOSPC ==============="
9143
9144 test_81b() { # LU-456
9145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9146         remote_ost_nodsh && skip "remote OST with nodsh"
9147
9148         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9149         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9150         do_facet ost1 lctl set_param fail_loc=0x228
9151
9152         # write should retry several times and return -ENOSPC finally
9153         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9154         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9155         RC=$?
9156         ENOSPC=28
9157         if [ $RC -ne $ENOSPC ] ; then
9158                 error "dd should fail for -ENOSPC, but succeed."
9159         fi
9160 }
9161 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9162
9163 test_99() {
9164         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9165
9166         test_mkdir $DIR/$tdir.cvsroot
9167         chown $RUNAS_ID $DIR/$tdir.cvsroot
9168
9169         cd $TMP
9170         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9171
9172         cd /etc/init.d
9173         # some versions of cvs import exit(1) when asked to import links or
9174         # files they can't read.  ignore those files.
9175         local toignore=$(find . -type l -printf '-I %f\n' -o \
9176                          ! -perm /4 -printf '-I %f\n')
9177         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9178                 $tdir.reposname vtag rtag
9179
9180         cd $DIR
9181         test_mkdir $DIR/$tdir.reposname
9182         chown $RUNAS_ID $DIR/$tdir.reposname
9183         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9184
9185         cd $DIR/$tdir.reposname
9186         $RUNAS touch foo99
9187         $RUNAS cvs add -m 'addmsg' foo99
9188         $RUNAS cvs update
9189         $RUNAS cvs commit -m 'nomsg' foo99
9190         rm -fr $DIR/$tdir.cvsroot
9191 }
9192 run_test 99 "cvs strange file/directory operations"
9193
9194 test_100() {
9195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9196         [[ "$NETTYPE" =~ tcp ]] ||
9197                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9198         remote_ost_nodsh && skip "remote OST with nodsh"
9199         remote_mds_nodsh && skip "remote MDS with nodsh"
9200         remote_servers ||
9201                 skip "useless for local single node setup"
9202
9203         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9204                 [ "$PROT" != "tcp" ] && continue
9205                 RPORT=$(echo $REMOTE | cut -d: -f2)
9206                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9207
9208                 rc=0
9209                 LPORT=`echo $LOCAL | cut -d: -f2`
9210                 if [ $LPORT -ge 1024 ]; then
9211                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9212                         netstat -tna
9213                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9214                 fi
9215         done
9216         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9217 }
9218 run_test 100 "check local port using privileged port ==========="
9219
9220 function get_named_value()
9221 {
9222     local tag
9223
9224     tag=$1
9225     while read ;do
9226         line=$REPLY
9227         case $line in
9228         $tag*)
9229             echo $line | sed "s/^$tag[ ]*//"
9230             break
9231             ;;
9232         esac
9233     done
9234 }
9235
9236 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9237                    awk '/^max_cached_mb/ { print $2 }')
9238
9239 cleanup_101a() {
9240         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9241         trap 0
9242 }
9243
9244 test_101a() {
9245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9246
9247         local s
9248         local discard
9249         local nreads=10000
9250         local cache_limit=32
9251
9252         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9253         trap cleanup_101a EXIT
9254         $LCTL set_param -n llite.*.read_ahead_stats 0
9255         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9256
9257         #
9258         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9259         #
9260         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9261         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9262
9263         discard=0
9264         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9265                 get_named_value 'read but discarded' | cut -d" " -f1); do
9266                         discard=$(($discard + $s))
9267         done
9268         cleanup_101a
9269
9270         $LCTL get_param osc.*-osc*.rpc_stats
9271         $LCTL get_param llite.*.read_ahead_stats
9272
9273         # Discard is generally zero, but sometimes a few random reads line up
9274         # and trigger larger readahead, which is wasted & leads to discards.
9275         if [[ $(($discard)) -gt $nreads ]]; then
9276                 error "too many ($discard) discarded pages"
9277         fi
9278         rm -f $DIR/$tfile || true
9279 }
9280 run_test 101a "check read-ahead for random reads"
9281
9282 setup_test101bc() {
9283         test_mkdir $DIR/$tdir
9284         local ssize=$1
9285         local FILE_LENGTH=$2
9286         STRIPE_OFFSET=0
9287
9288         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9289
9290         local list=$(comma_list $(osts_nodes))
9291         set_osd_param $list '' read_cache_enable 0
9292         set_osd_param $list '' writethrough_cache_enable 0
9293
9294         trap cleanup_test101bc EXIT
9295         # prepare the read-ahead file
9296         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9297
9298         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9299                                 count=$FILE_SIZE_MB 2> /dev/null
9300
9301 }
9302
9303 cleanup_test101bc() {
9304         trap 0
9305         rm -rf $DIR/$tdir
9306         rm -f $DIR/$tfile
9307
9308         local list=$(comma_list $(osts_nodes))
9309         set_osd_param $list '' read_cache_enable 1
9310         set_osd_param $list '' writethrough_cache_enable 1
9311 }
9312
9313 calc_total() {
9314         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9315 }
9316
9317 ra_check_101() {
9318         local READ_SIZE=$1
9319         local STRIPE_SIZE=$2
9320         local FILE_LENGTH=$3
9321         local RA_INC=1048576
9322         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9323         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9324                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9325         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9326                         get_named_value 'read but discarded' |
9327                         cut -d" " -f1 | calc_total)
9328         if [[ $DISCARD -gt $discard_limit ]]; then
9329                 $LCTL get_param llite.*.read_ahead_stats
9330                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9331         else
9332                 echo "Read-ahead success for size ${READ_SIZE}"
9333         fi
9334 }
9335
9336 test_101b() {
9337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9338         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9339
9340         local STRIPE_SIZE=1048576
9341         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9342
9343         if [ $SLOW == "yes" ]; then
9344                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9345         else
9346                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9347         fi
9348
9349         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9350
9351         # prepare the read-ahead file
9352         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9353         cancel_lru_locks osc
9354         for BIDX in 2 4 8 16 32 64 128 256
9355         do
9356                 local BSIZE=$((BIDX*4096))
9357                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9358                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9359                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9360                 $LCTL set_param -n llite.*.read_ahead_stats 0
9361                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9362                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9363                 cancel_lru_locks osc
9364                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9365         done
9366         cleanup_test101bc
9367         true
9368 }
9369 run_test 101b "check stride-io mode read-ahead ================="
9370
9371 test_101c() {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373
9374         local STRIPE_SIZE=1048576
9375         local FILE_LENGTH=$((STRIPE_SIZE*100))
9376         local nreads=10000
9377         local rsize=65536
9378         local osc_rpc_stats
9379
9380         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9381
9382         cancel_lru_locks osc
9383         $LCTL set_param osc.*.rpc_stats 0
9384         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9385         $LCTL get_param osc.*.rpc_stats
9386         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9387                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9388                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9389                 local size
9390
9391                 if [ $lines -le 20 ]; then
9392                         echo "continue debug"
9393                         continue
9394                 fi
9395                 for size in 1 2 4 8; do
9396                         local rpc=$(echo "$stats" |
9397                                     awk '($1 == "'$size':") {print $2; exit; }')
9398                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9399                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9400                 done
9401                 echo "$osc_rpc_stats check passed!"
9402         done
9403         cleanup_test101bc
9404         true
9405 }
9406 run_test 101c "check stripe_size aligned read-ahead ================="
9407
9408 test_101d() {
9409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9410
9411         local file=$DIR/$tfile
9412         local sz_MB=${FILESIZE_101d:-80}
9413         local ra_MB=${READAHEAD_MB:-40}
9414
9415         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9416         [ $free_MB -lt $sz_MB ] &&
9417                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9418
9419         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9420         $LFS setstripe -c -1 $file || error "setstripe failed"
9421
9422         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9423         echo Cancel LRU locks on lustre client to flush the client cache
9424         cancel_lru_locks osc
9425
9426         echo Disable read-ahead
9427         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9428         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9429         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9430         $LCTL get_param -n llite.*.max_read_ahead_mb
9431
9432         echo "Reading the test file $file with read-ahead disabled"
9433         local sz_KB=$((sz_MB * 1024 / 4))
9434         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9435         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9436         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9437                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9438
9439         echo "Cancel LRU locks on lustre client to flush the client cache"
9440         cancel_lru_locks osc
9441         echo Enable read-ahead with ${ra_MB}MB
9442         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9443
9444         echo "Reading the test file $file with read-ahead enabled"
9445         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9446                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9447
9448         echo "read-ahead disabled time read $raOFF"
9449         echo "read-ahead enabled time read $raON"
9450
9451         rm -f $file
9452         wait_delete_completed
9453
9454         # use awk for this check instead of bash because it handles decimals
9455         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9456                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9457 }
9458 run_test 101d "file read with and without read-ahead enabled"
9459
9460 test_101e() {
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462
9463         local file=$DIR/$tfile
9464         local size_KB=500  #KB
9465         local count=100
9466         local bsize=1024
9467
9468         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9469         local need_KB=$((count * size_KB))
9470         [[ $free_KB -le $need_KB ]] &&
9471                 skip_env "Need free space $need_KB, have $free_KB"
9472
9473         echo "Creating $count ${size_KB}K test files"
9474         for ((i = 0; i < $count; i++)); do
9475                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9476         done
9477
9478         echo "Cancel LRU locks on lustre client to flush the client cache"
9479         cancel_lru_locks $OSC
9480
9481         echo "Reset readahead stats"
9482         $LCTL set_param -n llite.*.read_ahead_stats 0
9483
9484         for ((i = 0; i < $count; i++)); do
9485                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9486         done
9487
9488         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9489                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9490
9491         for ((i = 0; i < $count; i++)); do
9492                 rm -rf $file.$i 2>/dev/null
9493         done
9494
9495         #10000 means 20% reads are missing in readahead
9496         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9497 }
9498 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9499
9500 test_101f() {
9501         which iozone || skip_env "no iozone installed"
9502
9503         local old_debug=$($LCTL get_param debug)
9504         old_debug=${old_debug#*=}
9505         $LCTL set_param debug="reada mmap"
9506
9507         # create a test file
9508         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9509
9510         echo Cancel LRU locks on lustre client to flush the client cache
9511         cancel_lru_locks osc
9512
9513         echo Reset readahead stats
9514         $LCTL set_param -n llite.*.read_ahead_stats 0
9515
9516         echo mmap read the file with small block size
9517         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9518                 > /dev/null 2>&1
9519
9520         echo checking missing pages
9521         $LCTL get_param llite.*.read_ahead_stats
9522         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9523                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9524
9525         $LCTL set_param debug="$old_debug"
9526         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9527         rm -f $DIR/$tfile
9528 }
9529 run_test 101f "check mmap read performance"
9530
9531 test_101g_brw_size_test() {
9532         local mb=$1
9533         local pages=$((mb * 1048576 / PAGE_SIZE))
9534         local file=$DIR/$tfile
9535
9536         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9537                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9538         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9539                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9540                         return 2
9541         done
9542
9543         stack_trap "rm -f $file" EXIT
9544         $LCTL set_param -n osc.*.rpc_stats=0
9545
9546         # 10 RPCs should be enough for the test
9547         local count=10
9548         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9549                 { error "dd write ${mb} MB blocks failed"; return 3; }
9550         cancel_lru_locks osc
9551         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9552                 { error "dd write ${mb} MB blocks failed"; return 4; }
9553
9554         # calculate number of full-sized read and write RPCs
9555         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9556                 sed -n '/pages per rpc/,/^$/p' |
9557                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9558                 END { print reads,writes }'))
9559         # allow one extra full-sized read RPC for async readahead
9560         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9561                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9562         [[ ${rpcs[1]} == $count ]] ||
9563                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9564 }
9565
9566 test_101g() {
9567         remote_ost_nodsh && skip "remote OST with nodsh"
9568
9569         local rpcs
9570         local osts=$(get_facets OST)
9571         local list=$(comma_list $(osts_nodes))
9572         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9573         local brw_size="obdfilter.*.brw_size"
9574
9575         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9576
9577         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9578
9579         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9580                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9581                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9582            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9583                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9584                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9585
9586                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9587                         suffix="M"
9588
9589                 if [[ $orig_mb -lt 16 ]]; then
9590                         save_lustre_params $osts "$brw_size" > $p
9591                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9592                                 error "set 16MB RPC size failed"
9593
9594                         echo "remount client to enable new RPC size"
9595                         remount_client $MOUNT || error "remount_client failed"
9596                 fi
9597
9598                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9599                 # should be able to set brw_size=12, but no rpc_stats for that
9600                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9601         fi
9602
9603         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9604
9605         if [[ $orig_mb -lt 16 ]]; then
9606                 restore_lustre_params < $p
9607                 remount_client $MOUNT || error "remount_client restore failed"
9608         fi
9609
9610         rm -f $p $DIR/$tfile
9611 }
9612 run_test 101g "Big bulk(4/16 MiB) readahead"
9613
9614 test_101h() {
9615         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9616
9617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9618                 error "dd 70M file failed"
9619         echo Cancel LRU locks on lustre client to flush the client cache
9620         cancel_lru_locks osc
9621
9622         echo "Reset readahead stats"
9623         $LCTL set_param -n llite.*.read_ahead_stats 0
9624
9625         echo "Read 10M of data but cross 64M bundary"
9626         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9627         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9628                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9629         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9630         rm -f $p $DIR/$tfile
9631 }
9632 run_test 101h "Readahead should cover current read window"
9633
9634 test_101i() {
9635         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9636                 error "dd 10M file failed"
9637
9638         local max_per_file_mb=$($LCTL get_param -n \
9639                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9640         cancel_lru_locks osc
9641         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9642         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9643                 error "set max_read_ahead_per_file_mb to 1 failed"
9644
9645         echo "Reset readahead stats"
9646         $LCTL set_param llite.*.read_ahead_stats=0
9647
9648         dd if=$DIR/$tfile of=/dev/null bs=2M
9649
9650         $LCTL get_param llite.*.read_ahead_stats
9651         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9652                      awk '/misses/ { print $2 }')
9653         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9654         rm -f $DIR/$tfile
9655 }
9656 run_test 101i "allow current readahead to exceed reservation"
9657
9658 test_101j() {
9659         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9660                 error "setstripe $DIR/$tfile failed"
9661         local file_size=$((1048576 * 16))
9662         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9663         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9664
9665         echo Disable read-ahead
9666         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9667
9668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9669         for blk in $PAGE_SIZE 1048576 $file_size; do
9670                 cancel_lru_locks osc
9671                 echo "Reset readahead stats"
9672                 $LCTL set_param -n llite.*.read_ahead_stats=0
9673                 local count=$(($file_size / $blk))
9674                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9675                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9676                              get_named_value 'failed to fast read' |
9677                              cut -d" " -f1 | calc_total)
9678                 $LCTL get_param -n llite.*.read_ahead_stats
9679                 [ $miss -eq $count ] || error "expected $count got $miss"
9680         done
9681
9682         rm -f $p $DIR/$tfile
9683 }
9684 run_test 101j "A complete read block should be submitted when no RA"
9685
9686 setup_test102() {
9687         test_mkdir $DIR/$tdir
9688         chown $RUNAS_ID $DIR/$tdir
9689         STRIPE_SIZE=65536
9690         STRIPE_OFFSET=1
9691         STRIPE_COUNT=$OSTCOUNT
9692         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9693
9694         trap cleanup_test102 EXIT
9695         cd $DIR
9696         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9697         cd $DIR/$tdir
9698         for num in 1 2 3 4; do
9699                 for count in $(seq 1 $STRIPE_COUNT); do
9700                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9701                                 local size=`expr $STRIPE_SIZE \* $num`
9702                                 local file=file"$num-$idx-$count"
9703                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9704                         done
9705                 done
9706         done
9707
9708         cd $DIR
9709         $1 tar cf $TMP/f102.tar $tdir --xattrs
9710 }
9711
9712 cleanup_test102() {
9713         trap 0
9714         rm -f $TMP/f102.tar
9715         rm -rf $DIR/d0.sanity/d102
9716 }
9717
9718 test_102a() {
9719         [ "$UID" != 0 ] && skip "must run as root"
9720         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9721                 skip_env "must have user_xattr"
9722
9723         [ -z "$(which setfattr 2>/dev/null)" ] &&
9724                 skip_env "could not find setfattr"
9725
9726         local testfile=$DIR/$tfile
9727
9728         touch $testfile
9729         echo "set/get xattr..."
9730         setfattr -n trusted.name1 -v value1 $testfile ||
9731                 error "setfattr -n trusted.name1=value1 $testfile failed"
9732         getfattr -n trusted.name1 $testfile 2> /dev/null |
9733           grep "trusted.name1=.value1" ||
9734                 error "$testfile missing trusted.name1=value1"
9735
9736         setfattr -n user.author1 -v author1 $testfile ||
9737                 error "setfattr -n user.author1=author1 $testfile failed"
9738         getfattr -n user.author1 $testfile 2> /dev/null |
9739           grep "user.author1=.author1" ||
9740                 error "$testfile missing trusted.author1=author1"
9741
9742         echo "listxattr..."
9743         setfattr -n trusted.name2 -v value2 $testfile ||
9744                 error "$testfile unable to set trusted.name2"
9745         setfattr -n trusted.name3 -v value3 $testfile ||
9746                 error "$testfile unable to set trusted.name3"
9747         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9748             grep "trusted.name" | wc -l) -eq 3 ] ||
9749                 error "$testfile missing 3 trusted.name xattrs"
9750
9751         setfattr -n user.author2 -v author2 $testfile ||
9752                 error "$testfile unable to set user.author2"
9753         setfattr -n user.author3 -v author3 $testfile ||
9754                 error "$testfile unable to set user.author3"
9755         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9756             grep "user.author" | wc -l) -eq 3 ] ||
9757                 error "$testfile missing 3 user.author xattrs"
9758
9759         echo "remove xattr..."
9760         setfattr -x trusted.name1 $testfile ||
9761                 error "$testfile error deleting trusted.name1"
9762         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9763                 error "$testfile did not delete trusted.name1 xattr"
9764
9765         setfattr -x user.author1 $testfile ||
9766                 error "$testfile error deleting user.author1"
9767         echo "set lustre special xattr ..."
9768         $LFS setstripe -c1 $testfile
9769         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9770                 awk -F "=" '/trusted.lov/ { print $2 }' )
9771         setfattr -n "trusted.lov" -v $lovea $testfile ||
9772                 error "$testfile doesn't ignore setting trusted.lov again"
9773         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9774                 error "$testfile allow setting invalid trusted.lov"
9775         rm -f $testfile
9776 }
9777 run_test 102a "user xattr test =================================="
9778
9779 check_102b_layout() {
9780         local layout="$*"
9781         local testfile=$DIR/$tfile
9782
9783         echo "test layout '$layout'"
9784         $LFS setstripe $layout $testfile || error "setstripe failed"
9785         $LFS getstripe -y $testfile
9786
9787         echo "get/set/list trusted.lov xattr ..." # b=10930
9788         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9789         [[ "$value" =~ "trusted.lov" ]] ||
9790                 error "can't get trusted.lov from $testfile"
9791         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9792                 error "getstripe failed"
9793
9794         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9795
9796         value=$(cut -d= -f2 <<<$value)
9797         # LU-13168: truncated xattr should fail if short lov_user_md header
9798         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9799                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9800         for len in $lens; do
9801                 echo "setfattr $len $testfile.2"
9802                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9803                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9804         done
9805         local stripe_size=$($LFS getstripe -S $testfile.2)
9806         local stripe_count=$($LFS getstripe -c $testfile.2)
9807         [[ $stripe_size -eq 65536 ]] ||
9808                 error "stripe size $stripe_size != 65536"
9809         [[ $stripe_count -eq $stripe_count_orig ]] ||
9810                 error "stripe count $stripe_count != $stripe_count_orig"
9811         rm $testfile $testfile.2
9812 }
9813
9814 test_102b() {
9815         [ -z "$(which setfattr 2>/dev/null)" ] &&
9816                 skip_env "could not find setfattr"
9817         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9818
9819         # check plain layout
9820         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9821
9822         # and also check composite layout
9823         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9824
9825 }
9826 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9827
9828 test_102c() {
9829         [ -z "$(which setfattr 2>/dev/null)" ] &&
9830                 skip_env "could not find setfattr"
9831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9832
9833         # b10930: get/set/list lustre.lov xattr
9834         echo "get/set/list lustre.lov xattr ..."
9835         test_mkdir $DIR/$tdir
9836         chown $RUNAS_ID $DIR/$tdir
9837         local testfile=$DIR/$tdir/$tfile
9838         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9839                 error "setstripe failed"
9840         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9841                 error "getstripe failed"
9842         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9843         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9844
9845         local testfile2=${testfile}2
9846         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9847                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9848
9849         $RUNAS $MCREATE $testfile2
9850         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9851         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9852         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9853         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9854         [ $stripe_count -eq $STRIPECOUNT ] ||
9855                 error "stripe count $stripe_count != $STRIPECOUNT"
9856 }
9857 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9858
9859 compare_stripe_info1() {
9860         local stripe_index_all_zero=true
9861
9862         for num in 1 2 3 4; do
9863                 for count in $(seq 1 $STRIPE_COUNT); do
9864                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9865                                 local size=$((STRIPE_SIZE * num))
9866                                 local file=file"$num-$offset-$count"
9867                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9868                                 [[ $stripe_size -ne $size ]] &&
9869                                     error "$file: size $stripe_size != $size"
9870                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9871                                 # allow fewer stripes to be created, ORI-601
9872                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9873                                     error "$file: count $stripe_count != $count"
9874                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9875                                 [[ $stripe_index -ne 0 ]] &&
9876                                         stripe_index_all_zero=false
9877                         done
9878                 done
9879         done
9880         $stripe_index_all_zero &&
9881                 error "all files are being extracted starting from OST index 0"
9882         return 0
9883 }
9884
9885 have_xattrs_include() {
9886         tar --help | grep -q xattrs-include &&
9887                 echo --xattrs-include="lustre.*"
9888 }
9889
9890 test_102d() {
9891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9893
9894         XINC=$(have_xattrs_include)
9895         setup_test102
9896         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9897         cd $DIR/$tdir/$tdir
9898         compare_stripe_info1
9899 }
9900 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9901
9902 test_102f() {
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9905
9906         XINC=$(have_xattrs_include)
9907         setup_test102
9908         test_mkdir $DIR/$tdir.restore
9909         cd $DIR
9910         tar cf - --xattrs $tdir | tar xf - \
9911                 -C $DIR/$tdir.restore --xattrs $XINC
9912         cd $DIR/$tdir.restore/$tdir
9913         compare_stripe_info1
9914 }
9915 run_test 102f "tar copy files, not keep osts"
9916
9917 grow_xattr() {
9918         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9919                 skip "must have user_xattr"
9920         [ -z "$(which setfattr 2>/dev/null)" ] &&
9921                 skip_env "could not find setfattr"
9922         [ -z "$(which getfattr 2>/dev/null)" ] &&
9923                 skip_env "could not find getfattr"
9924
9925         local xsize=${1:-1024}  # in bytes
9926         local file=$DIR/$tfile
9927         local value="$(generate_string $xsize)"
9928         local xbig=trusted.big
9929         local toobig=$2
9930
9931         touch $file
9932         log "save $xbig on $file"
9933         if [ -z "$toobig" ]
9934         then
9935                 setfattr -n $xbig -v $value $file ||
9936                         error "saving $xbig on $file failed"
9937         else
9938                 setfattr -n $xbig -v $value $file &&
9939                         error "saving $xbig on $file succeeded"
9940                 return 0
9941         fi
9942
9943         local orig=$(get_xattr_value $xbig $file)
9944         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9945
9946         local xsml=trusted.sml
9947         log "save $xsml on $file"
9948         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9949
9950         local new=$(get_xattr_value $xbig $file)
9951         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9952
9953         log "grow $xsml on $file"
9954         setfattr -n $xsml -v "$value" $file ||
9955                 error "growing $xsml on $file failed"
9956
9957         new=$(get_xattr_value $xbig $file)
9958         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9959         log "$xbig still valid after growing $xsml"
9960
9961         rm -f $file
9962 }
9963
9964 test_102h() { # bug 15777
9965         grow_xattr 1024
9966 }
9967 run_test 102h "grow xattr from inside inode to external block"
9968
9969 test_102ha() {
9970         large_xattr_enabled || skip_env "ea_inode feature disabled"
9971
9972         echo "setting xattr of max xattr size: $(max_xattr_size)"
9973         grow_xattr $(max_xattr_size)
9974
9975         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9976         echo "This should fail:"
9977         grow_xattr $(($(max_xattr_size) + 10)) 1
9978 }
9979 run_test 102ha "grow xattr from inside inode to external inode"
9980
9981 test_102i() { # bug 17038
9982         [ -z "$(which getfattr 2>/dev/null)" ] &&
9983                 skip "could not find getfattr"
9984
9985         touch $DIR/$tfile
9986         ln -s $DIR/$tfile $DIR/${tfile}link
9987         getfattr -n trusted.lov $DIR/$tfile ||
9988                 error "lgetxattr on $DIR/$tfile failed"
9989         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9990                 grep -i "no such attr" ||
9991                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9992         rm -f $DIR/$tfile $DIR/${tfile}link
9993 }
9994 run_test 102i "lgetxattr test on symbolic link ============"
9995
9996 test_102j() {
9997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9998         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9999
10000         XINC=$(have_xattrs_include)
10001         setup_test102 "$RUNAS"
10002         chown $RUNAS_ID $DIR/$tdir
10003         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10004         cd $DIR/$tdir/$tdir
10005         compare_stripe_info1 "$RUNAS"
10006 }
10007 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10008
10009 test_102k() {
10010         [ -z "$(which setfattr 2>/dev/null)" ] &&
10011                 skip "could not find setfattr"
10012
10013         touch $DIR/$tfile
10014         # b22187 just check that does not crash for regular file.
10015         setfattr -n trusted.lov $DIR/$tfile
10016         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10017         local test_kdir=$DIR/$tdir
10018         test_mkdir $test_kdir
10019         local default_size=$($LFS getstripe -S $test_kdir)
10020         local default_count=$($LFS getstripe -c $test_kdir)
10021         local default_offset=$($LFS getstripe -i $test_kdir)
10022         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10023                 error 'dir setstripe failed'
10024         setfattr -n trusted.lov $test_kdir
10025         local stripe_size=$($LFS getstripe -S $test_kdir)
10026         local stripe_count=$($LFS getstripe -c $test_kdir)
10027         local stripe_offset=$($LFS getstripe -i $test_kdir)
10028         [ $stripe_size -eq $default_size ] ||
10029                 error "stripe size $stripe_size != $default_size"
10030         [ $stripe_count -eq $default_count ] ||
10031                 error "stripe count $stripe_count != $default_count"
10032         [ $stripe_offset -eq $default_offset ] ||
10033                 error "stripe offset $stripe_offset != $default_offset"
10034         rm -rf $DIR/$tfile $test_kdir
10035 }
10036 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10037
10038 test_102l() {
10039         [ -z "$(which getfattr 2>/dev/null)" ] &&
10040                 skip "could not find getfattr"
10041
10042         # LU-532 trusted. xattr is invisible to non-root
10043         local testfile=$DIR/$tfile
10044
10045         touch $testfile
10046
10047         echo "listxattr as user..."
10048         chown $RUNAS_ID $testfile
10049         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10050             grep -q "trusted" &&
10051                 error "$testfile trusted xattrs are user visible"
10052
10053         return 0;
10054 }
10055 run_test 102l "listxattr size test =================================="
10056
10057 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10058         local path=$DIR/$tfile
10059         touch $path
10060
10061         listxattr_size_check $path || error "listattr_size_check $path failed"
10062 }
10063 run_test 102m "Ensure listxattr fails on small bufffer ========"
10064
10065 cleanup_test102
10066
10067 getxattr() { # getxattr path name
10068         # Return the base64 encoding of the value of xattr name on path.
10069         local path=$1
10070         local name=$2
10071
10072         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10073         # file: $path
10074         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10075         #
10076         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10077
10078         getfattr --absolute-names --encoding=base64 --name=$name $path |
10079                 awk -F= -v name=$name '$1 == name {
10080                         print substr($0, index($0, "=") + 1);
10081         }'
10082 }
10083
10084 test_102n() { # LU-4101 mdt: protect internal xattrs
10085         [ -z "$(which setfattr 2>/dev/null)" ] &&
10086                 skip "could not find setfattr"
10087         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10088         then
10089                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10090         fi
10091
10092         local file0=$DIR/$tfile.0
10093         local file1=$DIR/$tfile.1
10094         local xattr0=$TMP/$tfile.0
10095         local xattr1=$TMP/$tfile.1
10096         local namelist="lov lma lmv link fid version som hsm"
10097         local name
10098         local value
10099
10100         rm -rf $file0 $file1 $xattr0 $xattr1
10101         touch $file0 $file1
10102
10103         # Get 'before' xattrs of $file1.
10104         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10105
10106         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10107                 namelist+=" lfsck_namespace"
10108         for name in $namelist; do
10109                 # Try to copy xattr from $file0 to $file1.
10110                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10111
10112                 setfattr --name=trusted.$name --value="$value" $file1 ||
10113                         error "setxattr 'trusted.$name' failed"
10114
10115                 # Try to set a garbage xattr.
10116                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10117
10118                 if [[ x$name == "xlov" ]]; then
10119                         setfattr --name=trusted.lov --value="$value" $file1 &&
10120                         error "setxattr invalid 'trusted.lov' success"
10121                 else
10122                         setfattr --name=trusted.$name --value="$value" $file1 ||
10123                                 error "setxattr invalid 'trusted.$name' failed"
10124                 fi
10125
10126                 # Try to remove the xattr from $file1. We don't care if this
10127                 # appears to succeed or fail, we just don't want there to be
10128                 # any changes or crashes.
10129                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10130         done
10131
10132         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10133         then
10134                 name="lfsck_ns"
10135                 # Try to copy xattr from $file0 to $file1.
10136                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10137
10138                 setfattr --name=trusted.$name --value="$value" $file1 ||
10139                         error "setxattr 'trusted.$name' failed"
10140
10141                 # Try to set a garbage xattr.
10142                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10143
10144                 setfattr --name=trusted.$name --value="$value" $file1 ||
10145                         error "setxattr 'trusted.$name' failed"
10146
10147                 # Try to remove the xattr from $file1. We don't care if this
10148                 # appears to succeed or fail, we just don't want there to be
10149                 # any changes or crashes.
10150                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10151         fi
10152
10153         # Get 'after' xattrs of file1.
10154         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10155
10156         if ! diff $xattr0 $xattr1; then
10157                 error "before and after xattrs of '$file1' differ"
10158         fi
10159
10160         rm -rf $file0 $file1 $xattr0 $xattr1
10161
10162         return 0
10163 }
10164 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10165
10166 test_102p() { # LU-4703 setxattr did not check ownership
10167         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10168                 skip "MDS needs to be at least 2.5.56"
10169
10170         local testfile=$DIR/$tfile
10171
10172         touch $testfile
10173
10174         echo "setfacl as user..."
10175         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10176         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10177
10178         echo "setfattr as user..."
10179         setfacl -m "u:$RUNAS_ID:---" $testfile
10180         $RUNAS setfattr -x system.posix_acl_access $testfile
10181         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10182 }
10183 run_test 102p "check setxattr(2) correctly fails without permission"
10184
10185 test_102q() {
10186         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10187                 skip "MDS needs to be at least 2.6.92"
10188
10189         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10190 }
10191 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10192
10193 test_102r() {
10194         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10195                 skip "MDS needs to be at least 2.6.93"
10196
10197         touch $DIR/$tfile || error "touch"
10198         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10199         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10200         rm $DIR/$tfile || error "rm"
10201
10202         #normal directory
10203         mkdir -p $DIR/$tdir || error "mkdir"
10204         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10205         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10206         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10207                 error "$testfile error deleting user.author1"
10208         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10209                 grep "user.$(basename $tdir)" &&
10210                 error "$tdir did not delete user.$(basename $tdir)"
10211         rmdir $DIR/$tdir || error "rmdir"
10212
10213         #striped directory
10214         test_mkdir $DIR/$tdir
10215         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10216         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10217         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10218                 error "$testfile error deleting user.author1"
10219         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10220                 grep "user.$(basename $tdir)" &&
10221                 error "$tdir did not delete user.$(basename $tdir)"
10222         rmdir $DIR/$tdir || error "rm striped dir"
10223 }
10224 run_test 102r "set EAs with empty values"
10225
10226 test_102s() {
10227         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10228                 skip "MDS needs to be at least 2.11.52"
10229
10230         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10231
10232         save_lustre_params client "llite.*.xattr_cache" > $save
10233
10234         for cache in 0 1; do
10235                 lctl set_param llite.*.xattr_cache=$cache
10236
10237                 rm -f $DIR/$tfile
10238                 touch $DIR/$tfile || error "touch"
10239                 for prefix in lustre security system trusted user; do
10240                         # Note getxattr() may fail with 'Operation not
10241                         # supported' or 'No such attribute' depending
10242                         # on prefix and cache.
10243                         getfattr -n $prefix.n102s $DIR/$tfile &&
10244                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10245                 done
10246         done
10247
10248         restore_lustre_params < $save
10249 }
10250 run_test 102s "getting nonexistent xattrs should fail"
10251
10252 test_102t() {
10253         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10254                 skip "MDS needs to be at least 2.11.52"
10255
10256         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10257
10258         save_lustre_params client "llite.*.xattr_cache" > $save
10259
10260         for cache in 0 1; do
10261                 lctl set_param llite.*.xattr_cache=$cache
10262
10263                 for buf_size in 0 256; do
10264                         rm -f $DIR/$tfile
10265                         touch $DIR/$tfile || error "touch"
10266                         setfattr -n user.multiop $DIR/$tfile
10267                         $MULTIOP $DIR/$tfile oa$buf_size ||
10268                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10269                 done
10270         done
10271
10272         restore_lustre_params < $save
10273 }
10274 run_test 102t "zero length xattr values handled correctly"
10275
10276 run_acl_subtest()
10277 {
10278     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10279     return $?
10280 }
10281
10282 test_103a() {
10283         [ "$UID" != 0 ] && skip "must run as root"
10284         $GSS && skip_env "could not run under gss"
10285         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10286                 skip_env "must have acl enabled"
10287         [ -z "$(which setfacl 2>/dev/null)" ] &&
10288                 skip_env "could not find setfacl"
10289         remote_mds_nodsh && skip "remote MDS with nodsh"
10290
10291         gpasswd -a daemon bin                           # LU-5641
10292         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10293
10294         declare -a identity_old
10295
10296         for num in $(seq $MDSCOUNT); do
10297                 switch_identity $num true || identity_old[$num]=$?
10298         done
10299
10300         SAVE_UMASK=$(umask)
10301         umask 0022
10302         mkdir -p $DIR/$tdir
10303         cd $DIR/$tdir
10304
10305         echo "performing cp ..."
10306         run_acl_subtest cp || error "run_acl_subtest cp failed"
10307         echo "performing getfacl-noacl..."
10308         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10309         echo "performing misc..."
10310         run_acl_subtest misc || error  "misc test failed"
10311         echo "performing permissions..."
10312         run_acl_subtest permissions || error "permissions failed"
10313         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10314         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10315                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10316                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10317         then
10318                 echo "performing permissions xattr..."
10319                 run_acl_subtest permissions_xattr ||
10320                         error "permissions_xattr failed"
10321         fi
10322         echo "performing setfacl..."
10323         run_acl_subtest setfacl || error  "setfacl test failed"
10324
10325         # inheritance test got from HP
10326         echo "performing inheritance..."
10327         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10328         chmod +x make-tree || error "chmod +x failed"
10329         run_acl_subtest inheritance || error "inheritance test failed"
10330         rm -f make-tree
10331
10332         echo "LU-974 ignore umask when acl is enabled..."
10333         run_acl_subtest 974 || error "LU-974 umask test failed"
10334         if [ $MDSCOUNT -ge 2 ]; then
10335                 run_acl_subtest 974_remote ||
10336                         error "LU-974 umask test failed under remote dir"
10337         fi
10338
10339         echo "LU-2561 newly created file is same size as directory..."
10340         if [ "$mds1_FSTYPE" != "zfs" ]; then
10341                 run_acl_subtest 2561 || error "LU-2561 test failed"
10342         else
10343                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10344         fi
10345
10346         run_acl_subtest 4924 || error "LU-4924 test failed"
10347
10348         cd $SAVE_PWD
10349         umask $SAVE_UMASK
10350
10351         for num in $(seq $MDSCOUNT); do
10352                 if [ "${identity_old[$num]}" = 1 ]; then
10353                         switch_identity $num false || identity_old[$num]=$?
10354                 fi
10355         done
10356 }
10357 run_test 103a "acl test"
10358
10359 test_103b() {
10360         declare -a pids
10361         local U
10362
10363         for U in {0..511}; do
10364                 {
10365                 local O=$(printf "%04o" $U)
10366
10367                 umask $(printf "%04o" $((511 ^ $O)))
10368                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10369                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10370
10371                 (( $S == ($O & 0666) )) ||
10372                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10373
10374                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10375                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10376                 (( $S == ($O & 0666) )) ||
10377                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10378
10379                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10380                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10381                 (( $S == ($O & 0666) )) ||
10382                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10383                 rm -f $DIR/$tfile.[smp]$0
10384                 } &
10385                 local pid=$!
10386
10387                 # limit the concurrently running threads to 64. LU-11878
10388                 local idx=$((U % 64))
10389                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10390                 pids[idx]=$pid
10391         done
10392         wait
10393 }
10394 run_test 103b "umask lfs setstripe"
10395
10396 test_103c() {
10397         mkdir -p $DIR/$tdir
10398         cp -rp $DIR/$tdir $DIR/$tdir.bak
10399
10400         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10401                 error "$DIR/$tdir shouldn't contain default ACL"
10402         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10403                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10404         true
10405 }
10406 run_test 103c "'cp -rp' won't set empty acl"
10407
10408 test_104a() {
10409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10410
10411         touch $DIR/$tfile
10412         lfs df || error "lfs df failed"
10413         lfs df -ih || error "lfs df -ih failed"
10414         lfs df -h $DIR || error "lfs df -h $DIR failed"
10415         lfs df -i $DIR || error "lfs df -i $DIR failed"
10416         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10417         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10418
10419         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10420         lctl --device %$OSC deactivate
10421         lfs df || error "lfs df with deactivated OSC failed"
10422         lctl --device %$OSC activate
10423         # wait the osc back to normal
10424         wait_osc_import_ready client ost
10425
10426         lfs df || error "lfs df with reactivated OSC failed"
10427         rm -f $DIR/$tfile
10428 }
10429 run_test 104a "lfs df [-ih] [path] test ========================="
10430
10431 test_104b() {
10432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10433         [ $RUNAS_ID -eq $UID ] &&
10434                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10435
10436         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10437                         grep "Permission denied" | wc -l)))
10438         if [ $denied_cnt -ne 0 ]; then
10439                 error "lfs check servers test failed"
10440         fi
10441 }
10442 run_test 104b "$RUNAS lfs check servers test ===================="
10443
10444 test_105a() {
10445         # doesn't work on 2.4 kernels
10446         touch $DIR/$tfile
10447         if $(flock_is_enabled); then
10448                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10449         else
10450                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10451         fi
10452         rm -f $DIR/$tfile
10453 }
10454 run_test 105a "flock when mounted without -o flock test ========"
10455
10456 test_105b() {
10457         touch $DIR/$tfile
10458         if $(flock_is_enabled); then
10459                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10460         else
10461                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10462         fi
10463         rm -f $DIR/$tfile
10464 }
10465 run_test 105b "fcntl when mounted without -o flock test ========"
10466
10467 test_105c() {
10468         touch $DIR/$tfile
10469         if $(flock_is_enabled); then
10470                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10471         else
10472                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10473         fi
10474         rm -f $DIR/$tfile
10475 }
10476 run_test 105c "lockf when mounted without -o flock test"
10477
10478 test_105d() { # bug 15924
10479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10480
10481         test_mkdir $DIR/$tdir
10482         flock_is_enabled || skip_env "mount w/o flock enabled"
10483         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10484         $LCTL set_param fail_loc=0x80000315
10485         flocks_test 2 $DIR/$tdir
10486 }
10487 run_test 105d "flock race (should not freeze) ========"
10488
10489 test_105e() { # bug 22660 && 22040
10490         flock_is_enabled || skip_env "mount w/o flock enabled"
10491
10492         touch $DIR/$tfile
10493         flocks_test 3 $DIR/$tfile
10494 }
10495 run_test 105e "Two conflicting flocks from same process"
10496
10497 test_106() { #bug 10921
10498         test_mkdir $DIR/$tdir
10499         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10500         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10501 }
10502 run_test 106 "attempt exec of dir followed by chown of that dir"
10503
10504 test_107() {
10505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10506
10507         CDIR=`pwd`
10508         local file=core
10509
10510         cd $DIR
10511         rm -f $file
10512
10513         local save_pattern=$(sysctl -n kernel.core_pattern)
10514         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10515         sysctl -w kernel.core_pattern=$file
10516         sysctl -w kernel.core_uses_pid=0
10517
10518         ulimit -c unlimited
10519         sleep 60 &
10520         SLEEPPID=$!
10521
10522         sleep 1
10523
10524         kill -s 11 $SLEEPPID
10525         wait $SLEEPPID
10526         if [ -e $file ]; then
10527                 size=`stat -c%s $file`
10528                 [ $size -eq 0 ] && error "Fail to create core file $file"
10529         else
10530                 error "Fail to create core file $file"
10531         fi
10532         rm -f $file
10533         sysctl -w kernel.core_pattern=$save_pattern
10534         sysctl -w kernel.core_uses_pid=$save_uses_pid
10535         cd $CDIR
10536 }
10537 run_test 107 "Coredump on SIG"
10538
10539 test_110() {
10540         test_mkdir $DIR/$tdir
10541         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10542         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10543                 error "mkdir with 256 char should fail, but did not"
10544         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10545                 error "create with 255 char failed"
10546         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10547                 error "create with 256 char should fail, but did not"
10548
10549         ls -l $DIR/$tdir
10550         rm -rf $DIR/$tdir
10551 }
10552 run_test 110 "filename length checking"
10553
10554 #
10555 # Purpose: To verify dynamic thread (OSS) creation.
10556 #
10557 test_115() {
10558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10559         remote_ost_nodsh && skip "remote OST with nodsh"
10560
10561         # Lustre does not stop service threads once they are started.
10562         # Reset number of running threads to default.
10563         stopall
10564         setupall
10565
10566         local OSTIO_pre
10567         local save_params="$TMP/sanity-$TESTNAME.parameters"
10568
10569         # Get ll_ost_io count before I/O
10570         OSTIO_pre=$(do_facet ost1 \
10571                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10572         # Exit if lustre is not running (ll_ost_io not running).
10573         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10574
10575         echo "Starting with $OSTIO_pre threads"
10576         local thread_max=$((OSTIO_pre * 2))
10577         local rpc_in_flight=$((thread_max * 2))
10578         # Number of I/O Process proposed to be started.
10579         local nfiles
10580         local facets=$(get_facets OST)
10581
10582         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10583         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10584
10585         # Set in_flight to $rpc_in_flight
10586         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10587                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10588         nfiles=${rpc_in_flight}
10589         # Set ost thread_max to $thread_max
10590         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10591
10592         # 5 Minutes should be sufficient for max number of OSS
10593         # threads(thread_max) to be created.
10594         local timeout=300
10595
10596         # Start I/O.
10597         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10598         test_mkdir $DIR/$tdir
10599         for i in $(seq $nfiles); do
10600                 local file=$DIR/$tdir/${tfile}-$i
10601                 $LFS setstripe -c -1 -i 0 $file
10602                 ($WTL $file $timeout)&
10603         done
10604
10605         # I/O Started - Wait for thread_started to reach thread_max or report
10606         # error if thread_started is more than thread_max.
10607         echo "Waiting for thread_started to reach thread_max"
10608         local thread_started=0
10609         local end_time=$((SECONDS + timeout))
10610
10611         while [ $SECONDS -le $end_time ] ; do
10612                 echo -n "."
10613                 # Get ost i/o thread_started count.
10614                 thread_started=$(do_facet ost1 \
10615                         "$LCTL get_param \
10616                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10617                 # Break out if thread_started is equal/greater than thread_max
10618                 if [[ $thread_started -ge $thread_max ]]; then
10619                         echo ll_ost_io thread_started $thread_started, \
10620                                 equal/greater than thread_max $thread_max
10621                         break
10622                 fi
10623                 sleep 1
10624         done
10625
10626         # Cleanup - We have the numbers, Kill i/o jobs if running.
10627         jobcount=($(jobs -p))
10628         for i in $(seq 0 $((${#jobcount[@]}-1)))
10629         do
10630                 kill -9 ${jobcount[$i]}
10631                 if [ $? -ne 0 ] ; then
10632                         echo Warning: \
10633                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10634                 fi
10635         done
10636
10637         # Cleanup files left by WTL binary.
10638         for i in $(seq $nfiles); do
10639                 local file=$DIR/$tdir/${tfile}-$i
10640                 rm -rf $file
10641                 if [ $? -ne 0 ] ; then
10642                         echo "Warning: Failed to delete file $file"
10643                 fi
10644         done
10645
10646         restore_lustre_params <$save_params
10647         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10648
10649         # Error out if no new thread has started or Thread started is greater
10650         # than thread max.
10651         if [[ $thread_started -le $OSTIO_pre ||
10652                         $thread_started -gt $thread_max ]]; then
10653                 error "ll_ost_io: thread_started $thread_started" \
10654                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10655                       "No new thread started or thread started greater " \
10656                       "than thread_max."
10657         fi
10658 }
10659 run_test 115 "verify dynamic thread creation===================="
10660
10661 free_min_max () {
10662         wait_delete_completed
10663         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10664         echo "OST kbytes available: ${AVAIL[@]}"
10665         MAXV=${AVAIL[0]}
10666         MAXI=0
10667         MINV=${AVAIL[0]}
10668         MINI=0
10669         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10670                 #echo OST $i: ${AVAIL[i]}kb
10671                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10672                         MAXV=${AVAIL[i]}
10673                         MAXI=$i
10674                 fi
10675                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10676                         MINV=${AVAIL[i]}
10677                         MINI=$i
10678                 fi
10679         done
10680         echo "Min free space: OST $MINI: $MINV"
10681         echo "Max free space: OST $MAXI: $MAXV"
10682 }
10683
10684 test_116a() { # was previously test_116()
10685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10686         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10687         remote_mds_nodsh && skip "remote MDS with nodsh"
10688
10689         echo -n "Free space priority "
10690         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10691                 head -n1
10692         declare -a AVAIL
10693         free_min_max
10694
10695         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10696         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10697         trap simple_cleanup_common EXIT
10698
10699         # Check if we need to generate uneven OSTs
10700         test_mkdir -p $DIR/$tdir/OST${MINI}
10701         local FILL=$((MINV / 4))
10702         local DIFF=$((MAXV - MINV))
10703         local DIFF2=$((DIFF * 100 / MINV))
10704
10705         local threshold=$(do_facet $SINGLEMDS \
10706                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10707         threshold=${threshold%%%}
10708         echo -n "Check for uneven OSTs: "
10709         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10710
10711         if [[ $DIFF2 -gt $threshold ]]; then
10712                 echo "ok"
10713                 echo "Don't need to fill OST$MINI"
10714         else
10715                 # generate uneven OSTs. Write 2% over the QOS threshold value
10716                 echo "no"
10717                 DIFF=$((threshold - DIFF2 + 2))
10718                 DIFF2=$((MINV * DIFF / 100))
10719                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10720                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10721                         error "setstripe failed"
10722                 DIFF=$((DIFF2 / 2048))
10723                 i=0
10724                 while [ $i -lt $DIFF ]; do
10725                         i=$((i + 1))
10726                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10727                                 bs=2M count=1 2>/dev/null
10728                         echo -n .
10729                 done
10730                 echo .
10731                 sync
10732                 sleep_maxage
10733                 free_min_max
10734         fi
10735
10736         DIFF=$((MAXV - MINV))
10737         DIFF2=$((DIFF * 100 / MINV))
10738         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10739         if [ $DIFF2 -gt $threshold ]; then
10740                 echo "ok"
10741         else
10742                 echo "failed - QOS mode won't be used"
10743                 simple_cleanup_common
10744                 skip "QOS imbalance criteria not met"
10745         fi
10746
10747         MINI1=$MINI
10748         MINV1=$MINV
10749         MAXI1=$MAXI
10750         MAXV1=$MAXV
10751
10752         # now fill using QOS
10753         $LFS setstripe -c 1 $DIR/$tdir
10754         FILL=$((FILL / 200))
10755         if [ $FILL -gt 600 ]; then
10756                 FILL=600
10757         fi
10758         echo "writing $FILL files to QOS-assigned OSTs"
10759         i=0
10760         while [ $i -lt $FILL ]; do
10761                 i=$((i + 1))
10762                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10763                         count=1 2>/dev/null
10764                 echo -n .
10765         done
10766         echo "wrote $i 200k files"
10767         sync
10768         sleep_maxage
10769
10770         echo "Note: free space may not be updated, so measurements might be off"
10771         free_min_max
10772         DIFF2=$((MAXV - MINV))
10773         echo "free space delta: orig $DIFF final $DIFF2"
10774         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10775         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10776         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10777         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10778         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10779         if [[ $DIFF -gt 0 ]]; then
10780                 FILL=$((DIFF2 * 100 / DIFF - 100))
10781                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10782         fi
10783
10784         # Figure out which files were written where
10785         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10786                awk '/'$MINI1': / {print $2; exit}')
10787         echo $UUID
10788         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10789         echo "$MINC files created on smaller OST $MINI1"
10790         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10791                awk '/'$MAXI1': / {print $2; exit}')
10792         echo $UUID
10793         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10794         echo "$MAXC files created on larger OST $MAXI1"
10795         if [[ $MINC -gt 0 ]]; then
10796                 FILL=$((MAXC * 100 / MINC - 100))
10797                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10798         fi
10799         [[ $MAXC -gt $MINC ]] ||
10800                 error_ignore LU-9 "stripe QOS didn't balance free space"
10801         simple_cleanup_common
10802 }
10803 run_test 116a "stripe QOS: free space balance ==================="
10804
10805 test_116b() { # LU-2093
10806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10807         remote_mds_nodsh && skip "remote MDS with nodsh"
10808
10809 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10810         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10811                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10812         [ -z "$old_rr" ] && skip "no QOS"
10813         do_facet $SINGLEMDS lctl set_param \
10814                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10815         mkdir -p $DIR/$tdir
10816         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10817         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10818         do_facet $SINGLEMDS lctl set_param fail_loc=0
10819         rm -rf $DIR/$tdir
10820         do_facet $SINGLEMDS lctl set_param \
10821                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10822 }
10823 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10824
10825 test_117() # bug 10891
10826 {
10827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10828
10829         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10830         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10831         lctl set_param fail_loc=0x21e
10832         > $DIR/$tfile || error "truncate failed"
10833         lctl set_param fail_loc=0
10834         echo "Truncate succeeded."
10835         rm -f $DIR/$tfile
10836 }
10837 run_test 117 "verify osd extend =========="
10838
10839 NO_SLOW_RESENDCOUNT=4
10840 export OLD_RESENDCOUNT=""
10841 set_resend_count () {
10842         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10843         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10844         lctl set_param -n $PROC_RESENDCOUNT $1
10845         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10846 }
10847
10848 # for reduce test_118* time (b=14842)
10849 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10850
10851 # Reset async IO behavior after error case
10852 reset_async() {
10853         FILE=$DIR/reset_async
10854
10855         # Ensure all OSCs are cleared
10856         $LFS setstripe -c -1 $FILE
10857         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10858         sync
10859         rm $FILE
10860 }
10861
10862 test_118a() #bug 11710
10863 {
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865
10866         reset_async
10867
10868         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10869         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10870         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10871
10872         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10873                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10874                 return 1;
10875         fi
10876         rm -f $DIR/$tfile
10877 }
10878 run_test 118a "verify O_SYNC works =========="
10879
10880 test_118b()
10881 {
10882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10883         remote_ost_nodsh && skip "remote OST with nodsh"
10884
10885         reset_async
10886
10887         #define OBD_FAIL_SRV_ENOENT 0x217
10888         set_nodes_failloc "$(osts_nodes)" 0x217
10889         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10890         RC=$?
10891         set_nodes_failloc "$(osts_nodes)" 0
10892         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10893         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10894                     grep -c writeback)
10895
10896         if [[ $RC -eq 0 ]]; then
10897                 error "Must return error due to dropped pages, rc=$RC"
10898                 return 1;
10899         fi
10900
10901         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10902                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10903                 return 1;
10904         fi
10905
10906         echo "Dirty pages not leaked on ENOENT"
10907
10908         # Due to the above error the OSC will issue all RPCs syncronously
10909         # until a subsequent RPC completes successfully without error.
10910         $MULTIOP $DIR/$tfile Ow4096yc
10911         rm -f $DIR/$tfile
10912
10913         return 0
10914 }
10915 run_test 118b "Reclaim dirty pages on fatal error =========="
10916
10917 test_118c()
10918 {
10919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10920
10921         # for 118c, restore the original resend count, LU-1940
10922         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10923                                 set_resend_count $OLD_RESENDCOUNT
10924         remote_ost_nodsh && skip "remote OST with nodsh"
10925
10926         reset_async
10927
10928         #define OBD_FAIL_OST_EROFS               0x216
10929         set_nodes_failloc "$(osts_nodes)" 0x216
10930
10931         # multiop should block due to fsync until pages are written
10932         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10933         MULTIPID=$!
10934         sleep 1
10935
10936         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10937                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10938         fi
10939
10940         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10941                     grep -c writeback)
10942         if [[ $WRITEBACK -eq 0 ]]; then
10943                 error "No page in writeback, writeback=$WRITEBACK"
10944         fi
10945
10946         set_nodes_failloc "$(osts_nodes)" 0
10947         wait $MULTIPID
10948         RC=$?
10949         if [[ $RC -ne 0 ]]; then
10950                 error "Multiop fsync failed, rc=$RC"
10951         fi
10952
10953         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10954         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10955                     grep -c writeback)
10956         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10957                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10958         fi
10959
10960         rm -f $DIR/$tfile
10961         echo "Dirty pages flushed via fsync on EROFS"
10962         return 0
10963 }
10964 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10965
10966 # continue to use small resend count to reduce test_118* time (b=14842)
10967 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10968
10969 test_118d()
10970 {
10971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10972         remote_ost_nodsh && skip "remote OST with nodsh"
10973
10974         reset_async
10975
10976         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10977         set_nodes_failloc "$(osts_nodes)" 0x214
10978         # multiop should block due to fsync until pages are written
10979         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10980         MULTIPID=$!
10981         sleep 1
10982
10983         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10984                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10985         fi
10986
10987         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10988                     grep -c writeback)
10989         if [[ $WRITEBACK -eq 0 ]]; then
10990                 error "No page in writeback, writeback=$WRITEBACK"
10991         fi
10992
10993         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10994         set_nodes_failloc "$(osts_nodes)" 0
10995
10996         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10997         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10998                     grep -c writeback)
10999         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11000                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11001         fi
11002
11003         rm -f $DIR/$tfile
11004         echo "Dirty pages gaurenteed flushed via fsync"
11005         return 0
11006 }
11007 run_test 118d "Fsync validation inject a delay of the bulk =========="
11008
11009 test_118f() {
11010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11011
11012         reset_async
11013
11014         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11015         lctl set_param fail_loc=0x8000040a
11016
11017         # Should simulate EINVAL error which is fatal
11018         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11019         RC=$?
11020         if [[ $RC -eq 0 ]]; then
11021                 error "Must return error due to dropped pages, rc=$RC"
11022         fi
11023
11024         lctl set_param fail_loc=0x0
11025
11026         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11027         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11028         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11029                     grep -c writeback)
11030         if [[ $LOCKED -ne 0 ]]; then
11031                 error "Locked pages remain in cache, locked=$LOCKED"
11032         fi
11033
11034         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11035                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11036         fi
11037
11038         rm -f $DIR/$tfile
11039         echo "No pages locked after fsync"
11040
11041         reset_async
11042         return 0
11043 }
11044 run_test 118f "Simulate unrecoverable OSC side error =========="
11045
11046 test_118g() {
11047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11048
11049         reset_async
11050
11051         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11052         lctl set_param fail_loc=0x406
11053
11054         # simulate local -ENOMEM
11055         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11056         RC=$?
11057
11058         lctl set_param fail_loc=0
11059         if [[ $RC -eq 0 ]]; then
11060                 error "Must return error due to dropped pages, rc=$RC"
11061         fi
11062
11063         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11064         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11065         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11066                         grep -c writeback)
11067         if [[ $LOCKED -ne 0 ]]; then
11068                 error "Locked pages remain in cache, locked=$LOCKED"
11069         fi
11070
11071         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11072                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11073         fi
11074
11075         rm -f $DIR/$tfile
11076         echo "No pages locked after fsync"
11077
11078         reset_async
11079         return 0
11080 }
11081 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11082
11083 test_118h() {
11084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11085         remote_ost_nodsh && skip "remote OST with nodsh"
11086
11087         reset_async
11088
11089         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11090         set_nodes_failloc "$(osts_nodes)" 0x20e
11091         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11092         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11093         RC=$?
11094
11095         set_nodes_failloc "$(osts_nodes)" 0
11096         if [[ $RC -eq 0 ]]; then
11097                 error "Must return error due to dropped pages, rc=$RC"
11098         fi
11099
11100         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11101         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11102         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11103                     grep -c writeback)
11104         if [[ $LOCKED -ne 0 ]]; then
11105                 error "Locked pages remain in cache, locked=$LOCKED"
11106         fi
11107
11108         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11109                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11110         fi
11111
11112         rm -f $DIR/$tfile
11113         echo "No pages locked after fsync"
11114
11115         return 0
11116 }
11117 run_test 118h "Verify timeout in handling recoverables errors  =========="
11118
11119 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11120
11121 test_118i() {
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         remote_ost_nodsh && skip "remote OST with nodsh"
11124
11125         reset_async
11126
11127         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11128         set_nodes_failloc "$(osts_nodes)" 0x20e
11129
11130         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11132         PID=$!
11133         sleep 5
11134         set_nodes_failloc "$(osts_nodes)" 0
11135
11136         wait $PID
11137         RC=$?
11138         if [[ $RC -ne 0 ]]; then
11139                 error "got error, but should be not, rc=$RC"
11140         fi
11141
11142         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11143         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11144         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11145         if [[ $LOCKED -ne 0 ]]; then
11146                 error "Locked pages remain in cache, locked=$LOCKED"
11147         fi
11148
11149         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11150                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11151         fi
11152
11153         rm -f $DIR/$tfile
11154         echo "No pages locked after fsync"
11155
11156         return 0
11157 }
11158 run_test 118i "Fix error before timeout in recoverable error  =========="
11159
11160 [ "$SLOW" = "no" ] && set_resend_count 4
11161
11162 test_118j() {
11163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11164         remote_ost_nodsh && skip "remote OST with nodsh"
11165
11166         reset_async
11167
11168         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11169         set_nodes_failloc "$(osts_nodes)" 0x220
11170
11171         # return -EIO from OST
11172         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11173         RC=$?
11174         set_nodes_failloc "$(osts_nodes)" 0x0
11175         if [[ $RC -eq 0 ]]; then
11176                 error "Must return error due to dropped pages, rc=$RC"
11177         fi
11178
11179         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11180         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11181         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11182         if [[ $LOCKED -ne 0 ]]; then
11183                 error "Locked pages remain in cache, locked=$LOCKED"
11184         fi
11185
11186         # in recoverable error on OST we want resend and stay until it finished
11187         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11188                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11189         fi
11190
11191         rm -f $DIR/$tfile
11192         echo "No pages locked after fsync"
11193
11194         return 0
11195 }
11196 run_test 118j "Simulate unrecoverable OST side error =========="
11197
11198 test_118k()
11199 {
11200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11201         remote_ost_nodsh && skip "remote OSTs with nodsh"
11202
11203         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11204         set_nodes_failloc "$(osts_nodes)" 0x20e
11205         test_mkdir $DIR/$tdir
11206
11207         for ((i=0;i<10;i++)); do
11208                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11209                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11210                 SLEEPPID=$!
11211                 sleep 0.500s
11212                 kill $SLEEPPID
11213                 wait $SLEEPPID
11214         done
11215
11216         set_nodes_failloc "$(osts_nodes)" 0
11217         rm -rf $DIR/$tdir
11218 }
11219 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11220
11221 test_118l() # LU-646
11222 {
11223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11224
11225         test_mkdir $DIR/$tdir
11226         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11227         rm -rf $DIR/$tdir
11228 }
11229 run_test 118l "fsync dir"
11230
11231 test_118m() # LU-3066
11232 {
11233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11234
11235         test_mkdir $DIR/$tdir
11236         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11237         rm -rf $DIR/$tdir
11238 }
11239 run_test 118m "fdatasync dir ========="
11240
11241 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11242
11243 test_118n()
11244 {
11245         local begin
11246         local end
11247
11248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11249         remote_ost_nodsh && skip "remote OSTs with nodsh"
11250
11251         # Sleep to avoid a cached response.
11252         #define OBD_STATFS_CACHE_SECONDS 1
11253         sleep 2
11254
11255         # Inject a 10 second delay in the OST_STATFS handler.
11256         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11257         set_nodes_failloc "$(osts_nodes)" 0x242
11258
11259         begin=$SECONDS
11260         stat --file-system $MOUNT > /dev/null
11261         end=$SECONDS
11262
11263         set_nodes_failloc "$(osts_nodes)" 0
11264
11265         if ((end - begin > 20)); then
11266             error "statfs took $((end - begin)) seconds, expected 10"
11267         fi
11268 }
11269 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11270
11271 test_119a() # bug 11737
11272 {
11273         BSIZE=$((512 * 1024))
11274         directio write $DIR/$tfile 0 1 $BSIZE
11275         # We ask to read two blocks, which is more than a file size.
11276         # directio will indicate an error when requested and actual
11277         # sizes aren't equeal (a normal situation in this case) and
11278         # print actual read amount.
11279         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11280         if [ "$NOB" != "$BSIZE" ]; then
11281                 error "read $NOB bytes instead of $BSIZE"
11282         fi
11283         rm -f $DIR/$tfile
11284 }
11285 run_test 119a "Short directIO read must return actual read amount"
11286
11287 test_119b() # bug 11737
11288 {
11289         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11290
11291         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11292         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11293         sync
11294         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11295                 error "direct read failed"
11296         rm -f $DIR/$tfile
11297 }
11298 run_test 119b "Sparse directIO read must return actual read amount"
11299
11300 test_119c() # bug 13099
11301 {
11302         BSIZE=1048576
11303         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11304         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11305         rm -f $DIR/$tfile
11306 }
11307 run_test 119c "Testing for direct read hitting hole"
11308
11309 test_119d() # bug 15950
11310 {
11311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11312
11313         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11314         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11315         BSIZE=1048576
11316         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11317         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11318         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11319         lctl set_param fail_loc=0x40d
11320         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11321         pid_dio=$!
11322         sleep 1
11323         cat $DIR/$tfile > /dev/null &
11324         lctl set_param fail_loc=0
11325         pid_reads=$!
11326         wait $pid_dio
11327         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11328         sleep 2
11329         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11330         error "the read rpcs have not completed in 2s"
11331         rm -f $DIR/$tfile
11332         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11333 }
11334 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11335
11336 test_120a() {
11337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11338         remote_mds_nodsh && skip "remote MDS with nodsh"
11339         test_mkdir -i0 -c1 $DIR/$tdir
11340         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11341                 skip_env "no early lock cancel on server"
11342
11343         lru_resize_disable mdc
11344         lru_resize_disable osc
11345         cancel_lru_locks mdc
11346         # asynchronous object destroy at MDT could cause bl ast to client
11347         cancel_lru_locks osc
11348
11349         stat $DIR/$tdir > /dev/null
11350         can1=$(do_facet mds1 \
11351                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11352                awk '/ldlm_cancel/ {print $2}')
11353         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11354                awk '/ldlm_bl_callback/ {print $2}')
11355         test_mkdir -i0 -c1 $DIR/$tdir/d1
11356         can2=$(do_facet mds1 \
11357                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11358                awk '/ldlm_cancel/ {print $2}')
11359         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11360                awk '/ldlm_bl_callback/ {print $2}')
11361         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11362         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11363         lru_resize_enable mdc
11364         lru_resize_enable osc
11365 }
11366 run_test 120a "Early Lock Cancel: mkdir test"
11367
11368 test_120b() {
11369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11370         remote_mds_nodsh && skip "remote MDS with nodsh"
11371         test_mkdir $DIR/$tdir
11372         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11373                 skip_env "no early lock cancel on server"
11374
11375         lru_resize_disable mdc
11376         lru_resize_disable osc
11377         cancel_lru_locks mdc
11378         stat $DIR/$tdir > /dev/null
11379         can1=$(do_facet $SINGLEMDS \
11380                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11381                awk '/ldlm_cancel/ {print $2}')
11382         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11383                awk '/ldlm_bl_callback/ {print $2}')
11384         touch $DIR/$tdir/f1
11385         can2=$(do_facet $SINGLEMDS \
11386                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11387                awk '/ldlm_cancel/ {print $2}')
11388         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11389                awk '/ldlm_bl_callback/ {print $2}')
11390         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11391         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11392         lru_resize_enable mdc
11393         lru_resize_enable osc
11394 }
11395 run_test 120b "Early Lock Cancel: create test"
11396
11397 test_120c() {
11398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11399         remote_mds_nodsh && skip "remote MDS with nodsh"
11400         test_mkdir -i0 -c1 $DIR/$tdir
11401         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11402                 skip "no early lock cancel on server"
11403
11404         lru_resize_disable mdc
11405         lru_resize_disable osc
11406         test_mkdir -i0 -c1 $DIR/$tdir/d1
11407         test_mkdir -i0 -c1 $DIR/$tdir/d2
11408         touch $DIR/$tdir/d1/f1
11409         cancel_lru_locks mdc
11410         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11411         can1=$(do_facet mds1 \
11412                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11413                awk '/ldlm_cancel/ {print $2}')
11414         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11415                awk '/ldlm_bl_callback/ {print $2}')
11416         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11417         can2=$(do_facet mds1 \
11418                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11419                awk '/ldlm_cancel/ {print $2}')
11420         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11421                awk '/ldlm_bl_callback/ {print $2}')
11422         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11423         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11424         lru_resize_enable mdc
11425         lru_resize_enable osc
11426 }
11427 run_test 120c "Early Lock Cancel: link test"
11428
11429 test_120d() {
11430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11431         remote_mds_nodsh && skip "remote MDS with nodsh"
11432         test_mkdir -i0 -c1 $DIR/$tdir
11433         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11434                 skip_env "no early lock cancel on server"
11435
11436         lru_resize_disable mdc
11437         lru_resize_disable osc
11438         touch $DIR/$tdir
11439         cancel_lru_locks mdc
11440         stat $DIR/$tdir > /dev/null
11441         can1=$(do_facet mds1 \
11442                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11443                awk '/ldlm_cancel/ {print $2}')
11444         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11445                awk '/ldlm_bl_callback/ {print $2}')
11446         chmod a+x $DIR/$tdir
11447         can2=$(do_facet mds1 \
11448                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11449                awk '/ldlm_cancel/ {print $2}')
11450         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11451                awk '/ldlm_bl_callback/ {print $2}')
11452         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11453         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11454         lru_resize_enable mdc
11455         lru_resize_enable osc
11456 }
11457 run_test 120d "Early Lock Cancel: setattr test"
11458
11459 test_120e() {
11460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11461         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11462                 skip_env "no early lock cancel on server"
11463         remote_mds_nodsh && skip "remote MDS with nodsh"
11464
11465         local dlmtrace_set=false
11466
11467         test_mkdir -i0 -c1 $DIR/$tdir
11468         lru_resize_disable mdc
11469         lru_resize_disable osc
11470         ! $LCTL get_param debug | grep -q dlmtrace &&
11471                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11472         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11473         cancel_lru_locks mdc
11474         cancel_lru_locks osc
11475         dd if=$DIR/$tdir/f1 of=/dev/null
11476         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11477         # XXX client can not do early lock cancel of OST lock
11478         # during unlink (LU-4206), so cancel osc lock now.
11479         sleep 2
11480         cancel_lru_locks osc
11481         can1=$(do_facet mds1 \
11482                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11483                awk '/ldlm_cancel/ {print $2}')
11484         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11485                awk '/ldlm_bl_callback/ {print $2}')
11486         unlink $DIR/$tdir/f1
11487         sleep 5
11488         can2=$(do_facet mds1 \
11489                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11490                awk '/ldlm_cancel/ {print $2}')
11491         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11492                awk '/ldlm_bl_callback/ {print $2}')
11493         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11494                 $LCTL dk $TMP/cancel.debug.txt
11495         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11496                 $LCTL dk $TMP/blocking.debug.txt
11497         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11498         lru_resize_enable mdc
11499         lru_resize_enable osc
11500 }
11501 run_test 120e "Early Lock Cancel: unlink test"
11502
11503 test_120f() {
11504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11505         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11506                 skip_env "no early lock cancel on server"
11507         remote_mds_nodsh && skip "remote MDS with nodsh"
11508
11509         test_mkdir -i0 -c1 $DIR/$tdir
11510         lru_resize_disable mdc
11511         lru_resize_disable osc
11512         test_mkdir -i0 -c1 $DIR/$tdir/d1
11513         test_mkdir -i0 -c1 $DIR/$tdir/d2
11514         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11515         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11516         cancel_lru_locks mdc
11517         cancel_lru_locks osc
11518         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11519         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11520         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11521         # XXX client can not do early lock cancel of OST lock
11522         # during rename (LU-4206), so cancel osc lock now.
11523         sleep 2
11524         cancel_lru_locks osc
11525         can1=$(do_facet mds1 \
11526                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11527                awk '/ldlm_cancel/ {print $2}')
11528         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11529                awk '/ldlm_bl_callback/ {print $2}')
11530         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11531         sleep 5
11532         can2=$(do_facet mds1 \
11533                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11534                awk '/ldlm_cancel/ {print $2}')
11535         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11536                awk '/ldlm_bl_callback/ {print $2}')
11537         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11538         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11539         lru_resize_enable mdc
11540         lru_resize_enable osc
11541 }
11542 run_test 120f "Early Lock Cancel: rename test"
11543
11544 test_120g() {
11545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11546         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11547                 skip_env "no early lock cancel on server"
11548         remote_mds_nodsh && skip "remote MDS with nodsh"
11549
11550         lru_resize_disable mdc
11551         lru_resize_disable osc
11552         count=10000
11553         echo create $count files
11554         test_mkdir $DIR/$tdir
11555         cancel_lru_locks mdc
11556         cancel_lru_locks osc
11557         t0=$(date +%s)
11558
11559         can0=$(do_facet $SINGLEMDS \
11560                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11561                awk '/ldlm_cancel/ {print $2}')
11562         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11563                awk '/ldlm_bl_callback/ {print $2}')
11564         createmany -o $DIR/$tdir/f $count
11565         sync
11566         can1=$(do_facet $SINGLEMDS \
11567                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11568                awk '/ldlm_cancel/ {print $2}')
11569         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11570                awk '/ldlm_bl_callback/ {print $2}')
11571         t1=$(date +%s)
11572         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11573         echo rm $count files
11574         rm -r $DIR/$tdir
11575         sync
11576         can2=$(do_facet $SINGLEMDS \
11577                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11578                awk '/ldlm_cancel/ {print $2}')
11579         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11580                awk '/ldlm_bl_callback/ {print $2}')
11581         t2=$(date +%s)
11582         echo total: $count removes in $((t2-t1))
11583         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11584         sleep 2
11585         # wait for commitment of removal
11586         lru_resize_enable mdc
11587         lru_resize_enable osc
11588 }
11589 run_test 120g "Early Lock Cancel: performance test"
11590
11591 test_121() { #bug #10589
11592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11593
11594         rm -rf $DIR/$tfile
11595         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11596 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11597         lctl set_param fail_loc=0x310
11598         cancel_lru_locks osc > /dev/null
11599         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11600         lctl set_param fail_loc=0
11601         [[ $reads -eq $writes ]] ||
11602                 error "read $reads blocks, must be $writes blocks"
11603 }
11604 run_test 121 "read cancel race ========="
11605
11606 test_123a_base() { # was test 123, statahead(bug 11401)
11607         local lsx="$1"
11608
11609         SLOWOK=0
11610         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11611                 log "testing UP system. Performance may be lower than expected."
11612                 SLOWOK=1
11613         fi
11614
11615         rm -rf $DIR/$tdir
11616         test_mkdir $DIR/$tdir
11617         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11618         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11619         MULT=10
11620         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11621                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11622
11623                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11624                 lctl set_param -n llite.*.statahead_max 0
11625                 lctl get_param llite.*.statahead_max
11626                 cancel_lru_locks mdc
11627                 cancel_lru_locks osc
11628                 stime=$(date +%s)
11629                 time $lsx $DIR/$tdir | wc -l
11630                 etime=$(date +%s)
11631                 delta=$((etime - stime))
11632                 log "$lsx $i files without statahead: $delta sec"
11633                 lctl set_param llite.*.statahead_max=$max
11634
11635                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11636                         grep "statahead wrong:" | awk '{print $3}')
11637                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11638                 cancel_lru_locks mdc
11639                 cancel_lru_locks osc
11640                 stime=$(date +%s)
11641                 time $lsx $DIR/$tdir | wc -l
11642                 etime=$(date +%s)
11643                 delta_sa=$((etime - stime))
11644                 log "$lsx $i files with statahead: $delta_sa sec"
11645                 lctl get_param -n llite.*.statahead_stats
11646                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11647                         grep "statahead wrong:" | awk '{print $3}')
11648
11649                 [[ $swrong -lt $ewrong ]] &&
11650                         log "statahead was stopped, maybe too many locks held!"
11651                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11652
11653                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11654                         max=$(lctl get_param -n llite.*.statahead_max |
11655                                 head -n 1)
11656                         lctl set_param -n llite.*.statahead_max 0
11657                         lctl get_param llite.*.statahead_max
11658                         cancel_lru_locks mdc
11659                         cancel_lru_locks osc
11660                         stime=$(date +%s)
11661                         time $lsx $DIR/$tdir | wc -l
11662                         etime=$(date +%s)
11663                         delta=$((etime - stime))
11664                         log "$lsx $i files again without statahead: $delta sec"
11665                         lctl set_param llite.*.statahead_max=$max
11666                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11667                                 if [  $SLOWOK -eq 0 ]; then
11668                                         error "$lsx $i files is slower with statahead!"
11669                                 else
11670                                         log "$lsx $i files is slower with statahead!"
11671                                 fi
11672                                 break
11673                         fi
11674                 fi
11675
11676                 [ $delta -gt 20 ] && break
11677                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11678                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11679         done
11680         log "$lsx done"
11681
11682         stime=$(date +%s)
11683         rm -r $DIR/$tdir
11684         sync
11685         etime=$(date +%s)
11686         delta=$((etime - stime))
11687         log "rm -r $DIR/$tdir/: $delta seconds"
11688         log "rm done"
11689         lctl get_param -n llite.*.statahead_stats
11690 }
11691
11692 test_123aa() {
11693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11694
11695         test_123a_base "ls -l"
11696 }
11697 run_test 123aa "verify statahead work"
11698
11699 test_123ab() {
11700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11701
11702         statx_supported || skip_env "Test must be statx() syscall supported"
11703
11704         test_123a_base "$STATX -l"
11705 }
11706 run_test 123ab "verify statahead work by using statx"
11707
11708 test_123ac() {
11709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11710
11711         statx_supported || skip_env "Test must be statx() syscall supported"
11712
11713         local rpcs_before
11714         local rpcs_after
11715         local agl_before
11716         local agl_after
11717
11718         cancel_lru_locks $OSC
11719         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11720         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11721                 awk '/agl.total:/ {print $3}')
11722         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11723         test_123a_base "$STATX --cached=always -D"
11724         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11725                 awk '/agl.total:/ {print $3}')
11726         [ $agl_before -eq $agl_after ] ||
11727                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11728         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11729         [ $rpcs_after -eq $rpcs_before ] ||
11730                 error "$STATX should not send glimpse RPCs to $OSC"
11731 }
11732 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11733
11734 test_123b () { # statahead(bug 15027)
11735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11736
11737         test_mkdir $DIR/$tdir
11738         createmany -o $DIR/$tdir/$tfile-%d 1000
11739
11740         cancel_lru_locks mdc
11741         cancel_lru_locks osc
11742
11743 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11744         lctl set_param fail_loc=0x80000803
11745         ls -lR $DIR/$tdir > /dev/null
11746         log "ls done"
11747         lctl set_param fail_loc=0x0
11748         lctl get_param -n llite.*.statahead_stats
11749         rm -r $DIR/$tdir
11750         sync
11751
11752 }
11753 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11754
11755 test_123c() {
11756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11757
11758         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11759         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11760         touch $DIR/$tdir.1/{1..3}
11761         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11762
11763         remount_client $MOUNT
11764
11765         $MULTIOP $DIR/$tdir.0 Q
11766
11767         # let statahead to complete
11768         ls -l $DIR/$tdir.0 > /dev/null
11769
11770         testid=$(echo $TESTNAME | tr '_' ' ')
11771         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11772                 error "statahead warning" || true
11773 }
11774 run_test 123c "Can not initialize inode warning on DNE statahead"
11775
11776 test_124a() {
11777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11778         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11779                 skip_env "no lru resize on server"
11780
11781         local NR=2000
11782
11783         test_mkdir $DIR/$tdir
11784
11785         log "create $NR files at $DIR/$tdir"
11786         createmany -o $DIR/$tdir/f $NR ||
11787                 error "failed to create $NR files in $DIR/$tdir"
11788
11789         cancel_lru_locks mdc
11790         ls -l $DIR/$tdir > /dev/null
11791
11792         local NSDIR=""
11793         local LRU_SIZE=0
11794         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11795                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11796                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11797                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11798                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11799                         log "NSDIR=$NSDIR"
11800                         log "NS=$(basename $NSDIR)"
11801                         break
11802                 fi
11803         done
11804
11805         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11806                 skip "Not enough cached locks created!"
11807         fi
11808         log "LRU=$LRU_SIZE"
11809
11810         local SLEEP=30
11811
11812         # We know that lru resize allows one client to hold $LIMIT locks
11813         # for 10h. After that locks begin to be killed by client.
11814         local MAX_HRS=10
11815         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11816         log "LIMIT=$LIMIT"
11817         if [ $LIMIT -lt $LRU_SIZE ]; then
11818                 skip "Limit is too small $LIMIT"
11819         fi
11820
11821         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11822         # killing locks. Some time was spent for creating locks. This means
11823         # that up to the moment of sleep finish we must have killed some of
11824         # them (10-100 locks). This depends on how fast ther were created.
11825         # Many of them were touched in almost the same moment and thus will
11826         # be killed in groups.
11827         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11828
11829         # Use $LRU_SIZE_B here to take into account real number of locks
11830         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11831         local LRU_SIZE_B=$LRU_SIZE
11832         log "LVF=$LVF"
11833         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11834         log "OLD_LVF=$OLD_LVF"
11835         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11836
11837         # Let's make sure that we really have some margin. Client checks
11838         # cached locks every 10 sec.
11839         SLEEP=$((SLEEP+20))
11840         log "Sleep ${SLEEP} sec"
11841         local SEC=0
11842         while ((SEC<$SLEEP)); do
11843                 echo -n "..."
11844                 sleep 5
11845                 SEC=$((SEC+5))
11846                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11847                 echo -n "$LRU_SIZE"
11848         done
11849         echo ""
11850         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11851         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11852
11853         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11854                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11855                 unlinkmany $DIR/$tdir/f $NR
11856                 return
11857         }
11858
11859         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11860         log "unlink $NR files at $DIR/$tdir"
11861         unlinkmany $DIR/$tdir/f $NR
11862 }
11863 run_test 124a "lru resize ======================================="
11864
11865 get_max_pool_limit()
11866 {
11867         local limit=$($LCTL get_param \
11868                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11869         local max=0
11870         for l in $limit; do
11871                 if [[ $l -gt $max ]]; then
11872                         max=$l
11873                 fi
11874         done
11875         echo $max
11876 }
11877
11878 test_124b() {
11879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11880         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11881                 skip_env "no lru resize on server"
11882
11883         LIMIT=$(get_max_pool_limit)
11884
11885         NR=$(($(default_lru_size)*20))
11886         if [[ $NR -gt $LIMIT ]]; then
11887                 log "Limit lock number by $LIMIT locks"
11888                 NR=$LIMIT
11889         fi
11890
11891         IFree=$(mdsrate_inodes_available)
11892         if [ $IFree -lt $NR ]; then
11893                 log "Limit lock number by $IFree inodes"
11894                 NR=$IFree
11895         fi
11896
11897         lru_resize_disable mdc
11898         test_mkdir -p $DIR/$tdir/disable_lru_resize
11899
11900         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11901         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11902         cancel_lru_locks mdc
11903         stime=`date +%s`
11904         PID=""
11905         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11906         PID="$PID $!"
11907         sleep 2
11908         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11909         PID="$PID $!"
11910         sleep 2
11911         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11912         PID="$PID $!"
11913         wait $PID
11914         etime=`date +%s`
11915         nolruresize_delta=$((etime-stime))
11916         log "ls -la time: $nolruresize_delta seconds"
11917         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11918         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11919
11920         lru_resize_enable mdc
11921         test_mkdir -p $DIR/$tdir/enable_lru_resize
11922
11923         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11924         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11925         cancel_lru_locks mdc
11926         stime=`date +%s`
11927         PID=""
11928         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11929         PID="$PID $!"
11930         sleep 2
11931         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11932         PID="$PID $!"
11933         sleep 2
11934         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11935         PID="$PID $!"
11936         wait $PID
11937         etime=`date +%s`
11938         lruresize_delta=$((etime-stime))
11939         log "ls -la time: $lruresize_delta seconds"
11940         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11941
11942         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11943                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11944         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11945                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11946         else
11947                 log "lru resize performs the same with no lru resize"
11948         fi
11949         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11950 }
11951 run_test 124b "lru resize (performance test) ======================="
11952
11953 test_124c() {
11954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11955         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11956                 skip_env "no lru resize on server"
11957
11958         # cache ununsed locks on client
11959         local nr=100
11960         cancel_lru_locks mdc
11961         test_mkdir $DIR/$tdir
11962         createmany -o $DIR/$tdir/f $nr ||
11963                 error "failed to create $nr files in $DIR/$tdir"
11964         ls -l $DIR/$tdir > /dev/null
11965
11966         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11967         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11968         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11969         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11970         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11971
11972         # set lru_max_age to 1 sec
11973         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11974         echo "sleep $((recalc_p * 2)) seconds..."
11975         sleep $((recalc_p * 2))
11976
11977         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11978         # restore lru_max_age
11979         $LCTL set_param -n $nsdir.lru_max_age $max_age
11980         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11981         unlinkmany $DIR/$tdir/f $nr
11982 }
11983 run_test 124c "LRUR cancel very aged locks"
11984
11985 test_124d() {
11986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11987         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11988                 skip_env "no lru resize on server"
11989
11990         # cache ununsed locks on client
11991         local nr=100
11992
11993         lru_resize_disable mdc
11994         stack_trap "lru_resize_enable mdc" EXIT
11995
11996         cancel_lru_locks mdc
11997
11998         # asynchronous object destroy at MDT could cause bl ast to client
11999         test_mkdir $DIR/$tdir
12000         createmany -o $DIR/$tdir/f $nr ||
12001                 error "failed to create $nr files in $DIR/$tdir"
12002         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12003
12004         ls -l $DIR/$tdir > /dev/null
12005
12006         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12007         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12008         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12009         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12010
12011         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12012
12013         # set lru_max_age to 1 sec
12014         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12015         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12016
12017         echo "sleep $((recalc_p * 2)) seconds..."
12018         sleep $((recalc_p * 2))
12019
12020         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12021
12022         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12023 }
12024 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12025
12026 test_125() { # 13358
12027         $LCTL get_param -n llite.*.client_type | grep -q local ||
12028                 skip "must run as local client"
12029         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12030                 skip_env "must have acl enabled"
12031         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12032
12033         test_mkdir $DIR/$tdir
12034         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12035         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12036         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12037 }
12038 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12039
12040 test_126() { # bug 12829/13455
12041         $GSS && skip_env "must run as gss disabled"
12042         $LCTL get_param -n llite.*.client_type | grep -q local ||
12043                 skip "must run as local client"
12044         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12045
12046         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12047         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12048         rm -f $DIR/$tfile
12049         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12050 }
12051 run_test 126 "check that the fsgid provided by the client is taken into account"
12052
12053 test_127a() { # bug 15521
12054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12055         local name count samp unit min max sum sumsq
12056
12057         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12058         echo "stats before reset"
12059         $LCTL get_param osc.*.stats
12060         $LCTL set_param osc.*.stats=0
12061         local fsize=$((2048 * 1024))
12062
12063         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12064         cancel_lru_locks osc
12065         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12066
12067         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12068         stack_trap "rm -f $TMP/$tfile.tmp"
12069         while read name count samp unit min max sum sumsq; do
12070                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12071                 [ ! $min ] && error "Missing min value for $name proc entry"
12072                 eval $name=$count || error "Wrong proc format"
12073
12074                 case $name in
12075                 read_bytes|write_bytes)
12076                         [[ "$unit" =~ "bytes" ]] ||
12077                                 error "unit is not 'bytes': $unit"
12078                         (( $min >= 4096 )) || error "min is too small: $min"
12079                         (( $min <= $fsize )) || error "min is too big: $min"
12080                         (( $max >= 4096 )) || error "max is too small: $max"
12081                         (( $max <= $fsize )) || error "max is too big: $max"
12082                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12083                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12084                                 error "sumsquare is too small: $sumsq"
12085                         (( $sumsq <= $fsize * $fsize )) ||
12086                                 error "sumsquare is too big: $sumsq"
12087                         ;;
12088                 ost_read|ost_write)
12089                         [[ "$unit" =~ "usec" ]] ||
12090                                 error "unit is not 'usec': $unit"
12091                         ;;
12092                 *)      ;;
12093                 esac
12094         done < $DIR/$tfile.tmp
12095
12096         #check that we actually got some stats
12097         [ "$read_bytes" ] || error "Missing read_bytes stats"
12098         [ "$write_bytes" ] || error "Missing write_bytes stats"
12099         [ "$read_bytes" != 0 ] || error "no read done"
12100         [ "$write_bytes" != 0 ] || error "no write done"
12101 }
12102 run_test 127a "verify the client stats are sane"
12103
12104 test_127b() { # bug LU-333
12105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12106         local name count samp unit min max sum sumsq
12107
12108         echo "stats before reset"
12109         $LCTL get_param llite.*.stats
12110         $LCTL set_param llite.*.stats=0
12111
12112         # perform 2 reads and writes so MAX is different from SUM.
12113         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12114         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12115         cancel_lru_locks osc
12116         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12117         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12118
12119         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12120         stack_trap "rm -f $TMP/$tfile.tmp"
12121         while read name count samp unit min max sum sumsq; do
12122                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12123                 eval $name=$count || error "Wrong proc format"
12124
12125                 case $name in
12126                 read_bytes|write_bytes)
12127                         [[ "$unit" =~ "bytes" ]] ||
12128                                 error "unit is not 'bytes': $unit"
12129                         (( $count == 2 )) || error "count is not 2: $count"
12130                         (( $min == $PAGE_SIZE )) ||
12131                                 error "min is not $PAGE_SIZE: $min"
12132                         (( $max == $PAGE_SIZE )) ||
12133                                 error "max is not $PAGE_SIZE: $max"
12134                         (( $sum == $PAGE_SIZE * 2 )) ||
12135                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12136                         ;;
12137                 read|write)
12138                         [[ "$unit" =~ "usec" ]] ||
12139                                 error "unit is not 'usec': $unit"
12140                         ;;
12141                 *)      ;;
12142                 esac
12143         done < $TMP/$tfile.tmp
12144
12145         #check that we actually got some stats
12146         [ "$read_bytes" ] || error "Missing read_bytes stats"
12147         [ "$write_bytes" ] || error "Missing write_bytes stats"
12148         [ "$read_bytes" != 0 ] || error "no read done"
12149         [ "$write_bytes" != 0 ] || error "no write done"
12150 }
12151 run_test 127b "verify the llite client stats are sane"
12152
12153 test_127c() { # LU-12394
12154         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12155         local size
12156         local bsize
12157         local reads
12158         local writes
12159         local count
12160
12161         $LCTL set_param llite.*.extents_stats=1
12162         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12163
12164         # Use two stripes so there is enough space in default config
12165         $LFS setstripe -c 2 $DIR/$tfile
12166
12167         # Extent stats start at 0-4K and go in power of two buckets
12168         # LL_HIST_START = 12 --> 2^12 = 4K
12169         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12170         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12171         # small configs
12172         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12173                 do
12174                 # Write and read, 2x each, second time at a non-zero offset
12175                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12176                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12177                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12178                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12179                 rm -f $DIR/$tfile
12180         done
12181
12182         $LCTL get_param llite.*.extents_stats
12183
12184         count=2
12185         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12186                 do
12187                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12188                                 grep -m 1 $bsize)
12189                 reads=$(echo $bucket | awk '{print $5}')
12190                 writes=$(echo $bucket | awk '{print $9}')
12191                 [ "$reads" -eq $count ] ||
12192                         error "$reads reads in < $bsize bucket, expect $count"
12193                 [ "$writes" -eq $count ] ||
12194                         error "$writes writes in < $bsize bucket, expect $count"
12195         done
12196
12197         # Test mmap write and read
12198         $LCTL set_param llite.*.extents_stats=c
12199         size=512
12200         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12201         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12202         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12203
12204         $LCTL get_param llite.*.extents_stats
12205
12206         count=$(((size*1024) / PAGE_SIZE))
12207
12208         bsize=$((2 * PAGE_SIZE / 1024))K
12209
12210         bucket=$($LCTL get_param -n llite.*.extents_stats |
12211                         grep -m 1 $bsize)
12212         reads=$(echo $bucket | awk '{print $5}')
12213         writes=$(echo $bucket | awk '{print $9}')
12214         # mmap writes fault in the page first, creating an additonal read
12215         [ "$reads" -eq $((2 * count)) ] ||
12216                 error "$reads reads in < $bsize bucket, expect $count"
12217         [ "$writes" -eq $count ] ||
12218                 error "$writes writes in < $bsize bucket, expect $count"
12219 }
12220 run_test 127c "test llite extent stats with regular & mmap i/o"
12221
12222 test_128() { # bug 15212
12223         touch $DIR/$tfile
12224         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12225                 find $DIR/$tfile
12226                 find $DIR/$tfile
12227         EOF
12228
12229         result=$(grep error $TMP/$tfile.log)
12230         rm -f $DIR/$tfile $TMP/$tfile.log
12231         [ -z "$result" ] ||
12232                 error "consecutive find's under interactive lfs failed"
12233 }
12234 run_test 128 "interactive lfs for 2 consecutive find's"
12235
12236 set_dir_limits () {
12237         local mntdev
12238         local canondev
12239         local node
12240
12241         local ldproc=/proc/fs/ldiskfs
12242         local facets=$(get_facets MDS)
12243
12244         for facet in ${facets//,/ }; do
12245                 canondev=$(ldiskfs_canon \
12246                            *.$(convert_facet2label $facet).mntdev $facet)
12247                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12248                         ldproc=/sys/fs/ldiskfs
12249                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12250                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12251         done
12252 }
12253
12254 check_mds_dmesg() {
12255         local facets=$(get_facets MDS)
12256         for facet in ${facets//,/ }; do
12257                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12258         done
12259         return 1
12260 }
12261
12262 test_129() {
12263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12264         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12265                 skip "Need MDS version with at least 2.5.56"
12266         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12267                 skip_env "ldiskfs only test"
12268         fi
12269         remote_mds_nodsh && skip "remote MDS with nodsh"
12270
12271         local ENOSPC=28
12272         local has_warning=false
12273
12274         rm -rf $DIR/$tdir
12275         mkdir -p $DIR/$tdir
12276
12277         # block size of mds1
12278         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12279         set_dir_limits $maxsize $((maxsize * 6 / 8))
12280         stack_trap "set_dir_limits 0 0"
12281         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12282         local dirsize=$(stat -c%s "$DIR/$tdir")
12283         local nfiles=0
12284         while (( $dirsize <= $maxsize )); do
12285                 $MCREATE $DIR/$tdir/file_base_$nfiles
12286                 rc=$?
12287                 # check two errors:
12288                 # ENOSPC for ext4 max_dir_size, which has been used since
12289                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12290                 if (( rc == ENOSPC )); then
12291                         set_dir_limits 0 0
12292                         echo "rc=$rc returned as expected after $nfiles files"
12293
12294                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12295                                 error "create failed w/o dir size limit"
12296
12297                         # messages may be rate limited if test is run repeatedly
12298                         check_mds_dmesg '"is approaching max"' ||
12299                                 echo "warning message should be output"
12300                         check_mds_dmesg '"has reached max"' ||
12301                                 echo "reached message should be output"
12302
12303                         dirsize=$(stat -c%s "$DIR/$tdir")
12304
12305                         [[ $dirsize -ge $maxsize ]] && return 0
12306                         error "dirsize $dirsize < $maxsize after $nfiles files"
12307                 elif (( rc != 0 )); then
12308                         break
12309                 fi
12310                 nfiles=$((nfiles + 1))
12311                 dirsize=$(stat -c%s "$DIR/$tdir")
12312         done
12313
12314         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12315 }
12316 run_test 129 "test directory size limit ========================"
12317
12318 OLDIFS="$IFS"
12319 cleanup_130() {
12320         trap 0
12321         IFS="$OLDIFS"
12322 }
12323
12324 test_130a() {
12325         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12326         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12327
12328         trap cleanup_130 EXIT RETURN
12329
12330         local fm_file=$DIR/$tfile
12331         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12332         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12333                 error "dd failed for $fm_file"
12334
12335         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12336         filefrag -ves $fm_file
12337         RC=$?
12338         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12339                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12340         [ $RC != 0 ] && error "filefrag $fm_file failed"
12341
12342         filefrag_op=$(filefrag -ve -k $fm_file |
12343                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12344         lun=$($LFS getstripe -i $fm_file)
12345
12346         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12347         IFS=$'\n'
12348         tot_len=0
12349         for line in $filefrag_op
12350         do
12351                 frag_lun=`echo $line | cut -d: -f5`
12352                 ext_len=`echo $line | cut -d: -f4`
12353                 if (( $frag_lun != $lun )); then
12354                         cleanup_130
12355                         error "FIEMAP on 1-stripe file($fm_file) failed"
12356                         return
12357                 fi
12358                 (( tot_len += ext_len ))
12359         done
12360
12361         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12362                 cleanup_130
12363                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12364                 return
12365         fi
12366
12367         cleanup_130
12368
12369         echo "FIEMAP on single striped file succeeded"
12370 }
12371 run_test 130a "FIEMAP (1-stripe file)"
12372
12373 test_130b() {
12374         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12375
12376         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12377         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12378
12379         trap cleanup_130 EXIT RETURN
12380
12381         local fm_file=$DIR/$tfile
12382         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12383                         error "setstripe on $fm_file"
12384         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12385                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12386
12387         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12388                 error "dd failed on $fm_file"
12389
12390         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12391         filefrag_op=$(filefrag -ve -k $fm_file |
12392                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12393
12394         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12395                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12396
12397         IFS=$'\n'
12398         tot_len=0
12399         num_luns=1
12400         for line in $filefrag_op
12401         do
12402                 frag_lun=$(echo $line | cut -d: -f5 |
12403                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12404                 ext_len=$(echo $line | cut -d: -f4)
12405                 if (( $frag_lun != $last_lun )); then
12406                         if (( tot_len != 1024 )); then
12407                                 cleanup_130
12408                                 error "FIEMAP on $fm_file failed; returned " \
12409                                 "len $tot_len for OST $last_lun instead of 1024"
12410                                 return
12411                         else
12412                                 (( num_luns += 1 ))
12413                                 tot_len=0
12414                         fi
12415                 fi
12416                 (( tot_len += ext_len ))
12417                 last_lun=$frag_lun
12418         done
12419         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12420                 cleanup_130
12421                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12422                         "luns or wrong len for OST $last_lun"
12423                 return
12424         fi
12425
12426         cleanup_130
12427
12428         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12429 }
12430 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12431
12432 test_130c() {
12433         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12434
12435         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12436         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12437
12438         trap cleanup_130 EXIT RETURN
12439
12440         local fm_file=$DIR/$tfile
12441         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12442         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12443                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12444
12445         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12446                         error "dd failed on $fm_file"
12447
12448         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12449         filefrag_op=$(filefrag -ve -k $fm_file |
12450                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12451
12452         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12453                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12454
12455         IFS=$'\n'
12456         tot_len=0
12457         num_luns=1
12458         for line in $filefrag_op
12459         do
12460                 frag_lun=$(echo $line | cut -d: -f5 |
12461                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12462                 ext_len=$(echo $line | cut -d: -f4)
12463                 if (( $frag_lun != $last_lun )); then
12464                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12465                         if (( logical != 512 )); then
12466                                 cleanup_130
12467                                 error "FIEMAP on $fm_file failed; returned " \
12468                                 "logical start for lun $logical instead of 512"
12469                                 return
12470                         fi
12471                         if (( tot_len != 512 )); then
12472                                 cleanup_130
12473                                 error "FIEMAP on $fm_file failed; returned " \
12474                                 "len $tot_len for OST $last_lun instead of 1024"
12475                                 return
12476                         else
12477                                 (( num_luns += 1 ))
12478                                 tot_len=0
12479                         fi
12480                 fi
12481                 (( tot_len += ext_len ))
12482                 last_lun=$frag_lun
12483         done
12484         if (( num_luns != 2 || tot_len != 512 )); then
12485                 cleanup_130
12486                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12487                         "luns or wrong len for OST $last_lun"
12488                 return
12489         fi
12490
12491         cleanup_130
12492
12493         echo "FIEMAP on 2-stripe file with hole succeeded"
12494 }
12495 run_test 130c "FIEMAP (2-stripe file with hole)"
12496
12497 test_130d() {
12498         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12499
12500         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12501         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12502
12503         trap cleanup_130 EXIT RETURN
12504
12505         local fm_file=$DIR/$tfile
12506         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12507                         error "setstripe on $fm_file"
12508         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12509                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12510
12511         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12512         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12513                 error "dd failed on $fm_file"
12514
12515         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12516         filefrag_op=$(filefrag -ve -k $fm_file |
12517                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12518
12519         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12520                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12521
12522         IFS=$'\n'
12523         tot_len=0
12524         num_luns=1
12525         for line in $filefrag_op
12526         do
12527                 frag_lun=$(echo $line | cut -d: -f5 |
12528                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12529                 ext_len=$(echo $line | cut -d: -f4)
12530                 if (( $frag_lun != $last_lun )); then
12531                         if (( tot_len != 1024 )); then
12532                                 cleanup_130
12533                                 error "FIEMAP on $fm_file failed; returned " \
12534                                 "len $tot_len for OST $last_lun instead of 1024"
12535                                 return
12536                         else
12537                                 (( num_luns += 1 ))
12538                                 tot_len=0
12539                         fi
12540                 fi
12541                 (( tot_len += ext_len ))
12542                 last_lun=$frag_lun
12543         done
12544         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12545                 cleanup_130
12546                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12547                         "luns or wrong len for OST $last_lun"
12548                 return
12549         fi
12550
12551         cleanup_130
12552
12553         echo "FIEMAP on N-stripe file succeeded"
12554 }
12555 run_test 130d "FIEMAP (N-stripe file)"
12556
12557 test_130e() {
12558         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12559
12560         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12561         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12562
12563         trap cleanup_130 EXIT RETURN
12564
12565         local fm_file=$DIR/$tfile
12566         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12567         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12568                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12569
12570         NUM_BLKS=512
12571         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12572         for ((i = 0; i < $NUM_BLKS; i++))
12573         do
12574                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12575         done
12576
12577         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12578         filefrag_op=$(filefrag -ve -k $fm_file |
12579                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12580
12581         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12582                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12583
12584         IFS=$'\n'
12585         tot_len=0
12586         num_luns=1
12587         for line in $filefrag_op
12588         do
12589                 frag_lun=$(echo $line | cut -d: -f5 |
12590                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12591                 ext_len=$(echo $line | cut -d: -f4)
12592                 if (( $frag_lun != $last_lun )); then
12593                         if (( tot_len != $EXPECTED_LEN )); then
12594                                 cleanup_130
12595                                 error "FIEMAP on $fm_file failed; returned " \
12596                                 "len $tot_len for OST $last_lun instead " \
12597                                 "of $EXPECTED_LEN"
12598                                 return
12599                         else
12600                                 (( num_luns += 1 ))
12601                                 tot_len=0
12602                         fi
12603                 fi
12604                 (( tot_len += ext_len ))
12605                 last_lun=$frag_lun
12606         done
12607         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12608                 cleanup_130
12609                 error "FIEMAP on $fm_file failed; returned wrong number " \
12610                         "of luns or wrong len for OST $last_lun"
12611                 return
12612         fi
12613
12614         cleanup_130
12615
12616         echo "FIEMAP with continuation calls succeeded"
12617 }
12618 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12619
12620 test_130f() {
12621         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12622         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12623
12624         local fm_file=$DIR/$tfile
12625         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12626                 error "multiop create with lov_delay_create on $fm_file"
12627
12628         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12629         filefrag_extents=$(filefrag -vek $fm_file |
12630                            awk '/extents? found/ { print $2 }')
12631         if [[ "$filefrag_extents" != "0" ]]; then
12632                 error "FIEMAP on $fm_file failed; " \
12633                       "returned $filefrag_extents expected 0"
12634         fi
12635
12636         rm -f $fm_file
12637 }
12638 run_test 130f "FIEMAP (unstriped file)"
12639
12640 # Test for writev/readv
12641 test_131a() {
12642         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12643                 error "writev test failed"
12644         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12645                 error "readv failed"
12646         rm -f $DIR/$tfile
12647 }
12648 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12649
12650 test_131b() {
12651         local fsize=$((524288 + 1048576 + 1572864))
12652         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12653                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12654                         error "append writev test failed"
12655
12656         ((fsize += 1572864 + 1048576))
12657         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12658                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12659                         error "append writev test failed"
12660         rm -f $DIR/$tfile
12661 }
12662 run_test 131b "test append writev"
12663
12664 test_131c() {
12665         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12666         error "NOT PASS"
12667 }
12668 run_test 131c "test read/write on file w/o objects"
12669
12670 test_131d() {
12671         rwv -f $DIR/$tfile -w -n 1 1572864
12672         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12673         if [ "$NOB" != 1572864 ]; then
12674                 error "Short read filed: read $NOB bytes instead of 1572864"
12675         fi
12676         rm -f $DIR/$tfile
12677 }
12678 run_test 131d "test short read"
12679
12680 test_131e() {
12681         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12682         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12683         error "read hitting hole failed"
12684         rm -f $DIR/$tfile
12685 }
12686 run_test 131e "test read hitting hole"
12687
12688 check_stats() {
12689         local facet=$1
12690         local op=$2
12691         local want=${3:-0}
12692         local res
12693
12694         case $facet in
12695         mds*) res=$(do_facet $facet \
12696                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12697                  ;;
12698         ost*) res=$(do_facet $facet \
12699                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12700                  ;;
12701         *) error "Wrong facet '$facet'" ;;
12702         esac
12703         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12704         # if the argument $3 is zero, it means any stat increment is ok.
12705         if [[ $want -gt 0 ]]; then
12706                 local count=$(echo $res | awk '{ print $2 }')
12707                 [[ $count -ne $want ]] &&
12708                         error "The $op counter on $facet is $count, not $want"
12709         fi
12710 }
12711
12712 test_133a() {
12713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12714         remote_ost_nodsh && skip "remote OST with nodsh"
12715         remote_mds_nodsh && skip "remote MDS with nodsh"
12716         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12717                 skip_env "MDS doesn't support rename stats"
12718
12719         local testdir=$DIR/${tdir}/stats_testdir
12720
12721         mkdir -p $DIR/${tdir}
12722
12723         # clear stats.
12724         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12725         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12726
12727         # verify mdt stats first.
12728         mkdir ${testdir} || error "mkdir failed"
12729         check_stats $SINGLEMDS "mkdir" 1
12730         touch ${testdir}/${tfile} || error "touch failed"
12731         check_stats $SINGLEMDS "open" 1
12732         check_stats $SINGLEMDS "close" 1
12733         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12734                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12735                 check_stats $SINGLEMDS "mknod" 2
12736         }
12737         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12738         check_stats $SINGLEMDS "unlink" 1
12739         rm -f ${testdir}/${tfile} || error "file remove failed"
12740         check_stats $SINGLEMDS "unlink" 2
12741
12742         # remove working dir and check mdt stats again.
12743         rmdir ${testdir} || error "rmdir failed"
12744         check_stats $SINGLEMDS "rmdir" 1
12745
12746         local testdir1=$DIR/${tdir}/stats_testdir1
12747         mkdir -p ${testdir}
12748         mkdir -p ${testdir1}
12749         touch ${testdir1}/test1
12750         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12751         check_stats $SINGLEMDS "crossdir_rename" 1
12752
12753         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12754         check_stats $SINGLEMDS "samedir_rename" 1
12755
12756         rm -rf $DIR/${tdir}
12757 }
12758 run_test 133a "Verifying MDT stats ========================================"
12759
12760 test_133b() {
12761         local res
12762
12763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12764         remote_ost_nodsh && skip "remote OST with nodsh"
12765         remote_mds_nodsh && skip "remote MDS with nodsh"
12766
12767         local testdir=$DIR/${tdir}/stats_testdir
12768
12769         mkdir -p ${testdir} || error "mkdir failed"
12770         touch ${testdir}/${tfile} || error "touch failed"
12771         cancel_lru_locks mdc
12772
12773         # clear stats.
12774         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12775         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12776
12777         # extra mdt stats verification.
12778         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12779         check_stats $SINGLEMDS "setattr" 1
12780         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12781         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12782         then            # LU-1740
12783                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12784                 check_stats $SINGLEMDS "getattr" 1
12785         fi
12786         rm -rf $DIR/${tdir}
12787
12788         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12789         # so the check below is not reliable
12790         [ $MDSCOUNT -eq 1 ] || return 0
12791
12792         # Sleep to avoid a cached response.
12793         #define OBD_STATFS_CACHE_SECONDS 1
12794         sleep 2
12795         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12796         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12797         $LFS df || error "lfs failed"
12798         check_stats $SINGLEMDS "statfs" 1
12799
12800         # check aggregated statfs (LU-10018)
12801         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12802                 return 0
12803         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12804                 return 0
12805         sleep 2
12806         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12807         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12808         df $DIR
12809         check_stats $SINGLEMDS "statfs" 1
12810
12811         # We want to check that the client didn't send OST_STATFS to
12812         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12813         # extra care is needed here.
12814         if remote_mds; then
12815                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12816                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12817
12818                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12819                 [ "$res" ] && error "OST got STATFS"
12820         fi
12821
12822         return 0
12823 }
12824 run_test 133b "Verifying extra MDT stats =================================="
12825
12826 test_133c() {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828         remote_ost_nodsh && skip "remote OST with nodsh"
12829         remote_mds_nodsh && skip "remote MDS with nodsh"
12830
12831         local testdir=$DIR/$tdir/stats_testdir
12832
12833         test_mkdir -p $testdir
12834
12835         # verify obdfilter stats.
12836         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12837         sync
12838         cancel_lru_locks osc
12839         wait_delete_completed
12840
12841         # clear stats.
12842         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12843         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12844
12845         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12846                 error "dd failed"
12847         sync
12848         cancel_lru_locks osc
12849         check_stats ost1 "write" 1
12850
12851         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12852         check_stats ost1 "read" 1
12853
12854         > $testdir/$tfile || error "truncate failed"
12855         check_stats ost1 "punch" 1
12856
12857         rm -f $testdir/$tfile || error "file remove failed"
12858         wait_delete_completed
12859         check_stats ost1 "destroy" 1
12860
12861         rm -rf $DIR/$tdir
12862 }
12863 run_test 133c "Verifying OST stats ========================================"
12864
12865 order_2() {
12866         local value=$1
12867         local orig=$value
12868         local order=1
12869
12870         while [ $value -ge 2 ]; do
12871                 order=$((order*2))
12872                 value=$((value/2))
12873         done
12874
12875         if [ $orig -gt $order ]; then
12876                 order=$((order*2))
12877         fi
12878         echo $order
12879 }
12880
12881 size_in_KMGT() {
12882     local value=$1
12883     local size=('K' 'M' 'G' 'T');
12884     local i=0
12885     local size_string=$value
12886
12887     while [ $value -ge 1024 ]; do
12888         if [ $i -gt 3 ]; then
12889             #T is the biggest unit we get here, if that is bigger,
12890             #just return XXXT
12891             size_string=${value}T
12892             break
12893         fi
12894         value=$((value >> 10))
12895         if [ $value -lt 1024 ]; then
12896             size_string=${value}${size[$i]}
12897             break
12898         fi
12899         i=$((i + 1))
12900     done
12901
12902     echo $size_string
12903 }
12904
12905 get_rename_size() {
12906         local size=$1
12907         local context=${2:-.}
12908         local sample=$(do_facet $SINGLEMDS $LCTL \
12909                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12910                 grep -A1 $context |
12911                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12912         echo $sample
12913 }
12914
12915 test_133d() {
12916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12917         remote_ost_nodsh && skip "remote OST with nodsh"
12918         remote_mds_nodsh && skip "remote MDS with nodsh"
12919         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12920                 skip_env "MDS doesn't support rename stats"
12921
12922         local testdir1=$DIR/${tdir}/stats_testdir1
12923         local testdir2=$DIR/${tdir}/stats_testdir2
12924         mkdir -p $DIR/${tdir}
12925
12926         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12927
12928         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12929         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12930
12931         createmany -o $testdir1/test 512 || error "createmany failed"
12932
12933         # check samedir rename size
12934         mv ${testdir1}/test0 ${testdir1}/test_0
12935
12936         local testdir1_size=$(ls -l $DIR/${tdir} |
12937                 awk '/stats_testdir1/ {print $5}')
12938         local testdir2_size=$(ls -l $DIR/${tdir} |
12939                 awk '/stats_testdir2/ {print $5}')
12940
12941         testdir1_size=$(order_2 $testdir1_size)
12942         testdir2_size=$(order_2 $testdir2_size)
12943
12944         testdir1_size=$(size_in_KMGT $testdir1_size)
12945         testdir2_size=$(size_in_KMGT $testdir2_size)
12946
12947         echo "source rename dir size: ${testdir1_size}"
12948         echo "target rename dir size: ${testdir2_size}"
12949
12950         local cmd="do_facet $SINGLEMDS $LCTL "
12951         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12952
12953         eval $cmd || error "$cmd failed"
12954         local samedir=$($cmd | grep 'same_dir')
12955         local same_sample=$(get_rename_size $testdir1_size)
12956         [ -z "$samedir" ] && error "samedir_rename_size count error"
12957         [[ $same_sample -eq 1 ]] ||
12958                 error "samedir_rename_size error $same_sample"
12959         echo "Check same dir rename stats success"
12960
12961         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12962
12963         # check crossdir rename size
12964         mv ${testdir1}/test_0 ${testdir2}/test_0
12965
12966         testdir1_size=$(ls -l $DIR/${tdir} |
12967                 awk '/stats_testdir1/ {print $5}')
12968         testdir2_size=$(ls -l $DIR/${tdir} |
12969                 awk '/stats_testdir2/ {print $5}')
12970
12971         testdir1_size=$(order_2 $testdir1_size)
12972         testdir2_size=$(order_2 $testdir2_size)
12973
12974         testdir1_size=$(size_in_KMGT $testdir1_size)
12975         testdir2_size=$(size_in_KMGT $testdir2_size)
12976
12977         echo "source rename dir size: ${testdir1_size}"
12978         echo "target rename dir size: ${testdir2_size}"
12979
12980         eval $cmd || error "$cmd failed"
12981         local crossdir=$($cmd | grep 'crossdir')
12982         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12983         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12984         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12985         [[ $src_sample -eq 1 ]] ||
12986                 error "crossdir_rename_size error $src_sample"
12987         [[ $tgt_sample -eq 1 ]] ||
12988                 error "crossdir_rename_size error $tgt_sample"
12989         echo "Check cross dir rename stats success"
12990         rm -rf $DIR/${tdir}
12991 }
12992 run_test 133d "Verifying rename_stats ========================================"
12993
12994 test_133e() {
12995         remote_mds_nodsh && skip "remote MDS with nodsh"
12996         remote_ost_nodsh && skip "remote OST with nodsh"
12997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12998
12999         local testdir=$DIR/${tdir}/stats_testdir
13000         local ctr f0 f1 bs=32768 count=42 sum
13001
13002         mkdir -p ${testdir} || error "mkdir failed"
13003
13004         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13005
13006         for ctr in {write,read}_bytes; do
13007                 sync
13008                 cancel_lru_locks osc
13009
13010                 do_facet ost1 $LCTL set_param -n \
13011                         "obdfilter.*.exports.clear=clear"
13012
13013                 if [ $ctr = write_bytes ]; then
13014                         f0=/dev/zero
13015                         f1=${testdir}/${tfile}
13016                 else
13017                         f0=${testdir}/${tfile}
13018                         f1=/dev/null
13019                 fi
13020
13021                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13022                         error "dd failed"
13023                 sync
13024                 cancel_lru_locks osc
13025
13026                 sum=$(do_facet ost1 $LCTL get_param \
13027                         "obdfilter.*.exports.*.stats" |
13028                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13029                                 $1 == ctr { sum += $7 }
13030                                 END { printf("%0.0f", sum) }')
13031
13032                 if ((sum != bs * count)); then
13033                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13034                 fi
13035         done
13036
13037         rm -rf $DIR/${tdir}
13038 }
13039 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13040
13041 test_133f() {
13042         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13043                 skip "too old lustre for get_param -R ($facet_ver)"
13044
13045         # verifying readability.
13046         $LCTL get_param -R '*' &> /dev/null
13047
13048         # Verifing writability with badarea_io.
13049         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13050                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13051                 error "client badarea_io failed"
13052
13053         # remount the FS in case writes/reads /proc break the FS
13054         cleanup || error "failed to unmount"
13055         setup || error "failed to setup"
13056 }
13057 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13058
13059 test_133g() {
13060         remote_mds_nodsh && skip "remote MDS with nodsh"
13061         remote_ost_nodsh && skip "remote OST with nodsh"
13062
13063         local facet
13064         for facet in mds1 ost1; do
13065                 local facet_ver=$(lustre_version_code $facet)
13066                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13067                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13068                 else
13069                         log "$facet: too old lustre for get_param -R"
13070                 fi
13071                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13072                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13073                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13074                                 xargs badarea_io" ||
13075                                         error "$facet badarea_io failed"
13076                 else
13077                         skip_noexit "$facet: too old lustre for get_param -R"
13078                 fi
13079         done
13080
13081         # remount the FS in case writes/reads /proc break the FS
13082         cleanup || error "failed to unmount"
13083         setup || error "failed to setup"
13084 }
13085 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13086
13087 test_133h() {
13088         remote_mds_nodsh && skip "remote MDS with nodsh"
13089         remote_ost_nodsh && skip "remote OST with nodsh"
13090         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13091                 skip "Need MDS version at least 2.9.54"
13092
13093         local facet
13094         for facet in client mds1 ost1; do
13095                 # Get the list of files that are missing the terminating newline
13096                 local plist=$(do_facet $facet
13097                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13098                 local ent
13099                 for ent in $plist; do
13100                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13101                                 awk -v FS='\v' -v RS='\v\v' \
13102                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13103                                         print FILENAME}'" 2>/dev/null)
13104                         [ -z $missing ] || {
13105                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13106                                 error "file does not end with newline: $facet-$ent"
13107                         }
13108                 done
13109         done
13110 }
13111 run_test 133h "Proc files should end with newlines"
13112
13113 test_134a() {
13114         remote_mds_nodsh && skip "remote MDS with nodsh"
13115         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13116                 skip "Need MDS version at least 2.7.54"
13117
13118         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13119         cancel_lru_locks mdc
13120
13121         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13122         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13123         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13124
13125         local nr=1000
13126         createmany -o $DIR/$tdir/f $nr ||
13127                 error "failed to create $nr files in $DIR/$tdir"
13128         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13129
13130         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13131         do_facet mds1 $LCTL set_param fail_loc=0x327
13132         do_facet mds1 $LCTL set_param fail_val=500
13133         touch $DIR/$tdir/m
13134
13135         echo "sleep 10 seconds ..."
13136         sleep 10
13137         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13138
13139         do_facet mds1 $LCTL set_param fail_loc=0
13140         do_facet mds1 $LCTL set_param fail_val=0
13141         [ $lck_cnt -lt $unused ] ||
13142                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13143
13144         rm $DIR/$tdir/m
13145         unlinkmany $DIR/$tdir/f $nr
13146 }
13147 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13148
13149 test_134b() {
13150         remote_mds_nodsh && skip "remote MDS with nodsh"
13151         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13152                 skip "Need MDS version at least 2.7.54"
13153
13154         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13155         cancel_lru_locks mdc
13156
13157         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13158                         ldlm.lock_reclaim_threshold_mb)
13159         # disable reclaim temporarily
13160         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13161
13162         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13163         do_facet mds1 $LCTL set_param fail_loc=0x328
13164         do_facet mds1 $LCTL set_param fail_val=500
13165
13166         $LCTL set_param debug=+trace
13167
13168         local nr=600
13169         createmany -o $DIR/$tdir/f $nr &
13170         local create_pid=$!
13171
13172         echo "Sleep $TIMEOUT seconds ..."
13173         sleep $TIMEOUT
13174         if ! ps -p $create_pid  > /dev/null 2>&1; then
13175                 do_facet mds1 $LCTL set_param fail_loc=0
13176                 do_facet mds1 $LCTL set_param fail_val=0
13177                 do_facet mds1 $LCTL set_param \
13178                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13179                 error "createmany finished incorrectly!"
13180         fi
13181         do_facet mds1 $LCTL set_param fail_loc=0
13182         do_facet mds1 $LCTL set_param fail_val=0
13183         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13184         wait $create_pid || return 1
13185
13186         unlinkmany $DIR/$tdir/f $nr
13187 }
13188 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13189
13190 test_135() {
13191         remote_mds_nodsh && skip "remote MDS with nodsh"
13192         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13193                 skip "Need MDS version at least 2.13.50"
13194         local fname
13195
13196         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13197
13198 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13199         #set only one record at plain llog
13200         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13201
13202         #fill already existed plain llog each 64767
13203         #wrapping whole catalog
13204         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13205
13206         createmany -o $DIR/$tdir/$tfile_ 64700
13207         for (( i = 0; i < 64700; i = i + 2 ))
13208         do
13209                 rm $DIR/$tdir/$tfile_$i &
13210                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13211                 local pid=$!
13212                 wait $pid
13213         done
13214
13215         #waiting osp synchronization
13216         wait_delete_completed
13217 }
13218 run_test 135 "Race catalog processing"
13219
13220 test_136() {
13221         remote_mds_nodsh && skip "remote MDS with nodsh"
13222         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13223                 skip "Need MDS version at least 2.13.50"
13224         local fname
13225
13226         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13227         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13228         #set only one record at plain llog
13229 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13230         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13231
13232         #fill already existed 2 plain llogs each 64767
13233         #wrapping whole catalog
13234         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13235         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13236         wait_delete_completed
13237
13238         createmany -o $DIR/$tdir/$tfile_ 10
13239         sleep 25
13240
13241         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13242         for (( i = 0; i < 10; i = i + 3 ))
13243         do
13244                 rm $DIR/$tdir/$tfile_$i &
13245                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13246                 local pid=$!
13247                 wait $pid
13248                 sleep 7
13249                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13250         done
13251
13252         #waiting osp synchronization
13253         wait_delete_completed
13254 }
13255 run_test 136 "Race catalog processing 2"
13256
13257 test_140() { #bug-17379
13258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13259
13260         test_mkdir $DIR/$tdir
13261         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13262         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13263
13264         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13265         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13266         local i=0
13267         while i=$((i + 1)); do
13268                 test_mkdir $i
13269                 cd $i || error "Changing to $i"
13270                 ln -s ../stat stat || error "Creating stat symlink"
13271                 # Read the symlink until ELOOP present,
13272                 # not LBUGing the system is considered success,
13273                 # we didn't overrun the stack.
13274                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13275                 if [ $ret -ne 0 ]; then
13276                         if [ $ret -eq 40 ]; then
13277                                 break  # -ELOOP
13278                         else
13279                                 error "Open stat symlink"
13280                                         return
13281                         fi
13282                 fi
13283         done
13284         i=$((i - 1))
13285         echo "The symlink depth = $i"
13286         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13287                 error "Invalid symlink depth"
13288
13289         # Test recursive symlink
13290         ln -s symlink_self symlink_self
13291         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13292         echo "open symlink_self returns $ret"
13293         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13294 }
13295 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13296
13297 test_150a() {
13298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13299
13300         local TF="$TMP/$tfile"
13301
13302         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13303         cp $TF $DIR/$tfile
13304         cancel_lru_locks $OSC
13305         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13306         remount_client $MOUNT
13307         df -P $MOUNT
13308         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13309
13310         $TRUNCATE $TF 6000
13311         $TRUNCATE $DIR/$tfile 6000
13312         cancel_lru_locks $OSC
13313         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13314
13315         echo "12345" >>$TF
13316         echo "12345" >>$DIR/$tfile
13317         cancel_lru_locks $OSC
13318         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13319
13320         echo "12345" >>$TF
13321         echo "12345" >>$DIR/$tfile
13322         cancel_lru_locks $OSC
13323         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13324
13325         rm -f $TF
13326         true
13327 }
13328 run_test 150a "truncate/append tests"
13329
13330 test_150b() {
13331         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13332         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13333                 skip "Need OST version at least 2.13.53"
13334         touch $DIR/$tfile
13335         check_fallocate $DIR/$tfile || error "fallocate failed"
13336 }
13337 run_test 150b "Verify fallocate (prealloc) functionality"
13338
13339 test_150c() {
13340         local bytes
13341         local want
13342
13343         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13344         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13345                 skip "Need OST version at least 2.13.53"
13346
13347         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13348         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13349         sync; sync_all_data
13350         cancel_lru_locks $OSC
13351         sleep 5
13352         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13353         want=$((OSTCOUNT * 1048576))
13354
13355         # Must allocate all requested space, not more than 5% extra
13356         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13357                 error "bytes $bytes is not $want"
13358 }
13359 run_test 150c "Verify fallocate Size and Blocks"
13360
13361 test_150d() {
13362         local bytes
13363         local want
13364
13365         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13366         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13367                 skip "Need OST version at least 2.13.53"
13368
13369         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13370         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13371         sync; sync_all_data
13372         cancel_lru_locks $OSC
13373         sleep 5
13374         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13375         want=$((OSTCOUNT * 1048576))
13376
13377         # Must allocate all requested space, not more than 5% extra
13378         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13379                 error "bytes $bytes is not $want"
13380 }
13381 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13382
13383 #LU-2902 roc_hit was not able to read all values from lproc
13384 function roc_hit_init() {
13385         local list=$(comma_list $(osts_nodes))
13386         local dir=$DIR/$tdir-check
13387         local file=$dir/$tfile
13388         local BEFORE
13389         local AFTER
13390         local idx
13391
13392         test_mkdir $dir
13393         #use setstripe to do a write to every ost
13394         for i in $(seq 0 $((OSTCOUNT-1))); do
13395                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13396                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13397                 idx=$(printf %04x $i)
13398                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13399                         awk '$1 == "cache_access" {sum += $7}
13400                                 END { printf("%0.0f", sum) }')
13401
13402                 cancel_lru_locks osc
13403                 cat $file >/dev/null
13404
13405                 AFTER=$(get_osd_param $list *OST*$idx stats |
13406                         awk '$1 == "cache_access" {sum += $7}
13407                                 END { printf("%0.0f", sum) }')
13408
13409                 echo BEFORE:$BEFORE AFTER:$AFTER
13410                 if ! let "AFTER - BEFORE == 4"; then
13411                         rm -rf $dir
13412                         error "roc_hit is not safe to use"
13413                 fi
13414                 rm $file
13415         done
13416
13417         rm -rf $dir
13418 }
13419
13420 function roc_hit() {
13421         local list=$(comma_list $(osts_nodes))
13422         echo $(get_osd_param $list '' stats |
13423                 awk '$1 == "cache_hit" {sum += $7}
13424                         END { printf("%0.0f", sum) }')
13425 }
13426
13427 function set_cache() {
13428         local on=1
13429
13430         if [ "$2" == "off" ]; then
13431                 on=0;
13432         fi
13433         local list=$(comma_list $(osts_nodes))
13434         set_osd_param $list '' $1_cache_enable $on
13435
13436         cancel_lru_locks osc
13437 }
13438
13439 test_151() {
13440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13441         remote_ost_nodsh && skip "remote OST with nodsh"
13442
13443         local CPAGES=3
13444         local list=$(comma_list $(osts_nodes))
13445
13446         # check whether obdfilter is cache capable at all
13447         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13448                 skip "not cache-capable obdfilter"
13449         fi
13450
13451         # check cache is enabled on all obdfilters
13452         if get_osd_param $list '' read_cache_enable | grep 0; then
13453                 skip "oss cache is disabled"
13454         fi
13455
13456         set_osd_param $list '' writethrough_cache_enable 1
13457
13458         # check write cache is enabled on all obdfilters
13459         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13460                 skip "oss write cache is NOT enabled"
13461         fi
13462
13463         roc_hit_init
13464
13465         #define OBD_FAIL_OBD_NO_LRU  0x609
13466         do_nodes $list $LCTL set_param fail_loc=0x609
13467
13468         # pages should be in the case right after write
13469         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13470                 error "dd failed"
13471
13472         local BEFORE=$(roc_hit)
13473         cancel_lru_locks osc
13474         cat $DIR/$tfile >/dev/null
13475         local AFTER=$(roc_hit)
13476
13477         do_nodes $list $LCTL set_param fail_loc=0
13478
13479         if ! let "AFTER - BEFORE == CPAGES"; then
13480                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13481         fi
13482
13483         cancel_lru_locks osc
13484         # invalidates OST cache
13485         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13486         set_osd_param $list '' read_cache_enable 0
13487         cat $DIR/$tfile >/dev/null
13488
13489         # now data shouldn't be found in the cache
13490         BEFORE=$(roc_hit)
13491         cancel_lru_locks osc
13492         cat $DIR/$tfile >/dev/null
13493         AFTER=$(roc_hit)
13494         if let "AFTER - BEFORE != 0"; then
13495                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13496         fi
13497
13498         set_osd_param $list '' read_cache_enable 1
13499         rm -f $DIR/$tfile
13500 }
13501 run_test 151 "test cache on oss and controls ==============================="
13502
13503 test_152() {
13504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13505
13506         local TF="$TMP/$tfile"
13507
13508         # simulate ENOMEM during write
13509 #define OBD_FAIL_OST_NOMEM      0x226
13510         lctl set_param fail_loc=0x80000226
13511         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13512         cp $TF $DIR/$tfile
13513         sync || error "sync failed"
13514         lctl set_param fail_loc=0
13515
13516         # discard client's cache
13517         cancel_lru_locks osc
13518
13519         # simulate ENOMEM during read
13520         lctl set_param fail_loc=0x80000226
13521         cmp $TF $DIR/$tfile || error "cmp failed"
13522         lctl set_param fail_loc=0
13523
13524         rm -f $TF
13525 }
13526 run_test 152 "test read/write with enomem ============================"
13527
13528 test_153() {
13529         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13530 }
13531 run_test 153 "test if fdatasync does not crash ======================="
13532
13533 dot_lustre_fid_permission_check() {
13534         local fid=$1
13535         local ffid=$MOUNT/.lustre/fid/$fid
13536         local test_dir=$2
13537
13538         echo "stat fid $fid"
13539         stat $ffid > /dev/null || error "stat $ffid failed."
13540         echo "touch fid $fid"
13541         touch $ffid || error "touch $ffid failed."
13542         echo "write to fid $fid"
13543         cat /etc/hosts > $ffid || error "write $ffid failed."
13544         echo "read fid $fid"
13545         diff /etc/hosts $ffid || error "read $ffid failed."
13546         echo "append write to fid $fid"
13547         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13548         echo "rename fid $fid"
13549         mv $ffid $test_dir/$tfile.1 &&
13550                 error "rename $ffid to $tfile.1 should fail."
13551         touch $test_dir/$tfile.1
13552         mv $test_dir/$tfile.1 $ffid &&
13553                 error "rename $tfile.1 to $ffid should fail."
13554         rm -f $test_dir/$tfile.1
13555         echo "truncate fid $fid"
13556         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13557         echo "link fid $fid"
13558         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13559         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13560                 echo "setfacl fid $fid"
13561                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13562                 echo "getfacl fid $fid"
13563                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13564         fi
13565         echo "unlink fid $fid"
13566         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13567         echo "mknod fid $fid"
13568         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13569
13570         fid=[0xf00000400:0x1:0x0]
13571         ffid=$MOUNT/.lustre/fid/$fid
13572
13573         echo "stat non-exist fid $fid"
13574         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13575         echo "write to non-exist fid $fid"
13576         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13577         echo "link new fid $fid"
13578         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13579
13580         mkdir -p $test_dir/$tdir
13581         touch $test_dir/$tdir/$tfile
13582         fid=$($LFS path2fid $test_dir/$tdir)
13583         rc=$?
13584         [ $rc -ne 0 ] &&
13585                 error "error: could not get fid for $test_dir/$dir/$tfile."
13586
13587         ffid=$MOUNT/.lustre/fid/$fid
13588
13589         echo "ls $fid"
13590         ls $ffid > /dev/null || error "ls $ffid failed."
13591         echo "touch $fid/$tfile.1"
13592         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13593
13594         echo "touch $MOUNT/.lustre/fid/$tfile"
13595         touch $MOUNT/.lustre/fid/$tfile && \
13596                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13597
13598         echo "setxattr to $MOUNT/.lustre/fid"
13599         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13600
13601         echo "listxattr for $MOUNT/.lustre/fid"
13602         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13603
13604         echo "delxattr from $MOUNT/.lustre/fid"
13605         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13606
13607         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13608         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13609                 error "touch invalid fid should fail."
13610
13611         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13612         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13613                 error "touch non-normal fid should fail."
13614
13615         echo "rename $tdir to $MOUNT/.lustre/fid"
13616         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13617                 error "rename to $MOUNT/.lustre/fid should fail."
13618
13619         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13620         then            # LU-3547
13621                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13622                 local new_obf_mode=777
13623
13624                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13625                 chmod $new_obf_mode $DIR/.lustre/fid ||
13626                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13627
13628                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13629                 [ $obf_mode -eq $new_obf_mode ] ||
13630                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13631
13632                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13633                 chmod $old_obf_mode $DIR/.lustre/fid ||
13634                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13635         fi
13636
13637         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13638         fid=$($LFS path2fid $test_dir/$tfile-2)
13639
13640         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13641         then # LU-5424
13642                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13643                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13644                         error "create lov data thru .lustre failed"
13645         fi
13646         echo "cp /etc/passwd $test_dir/$tfile-2"
13647         cp /etc/passwd $test_dir/$tfile-2 ||
13648                 error "copy to $test_dir/$tfile-2 failed."
13649         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13650         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13651                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13652
13653         rm -rf $test_dir/tfile.lnk
13654         rm -rf $test_dir/$tfile-2
13655 }
13656
13657 test_154A() {
13658         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13659                 skip "Need MDS version at least 2.4.1"
13660
13661         local tf=$DIR/$tfile
13662         touch $tf
13663
13664         local fid=$($LFS path2fid $tf)
13665         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13666
13667         # check that we get the same pathname back
13668         local rootpath
13669         local found
13670         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13671                 echo "$rootpath $fid"
13672                 found=$($LFS fid2path $rootpath "$fid")
13673                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13674                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13675         done
13676
13677         # check wrong root path format
13678         rootpath=$MOUNT"_wrong"
13679         found=$($LFS fid2path $rootpath "$fid")
13680         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13681 }
13682 run_test 154A "lfs path2fid and fid2path basic checks"
13683
13684 test_154B() {
13685         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13686                 skip "Need MDS version at least 2.4.1"
13687
13688         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13689         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13690         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13691         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13692
13693         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13694         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13695
13696         # check that we get the same pathname
13697         echo "PFID: $PFID, name: $name"
13698         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13699         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13700         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13701                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13702
13703         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13704 }
13705 run_test 154B "verify the ll_decode_linkea tool"
13706
13707 test_154a() {
13708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13709         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13710         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13711                 skip "Need MDS version at least 2.2.51"
13712         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13713
13714         cp /etc/hosts $DIR/$tfile
13715
13716         fid=$($LFS path2fid $DIR/$tfile)
13717         rc=$?
13718         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13719
13720         dot_lustre_fid_permission_check "$fid" $DIR ||
13721                 error "dot lustre permission check $fid failed"
13722
13723         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13724
13725         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13726
13727         touch $MOUNT/.lustre/file &&
13728                 error "creation is not allowed under .lustre"
13729
13730         mkdir $MOUNT/.lustre/dir &&
13731                 error "mkdir is not allowed under .lustre"
13732
13733         rm -rf $DIR/$tfile
13734 }
13735 run_test 154a "Open-by-FID"
13736
13737 test_154b() {
13738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13739         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13741         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13742                 skip "Need MDS version at least 2.2.51"
13743
13744         local remote_dir=$DIR/$tdir/remote_dir
13745         local MDTIDX=1
13746         local rc=0
13747
13748         mkdir -p $DIR/$tdir
13749         $LFS mkdir -i $MDTIDX $remote_dir ||
13750                 error "create remote directory failed"
13751
13752         cp /etc/hosts $remote_dir/$tfile
13753
13754         fid=$($LFS path2fid $remote_dir/$tfile)
13755         rc=$?
13756         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13757
13758         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13759                 error "dot lustre permission check $fid failed"
13760         rm -rf $DIR/$tdir
13761 }
13762 run_test 154b "Open-by-FID for remote directory"
13763
13764 test_154c() {
13765         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13766                 skip "Need MDS version at least 2.4.1"
13767
13768         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13769         local FID1=$($LFS path2fid $DIR/$tfile.1)
13770         local FID2=$($LFS path2fid $DIR/$tfile.2)
13771         local FID3=$($LFS path2fid $DIR/$tfile.3)
13772
13773         local N=1
13774         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13775                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13776                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13777                 local want=FID$N
13778                 [ "$FID" = "${!want}" ] ||
13779                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13780                 N=$((N + 1))
13781         done
13782
13783         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13784         do
13785                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13786                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13787                 N=$((N + 1))
13788         done
13789 }
13790 run_test 154c "lfs path2fid and fid2path multiple arguments"
13791
13792 test_154d() {
13793         remote_mds_nodsh && skip "remote MDS with nodsh"
13794         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13795                 skip "Need MDS version at least 2.5.53"
13796
13797         if remote_mds; then
13798                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13799         else
13800                 nid="0@lo"
13801         fi
13802         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13803         local fd
13804         local cmd
13805
13806         rm -f $DIR/$tfile
13807         touch $DIR/$tfile
13808
13809         local fid=$($LFS path2fid $DIR/$tfile)
13810         # Open the file
13811         fd=$(free_fd)
13812         cmd="exec $fd<$DIR/$tfile"
13813         eval $cmd
13814         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13815         echo "$fid_list" | grep "$fid"
13816         rc=$?
13817
13818         cmd="exec $fd>/dev/null"
13819         eval $cmd
13820         if [ $rc -ne 0 ]; then
13821                 error "FID $fid not found in open files list $fid_list"
13822         fi
13823 }
13824 run_test 154d "Verify open file fid"
13825
13826 test_154e()
13827 {
13828         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13829                 skip "Need MDS version at least 2.6.50"
13830
13831         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13832                 error ".lustre returned by readdir"
13833         fi
13834 }
13835 run_test 154e ".lustre is not returned by readdir"
13836
13837 test_154f() {
13838         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13839
13840         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13841         test_mkdir -p -c1 $DIR/$tdir/d
13842         # test dirs inherit from its stripe
13843         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13844         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13845         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13846         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13847         touch $DIR/f
13848
13849         # get fid of parents
13850         local FID0=$($LFS path2fid $DIR/$tdir/d)
13851         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13852         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13853         local FID3=$($LFS path2fid $DIR)
13854
13855         # check that path2fid --parents returns expected <parent_fid>/name
13856         # 1) test for a directory (single parent)
13857         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13858         [ "$parent" == "$FID0/foo1" ] ||
13859                 error "expected parent: $FID0/foo1, got: $parent"
13860
13861         # 2) test for a file with nlink > 1 (multiple parents)
13862         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13863         echo "$parent" | grep -F "$FID1/$tfile" ||
13864                 error "$FID1/$tfile not returned in parent list"
13865         echo "$parent" | grep -F "$FID2/link" ||
13866                 error "$FID2/link not returned in parent list"
13867
13868         # 3) get parent by fid
13869         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13870         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13871         echo "$parent" | grep -F "$FID1/$tfile" ||
13872                 error "$FID1/$tfile not returned in parent list (by fid)"
13873         echo "$parent" | grep -F "$FID2/link" ||
13874                 error "$FID2/link not returned in parent list (by fid)"
13875
13876         # 4) test for entry in root directory
13877         parent=$($LFS path2fid --parents $DIR/f)
13878         echo "$parent" | grep -F "$FID3/f" ||
13879                 error "$FID3/f not returned in parent list"
13880
13881         # 5) test it on root directory
13882         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13883                 error "$MOUNT should not have parents"
13884
13885         # enable xattr caching and check that linkea is correctly updated
13886         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13887         save_lustre_params client "llite.*.xattr_cache" > $save
13888         lctl set_param llite.*.xattr_cache 1
13889
13890         # 6.1) linkea update on rename
13891         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13892
13893         # get parents by fid
13894         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13895         # foo1 should no longer be returned in parent list
13896         echo "$parent" | grep -F "$FID1" &&
13897                 error "$FID1 should no longer be in parent list"
13898         # the new path should appear
13899         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13900                 error "$FID2/$tfile.moved is not in parent list"
13901
13902         # 6.2) linkea update on unlink
13903         rm -f $DIR/$tdir/d/foo2/link
13904         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13905         # foo2/link should no longer be returned in parent list
13906         echo "$parent" | grep -F "$FID2/link" &&
13907                 error "$FID2/link should no longer be in parent list"
13908         true
13909
13910         rm -f $DIR/f
13911         restore_lustre_params < $save
13912         rm -f $save
13913 }
13914 run_test 154f "get parent fids by reading link ea"
13915
13916 test_154g()
13917 {
13918         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13919         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13920            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13921                 skip "Need MDS version at least 2.6.92"
13922
13923         mkdir -p $DIR/$tdir
13924         llapi_fid_test -d $DIR/$tdir
13925 }
13926 run_test 154g "various llapi FID tests"
13927
13928 test_155_small_load() {
13929     local temp=$TMP/$tfile
13930     local file=$DIR/$tfile
13931
13932     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13933         error "dd of=$temp bs=6096 count=1 failed"
13934     cp $temp $file
13935     cancel_lru_locks $OSC
13936     cmp $temp $file || error "$temp $file differ"
13937
13938     $TRUNCATE $temp 6000
13939     $TRUNCATE $file 6000
13940     cmp $temp $file || error "$temp $file differ (truncate1)"
13941
13942     echo "12345" >>$temp
13943     echo "12345" >>$file
13944     cmp $temp $file || error "$temp $file differ (append1)"
13945
13946     echo "12345" >>$temp
13947     echo "12345" >>$file
13948     cmp $temp $file || error "$temp $file differ (append2)"
13949
13950     rm -f $temp $file
13951     true
13952 }
13953
13954 test_155_big_load() {
13955         remote_ost_nodsh && skip "remote OST with nodsh"
13956
13957         local temp=$TMP/$tfile
13958         local file=$DIR/$tfile
13959
13960         free_min_max
13961         local cache_size=$(do_facet ost$((MAXI+1)) \
13962                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13963         local large_file_size=$((cache_size * 2))
13964
13965         echo "OSS cache size: $cache_size KB"
13966         echo "Large file size: $large_file_size KB"
13967
13968         [ $MAXV -le $large_file_size ] &&
13969                 skip_env "max available OST size needs > $large_file_size KB"
13970
13971         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13972
13973         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13974                 error "dd of=$temp bs=$large_file_size count=1k failed"
13975         cp $temp $file
13976         ls -lh $temp $file
13977         cancel_lru_locks osc
13978         cmp $temp $file || error "$temp $file differ"
13979
13980         rm -f $temp $file
13981         true
13982 }
13983
13984 save_writethrough() {
13985         local facets=$(get_facets OST)
13986
13987         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13988 }
13989
13990 test_155a() {
13991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13992
13993         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13994
13995         save_writethrough $p
13996
13997         set_cache read on
13998         set_cache writethrough on
13999         test_155_small_load
14000         restore_lustre_params < $p
14001         rm -f $p
14002 }
14003 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14004
14005 test_155b() {
14006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14007
14008         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14009
14010         save_writethrough $p
14011
14012         set_cache read on
14013         set_cache writethrough off
14014         test_155_small_load
14015         restore_lustre_params < $p
14016         rm -f $p
14017 }
14018 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14019
14020 test_155c() {
14021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14022
14023         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14024
14025         save_writethrough $p
14026
14027         set_cache read off
14028         set_cache writethrough on
14029         test_155_small_load
14030         restore_lustre_params < $p
14031         rm -f $p
14032 }
14033 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14034
14035 test_155d() {
14036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14037
14038         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14039
14040         save_writethrough $p
14041
14042         set_cache read off
14043         set_cache writethrough off
14044         test_155_small_load
14045         restore_lustre_params < $p
14046         rm -f $p
14047 }
14048 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14049
14050 test_155e() {
14051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14052
14053         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14054
14055         save_writethrough $p
14056
14057         set_cache read on
14058         set_cache writethrough on
14059         test_155_big_load
14060         restore_lustre_params < $p
14061         rm -f $p
14062 }
14063 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14064
14065 test_155f() {
14066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14067
14068         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14069
14070         save_writethrough $p
14071
14072         set_cache read on
14073         set_cache writethrough off
14074         test_155_big_load
14075         restore_lustre_params < $p
14076         rm -f $p
14077 }
14078 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14079
14080 test_155g() {
14081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14082
14083         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14084
14085         save_writethrough $p
14086
14087         set_cache read off
14088         set_cache writethrough on
14089         test_155_big_load
14090         restore_lustre_params < $p
14091         rm -f $p
14092 }
14093 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14094
14095 test_155h() {
14096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14097
14098         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14099
14100         save_writethrough $p
14101
14102         set_cache read off
14103         set_cache writethrough off
14104         test_155_big_load
14105         restore_lustre_params < $p
14106         rm -f $p
14107 }
14108 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14109
14110 test_156() {
14111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14112         remote_ost_nodsh && skip "remote OST with nodsh"
14113         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14114                 skip "stats not implemented on old servers"
14115         [ "$ost1_FSTYPE" = "zfs" ] &&
14116                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14117
14118         local CPAGES=3
14119         local BEFORE
14120         local AFTER
14121         local file="$DIR/$tfile"
14122         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14123
14124         save_writethrough $p
14125         roc_hit_init
14126
14127         log "Turn on read and write cache"
14128         set_cache read on
14129         set_cache writethrough on
14130
14131         log "Write data and read it back."
14132         log "Read should be satisfied from the cache."
14133         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14134         BEFORE=$(roc_hit)
14135         cancel_lru_locks osc
14136         cat $file >/dev/null
14137         AFTER=$(roc_hit)
14138         if ! let "AFTER - BEFORE == CPAGES"; then
14139                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14140         else
14141                 log "cache hits: before: $BEFORE, after: $AFTER"
14142         fi
14143
14144         log "Read again; it should be satisfied from the cache."
14145         BEFORE=$AFTER
14146         cancel_lru_locks osc
14147         cat $file >/dev/null
14148         AFTER=$(roc_hit)
14149         if ! let "AFTER - BEFORE == CPAGES"; then
14150                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14151         else
14152                 log "cache hits:: before: $BEFORE, after: $AFTER"
14153         fi
14154
14155         log "Turn off the read cache and turn on the write cache"
14156         set_cache read off
14157         set_cache writethrough on
14158
14159         log "Read again; it should be satisfied from the cache."
14160         BEFORE=$(roc_hit)
14161         cancel_lru_locks osc
14162         cat $file >/dev/null
14163         AFTER=$(roc_hit)
14164         if ! let "AFTER - BEFORE == CPAGES"; then
14165                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14166         else
14167                 log "cache hits:: before: $BEFORE, after: $AFTER"
14168         fi
14169
14170         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14171                 # > 2.12.56 uses pagecache if cached
14172                 log "Read again; it should not be satisfied from the cache."
14173                 BEFORE=$AFTER
14174                 cancel_lru_locks osc
14175                 cat $file >/dev/null
14176                 AFTER=$(roc_hit)
14177                 if ! let "AFTER - BEFORE == 0"; then
14178                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14179                 else
14180                         log "cache hits:: before: $BEFORE, after: $AFTER"
14181                 fi
14182         fi
14183
14184         log "Write data and read it back."
14185         log "Read should be satisfied from the cache."
14186         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14187         BEFORE=$(roc_hit)
14188         cancel_lru_locks osc
14189         cat $file >/dev/null
14190         AFTER=$(roc_hit)
14191         if ! let "AFTER - BEFORE == CPAGES"; then
14192                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14193         else
14194                 log "cache hits:: before: $BEFORE, after: $AFTER"
14195         fi
14196
14197         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14198                 # > 2.12.56 uses pagecache if cached
14199                 log "Read again; it should not be satisfied from the cache."
14200                 BEFORE=$AFTER
14201                 cancel_lru_locks osc
14202                 cat $file >/dev/null
14203                 AFTER=$(roc_hit)
14204                 if ! let "AFTER - BEFORE == 0"; then
14205                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14206                 else
14207                         log "cache hits:: before: $BEFORE, after: $AFTER"
14208                 fi
14209         fi
14210
14211         log "Turn off read and write cache"
14212         set_cache read off
14213         set_cache writethrough off
14214
14215         log "Write data and read it back"
14216         log "It should not be satisfied from the cache."
14217         rm -f $file
14218         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14219         cancel_lru_locks osc
14220         BEFORE=$(roc_hit)
14221         cat $file >/dev/null
14222         AFTER=$(roc_hit)
14223         if ! let "AFTER - BEFORE == 0"; then
14224                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14225         else
14226                 log "cache hits:: before: $BEFORE, after: $AFTER"
14227         fi
14228
14229         log "Turn on the read cache and turn off the write cache"
14230         set_cache read on
14231         set_cache writethrough off
14232
14233         log "Write data and read it back"
14234         log "It should not be satisfied from the cache."
14235         rm -f $file
14236         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14237         BEFORE=$(roc_hit)
14238         cancel_lru_locks osc
14239         cat $file >/dev/null
14240         AFTER=$(roc_hit)
14241         if ! let "AFTER - BEFORE == 0"; then
14242                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14243         else
14244                 log "cache hits:: before: $BEFORE, after: $AFTER"
14245         fi
14246
14247         log "Read again; it should be satisfied from the cache."
14248         BEFORE=$(roc_hit)
14249         cancel_lru_locks osc
14250         cat $file >/dev/null
14251         AFTER=$(roc_hit)
14252         if ! let "AFTER - BEFORE == CPAGES"; then
14253                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14254         else
14255                 log "cache hits:: before: $BEFORE, after: $AFTER"
14256         fi
14257
14258         restore_lustre_params < $p
14259         rm -f $p $file
14260 }
14261 run_test 156 "Verification of tunables"
14262
14263 test_160a() {
14264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14265         remote_mds_nodsh && skip "remote MDS with nodsh"
14266         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14267                 skip "Need MDS version at least 2.2.0"
14268
14269         changelog_register || error "changelog_register failed"
14270         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14271         changelog_users $SINGLEMDS | grep -q $cl_user ||
14272                 error "User $cl_user not found in changelog_users"
14273
14274         # change something
14275         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14276         changelog_clear 0 || error "changelog_clear failed"
14277         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14278         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14279         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14280         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14281         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14282         rm $DIR/$tdir/pics/desktop.jpg
14283
14284         changelog_dump | tail -10
14285
14286         echo "verifying changelog mask"
14287         changelog_chmask "-MKDIR"
14288         changelog_chmask "-CLOSE"
14289
14290         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14291         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14292
14293         changelog_chmask "+MKDIR"
14294         changelog_chmask "+CLOSE"
14295
14296         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14297         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14298
14299         changelog_dump | tail -10
14300         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14301         CLOSES=$(changelog_dump | grep -c "CLOSE")
14302         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14303         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14304
14305         # verify contents
14306         echo "verifying target fid"
14307         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14308         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14309         [ "$fidc" == "$fidf" ] ||
14310                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14311         echo "verifying parent fid"
14312         # The FID returned from the Changelog may be the directory shard on
14313         # a different MDT, and not the FID returned by path2fid on the parent.
14314         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14315         # since this is what will matter when recreating this file in the tree.
14316         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14317         local pathp=$($LFS fid2path $MOUNT "$fidp")
14318         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14319                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14320
14321         echo "getting records for $cl_user"
14322         changelog_users $SINGLEMDS
14323         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14324         local nclr=3
14325         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14326                 error "changelog_clear failed"
14327         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14328         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14329         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14330                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14331
14332         local min0_rec=$(changelog_users $SINGLEMDS |
14333                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14334         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14335                           awk '{ print $1; exit; }')
14336
14337         changelog_dump | tail -n 5
14338         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14339         [ $first_rec == $((min0_rec + 1)) ] ||
14340                 error "first index should be $min0_rec + 1 not $first_rec"
14341
14342         # LU-3446 changelog index reset on MDT restart
14343         local cur_rec1=$(changelog_users $SINGLEMDS |
14344                          awk '/^current.index:/ { print $NF }')
14345         changelog_clear 0 ||
14346                 error "clear all changelog records for $cl_user failed"
14347         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14348         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14349                 error "Fail to start $SINGLEMDS"
14350         local cur_rec2=$(changelog_users $SINGLEMDS |
14351                          awk '/^current.index:/ { print $NF }')
14352         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14353         [ $cur_rec1 == $cur_rec2 ] ||
14354                 error "current index should be $cur_rec1 not $cur_rec2"
14355
14356         echo "verifying users from this test are deregistered"
14357         changelog_deregister || error "changelog_deregister failed"
14358         changelog_users $SINGLEMDS | grep -q $cl_user &&
14359                 error "User '$cl_user' still in changelog_users"
14360
14361         # lctl get_param -n mdd.*.changelog_users
14362         # current index: 144
14363         # ID    index (idle seconds)
14364         # cl3   144 (2)
14365         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14366                 # this is the normal case where all users were deregistered
14367                 # make sure no new records are added when no users are present
14368                 local last_rec1=$(changelog_users $SINGLEMDS |
14369                                   awk '/^current.index:/ { print $NF }')
14370                 touch $DIR/$tdir/chloe
14371                 local last_rec2=$(changelog_users $SINGLEMDS |
14372                                   awk '/^current.index:/ { print $NF }')
14373                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14374                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14375         else
14376                 # any changelog users must be leftovers from a previous test
14377                 changelog_users $SINGLEMDS
14378                 echo "other changelog users; can't verify off"
14379         fi
14380 }
14381 run_test 160a "changelog sanity"
14382
14383 test_160b() { # LU-3587
14384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14385         remote_mds_nodsh && skip "remote MDS with nodsh"
14386         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14387                 skip "Need MDS version at least 2.2.0"
14388
14389         changelog_register || error "changelog_register failed"
14390         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14391         changelog_users $SINGLEMDS | grep -q $cl_user ||
14392                 error "User '$cl_user' not found in changelog_users"
14393
14394         local longname1=$(str_repeat a 255)
14395         local longname2=$(str_repeat b 255)
14396
14397         cd $DIR
14398         echo "creating very long named file"
14399         touch $longname1 || error "create of '$longname1' failed"
14400         echo "renaming very long named file"
14401         mv $longname1 $longname2
14402
14403         changelog_dump | grep RENME | tail -n 5
14404         rm -f $longname2
14405 }
14406 run_test 160b "Verify that very long rename doesn't crash in changelog"
14407
14408 test_160c() {
14409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14410         remote_mds_nodsh && skip "remote MDS with nodsh"
14411
14412         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14413                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14414                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14415                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14416
14417         local rc=0
14418
14419         # Registration step
14420         changelog_register || error "changelog_register failed"
14421
14422         rm -rf $DIR/$tdir
14423         mkdir -p $DIR/$tdir
14424         $MCREATE $DIR/$tdir/foo_160c
14425         changelog_chmask "-TRUNC"
14426         $TRUNCATE $DIR/$tdir/foo_160c 200
14427         changelog_chmask "+TRUNC"
14428         $TRUNCATE $DIR/$tdir/foo_160c 199
14429         changelog_dump | tail -n 5
14430         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14431         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14432 }
14433 run_test 160c "verify that changelog log catch the truncate event"
14434
14435 test_160d() {
14436         remote_mds_nodsh && skip "remote MDS with nodsh"
14437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14439         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14440                 skip "Need MDS version at least 2.7.60"
14441
14442         # Registration step
14443         changelog_register || error "changelog_register failed"
14444
14445         mkdir -p $DIR/$tdir/migrate_dir
14446         changelog_clear 0 || error "changelog_clear failed"
14447
14448         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14449         changelog_dump | tail -n 5
14450         local migrates=$(changelog_dump | grep -c "MIGRT")
14451         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14452 }
14453 run_test 160d "verify that changelog log catch the migrate event"
14454
14455 test_160e() {
14456         remote_mds_nodsh && skip "remote MDS with nodsh"
14457
14458         # Create a user
14459         changelog_register || error "changelog_register failed"
14460
14461         # Delete a future user (expect fail)
14462         local MDT0=$(facet_svc $SINGLEMDS)
14463         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14464         local rc=$?
14465
14466         if [ $rc -eq 0 ]; then
14467                 error "Deleted non-existant user cl77"
14468         elif [ $rc -ne 2 ]; then
14469                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14470         fi
14471
14472         # Clear to a bad index (1 billion should be safe)
14473         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14474         rc=$?
14475
14476         if [ $rc -eq 0 ]; then
14477                 error "Successfully cleared to invalid CL index"
14478         elif [ $rc -ne 22 ]; then
14479                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14480         fi
14481 }
14482 run_test 160e "changelog negative testing (should return errors)"
14483
14484 test_160f() {
14485         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14486         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14487                 skip "Need MDS version at least 2.10.56"
14488
14489         local mdts=$(comma_list $(mdts_nodes))
14490
14491         # Create a user
14492         changelog_register || error "first changelog_register failed"
14493         changelog_register || error "second changelog_register failed"
14494         local cl_users
14495         declare -A cl_user1
14496         declare -A cl_user2
14497         local user_rec1
14498         local user_rec2
14499         local i
14500
14501         # generate some changelog records to accumulate on each MDT
14502         # use fnv1a because created files should be evenly distributed
14503         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14504                 error "test_mkdir $tdir failed"
14505         log "$(date +%s): creating first files"
14506         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14507                 error "create $DIR/$tdir/$tfile failed"
14508
14509         # check changelogs have been generated
14510         local start=$SECONDS
14511         local idle_time=$((MDSCOUNT * 5 + 5))
14512         local nbcl=$(changelog_dump | wc -l)
14513         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14514
14515         for param in "changelog_max_idle_time=$idle_time" \
14516                      "changelog_gc=1" \
14517                      "changelog_min_gc_interval=2" \
14518                      "changelog_min_free_cat_entries=3"; do
14519                 local MDT0=$(facet_svc $SINGLEMDS)
14520                 local var="${param%=*}"
14521                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14522
14523                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14524                 do_nodes $mdts $LCTL set_param mdd.*.$param
14525         done
14526
14527         # force cl_user2 to be idle (1st part), but also cancel the
14528         # cl_user1 records so that it is not evicted later in the test.
14529         local sleep1=$((idle_time / 2))
14530         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14531         sleep $sleep1
14532
14533         # simulate changelog catalog almost full
14534         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14535         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14536
14537         for i in $(seq $MDSCOUNT); do
14538                 cl_users=(${CL_USERS[mds$i]})
14539                 cl_user1[mds$i]="${cl_users[0]}"
14540                 cl_user2[mds$i]="${cl_users[1]}"
14541
14542                 [ -n "${cl_user1[mds$i]}" ] ||
14543                         error "mds$i: no user registered"
14544                 [ -n "${cl_user2[mds$i]}" ] ||
14545                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14546
14547                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14548                 [ -n "$user_rec1" ] ||
14549                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14550                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14551                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14552                 [ -n "$user_rec2" ] ||
14553                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14554                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14555                      "$user_rec1 + 2 == $user_rec2"
14556                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14557                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14558                               "$user_rec1 + 2, but is $user_rec2"
14559                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14560                 [ -n "$user_rec2" ] ||
14561                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14562                 [ $user_rec1 == $user_rec2 ] ||
14563                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14564                               "$user_rec1, but is $user_rec2"
14565         done
14566
14567         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14568         local sleep2=$((idle_time - (SECONDS - start) + 1))
14569         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14570         sleep $sleep2
14571
14572         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14573         # cl_user1 should be OK because it recently processed records.
14574         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14575         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14576                 error "create $DIR/$tdir/${tfile}b failed"
14577
14578         # ensure gc thread is done
14579         for i in $(mdts_nodes); do
14580                 wait_update $i \
14581                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14582                         error "$i: GC-thread not done"
14583         done
14584
14585         local first_rec
14586         for i in $(seq $MDSCOUNT); do
14587                 # check cl_user1 still registered
14588                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14589                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14590                 # check cl_user2 unregistered
14591                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14592                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14593
14594                 # check changelogs are present and starting at $user_rec1 + 1
14595                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14596                 [ -n "$user_rec1" ] ||
14597                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14598                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14599                             awk '{ print $1; exit; }')
14600
14601                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14602                 [ $((user_rec1 + 1)) == $first_rec ] ||
14603                         error "mds$i: first index should be $user_rec1 + 1, " \
14604                               "but is $first_rec"
14605         done
14606 }
14607 run_test 160f "changelog garbage collect (timestamped users)"
14608
14609 test_160g() {
14610         remote_mds_nodsh && skip "remote MDS with nodsh"
14611         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14612                 skip "Need MDS version at least 2.10.56"
14613
14614         local mdts=$(comma_list $(mdts_nodes))
14615
14616         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14617         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14618
14619         # Create a user
14620         changelog_register || error "first changelog_register failed"
14621         changelog_register || error "second changelog_register failed"
14622         local cl_users
14623         declare -A cl_user1
14624         declare -A cl_user2
14625         local user_rec1
14626         local user_rec2
14627         local i
14628
14629         # generate some changelog records to accumulate on each MDT
14630         # use fnv1a because created files should be evenly distributed
14631         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14632                 error "mkdir $tdir failed"
14633         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14634                 error "create $DIR/$tdir/$tfile failed"
14635
14636         # check changelogs have been generated
14637         local nbcl=$(changelog_dump | wc -l)
14638         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14639
14640         # reduce the max_idle_indexes value to make sure we exceed it
14641         max_ndx=$((nbcl / 2 - 1))
14642
14643         for param in "changelog_max_idle_indexes=$max_ndx" \
14644                      "changelog_gc=1" \
14645                      "changelog_min_gc_interval=2" \
14646                      "changelog_min_free_cat_entries=3"; do
14647                 local MDT0=$(facet_svc $SINGLEMDS)
14648                 local var="${param%=*}"
14649                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14650
14651                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14652                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14653                         error "unable to set mdd.*.$param"
14654         done
14655
14656         # simulate changelog catalog almost full
14657         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14658         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14659
14660         for i in $(seq $MDSCOUNT); do
14661                 cl_users=(${CL_USERS[mds$i]})
14662                 cl_user1[mds$i]="${cl_users[0]}"
14663                 cl_user2[mds$i]="${cl_users[1]}"
14664
14665                 [ -n "${cl_user1[mds$i]}" ] ||
14666                         error "mds$i: no user registered"
14667                 [ -n "${cl_user2[mds$i]}" ] ||
14668                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14669
14670                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14671                 [ -n "$user_rec1" ] ||
14672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14673                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14674                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14675                 [ -n "$user_rec2" ] ||
14676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14677                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14678                      "$user_rec1 + 2 == $user_rec2"
14679                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14680                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14681                               "$user_rec1 + 2, but is $user_rec2"
14682                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14683                 [ -n "$user_rec2" ] ||
14684                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14685                 [ $user_rec1 == $user_rec2 ] ||
14686                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14687                               "$user_rec1, but is $user_rec2"
14688         done
14689
14690         # ensure we are past the previous changelog_min_gc_interval set above
14691         sleep 2
14692
14693         # generate one more changelog to trigger fail_loc
14694         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14695                 error "create $DIR/$tdir/${tfile}bis failed"
14696
14697         # ensure gc thread is done
14698         for i in $(mdts_nodes); do
14699                 wait_update $i \
14700                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14701                         error "$i: GC-thread not done"
14702         done
14703
14704         local first_rec
14705         for i in $(seq $MDSCOUNT); do
14706                 # check cl_user1 still registered
14707                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14708                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14709                 # check cl_user2 unregistered
14710                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14711                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14712
14713                 # check changelogs are present and starting at $user_rec1 + 1
14714                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14715                 [ -n "$user_rec1" ] ||
14716                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14717                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14718                             awk '{ print $1; exit; }')
14719
14720                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14721                 [ $((user_rec1 + 1)) == $first_rec ] ||
14722                         error "mds$i: first index should be $user_rec1 + 1, " \
14723                               "but is $first_rec"
14724         done
14725 }
14726 run_test 160g "changelog garbage collect (old users)"
14727
14728 test_160h() {
14729         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14730         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14731                 skip "Need MDS version at least 2.10.56"
14732
14733         local mdts=$(comma_list $(mdts_nodes))
14734
14735         # Create a user
14736         changelog_register || error "first changelog_register failed"
14737         changelog_register || error "second changelog_register failed"
14738         local cl_users
14739         declare -A cl_user1
14740         declare -A cl_user2
14741         local user_rec1
14742         local user_rec2
14743         local i
14744
14745         # generate some changelog records to accumulate on each MDT
14746         # use fnv1a because created files should be evenly distributed
14747         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14748                 error "test_mkdir $tdir failed"
14749         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14750                 error "create $DIR/$tdir/$tfile failed"
14751
14752         # check changelogs have been generated
14753         local nbcl=$(changelog_dump | wc -l)
14754         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14755
14756         for param in "changelog_max_idle_time=10" \
14757                      "changelog_gc=1" \
14758                      "changelog_min_gc_interval=2"; do
14759                 local MDT0=$(facet_svc $SINGLEMDS)
14760                 local var="${param%=*}"
14761                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14762
14763                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14764                 do_nodes $mdts $LCTL set_param mdd.*.$param
14765         done
14766
14767         # force cl_user2 to be idle (1st part)
14768         sleep 9
14769
14770         for i in $(seq $MDSCOUNT); do
14771                 cl_users=(${CL_USERS[mds$i]})
14772                 cl_user1[mds$i]="${cl_users[0]}"
14773                 cl_user2[mds$i]="${cl_users[1]}"
14774
14775                 [ -n "${cl_user1[mds$i]}" ] ||
14776                         error "mds$i: no user registered"
14777                 [ -n "${cl_user2[mds$i]}" ] ||
14778                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14779
14780                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14781                 [ -n "$user_rec1" ] ||
14782                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14783                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14784                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14785                 [ -n "$user_rec2" ] ||
14786                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14787                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14788                      "$user_rec1 + 2 == $user_rec2"
14789                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14790                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14791                               "$user_rec1 + 2, but is $user_rec2"
14792                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14793                 [ -n "$user_rec2" ] ||
14794                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14795                 [ $user_rec1 == $user_rec2 ] ||
14796                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14797                               "$user_rec1, but is $user_rec2"
14798         done
14799
14800         # force cl_user2 to be idle (2nd part) and to reach
14801         # changelog_max_idle_time
14802         sleep 2
14803
14804         # force each GC-thread start and block then
14805         # one per MDT/MDD, set fail_val accordingly
14806         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14807         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14808
14809         # generate more changelogs to trigger fail_loc
14810         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14811                 error "create $DIR/$tdir/${tfile}bis failed"
14812
14813         # stop MDT to stop GC-thread, should be done in back-ground as it will
14814         # block waiting for the thread to be released and exit
14815         declare -A stop_pids
14816         for i in $(seq $MDSCOUNT); do
14817                 stop mds$i &
14818                 stop_pids[mds$i]=$!
14819         done
14820
14821         for i in $(mdts_nodes); do
14822                 local facet
14823                 local nb=0
14824                 local facets=$(facets_up_on_host $i)
14825
14826                 for facet in ${facets//,/ }; do
14827                         if [[ $facet == mds* ]]; then
14828                                 nb=$((nb + 1))
14829                         fi
14830                 done
14831                 # ensure each MDS's gc threads are still present and all in "R"
14832                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14833                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14834                         error "$i: expected $nb GC-thread"
14835                 wait_update $i \
14836                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14837                         "R" 20 ||
14838                         error "$i: GC-thread not found in R-state"
14839                 # check umounts of each MDT on MDS have reached kthread_stop()
14840                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14841                         error "$i: expected $nb umount"
14842                 wait_update $i \
14843                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14844                         error "$i: umount not found in D-state"
14845         done
14846
14847         # release all GC-threads
14848         do_nodes $mdts $LCTL set_param fail_loc=0
14849
14850         # wait for MDT stop to complete
14851         for i in $(seq $MDSCOUNT); do
14852                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14853         done
14854
14855         # XXX
14856         # may try to check if any orphan changelog records are present
14857         # via ldiskfs/zfs and llog_reader...
14858
14859         # re-start/mount MDTs
14860         for i in $(seq $MDSCOUNT); do
14861                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14862                         error "Fail to start mds$i"
14863         done
14864
14865         local first_rec
14866         for i in $(seq $MDSCOUNT); do
14867                 # check cl_user1 still registered
14868                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14869                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14870                 # check cl_user2 unregistered
14871                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14872                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14873
14874                 # check changelogs are present and starting at $user_rec1 + 1
14875                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14876                 [ -n "$user_rec1" ] ||
14877                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14878                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14879                             awk '{ print $1; exit; }')
14880
14881                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14882                 [ $((user_rec1 + 1)) == $first_rec ] ||
14883                         error "mds$i: first index should be $user_rec1 + 1, " \
14884                               "but is $first_rec"
14885         done
14886 }
14887 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14888               "during mount"
14889
14890 test_160i() {
14891
14892         local mdts=$(comma_list $(mdts_nodes))
14893
14894         changelog_register || error "first changelog_register failed"
14895
14896         # generate some changelog records to accumulate on each MDT
14897         # use fnv1a because created files should be evenly distributed
14898         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14899                 error "mkdir $tdir failed"
14900         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14901                 error "create $DIR/$tdir/$tfile failed"
14902
14903         # check changelogs have been generated
14904         local nbcl=$(changelog_dump | wc -l)
14905         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14906
14907         # simulate race between register and unregister
14908         # XXX as fail_loc is set per-MDS, with DNE configs the race
14909         # simulation will only occur for one MDT per MDS and for the
14910         # others the normal race scenario will take place
14911         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14912         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14913         do_nodes $mdts $LCTL set_param fail_val=1
14914
14915         # unregister 1st user
14916         changelog_deregister &
14917         local pid1=$!
14918         # wait some time for deregister work to reach race rdv
14919         sleep 2
14920         # register 2nd user
14921         changelog_register || error "2nd user register failed"
14922
14923         wait $pid1 || error "1st user deregister failed"
14924
14925         local i
14926         local last_rec
14927         declare -A LAST_REC
14928         for i in $(seq $MDSCOUNT); do
14929                 if changelog_users mds$i | grep "^cl"; then
14930                         # make sure new records are added with one user present
14931                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14932                                           awk '/^current.index:/ { print $NF }')
14933                 else
14934                         error "mds$i has no user registered"
14935                 fi
14936         done
14937
14938         # generate more changelog records to accumulate on each MDT
14939         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14940                 error "create $DIR/$tdir/${tfile}bis failed"
14941
14942         for i in $(seq $MDSCOUNT); do
14943                 last_rec=$(changelog_users $SINGLEMDS |
14944                            awk '/^current.index:/ { print $NF }')
14945                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14946                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14947                         error "changelogs are off on mds$i"
14948         done
14949 }
14950 run_test 160i "changelog user register/unregister race"
14951
14952 test_160j() {
14953         remote_mds_nodsh && skip "remote MDS with nodsh"
14954         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14955                 skip "Need MDS version at least 2.12.56"
14956
14957         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14958         stack_trap "umount $MOUNT2" EXIT
14959
14960         changelog_register || error "first changelog_register failed"
14961         stack_trap "changelog_deregister" EXIT
14962
14963         # generate some changelog
14964         # use fnv1a because created files should be evenly distributed
14965         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14966                 error "mkdir $tdir failed"
14967         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14968                 error "create $DIR/$tdir/${tfile}bis failed"
14969
14970         # open the changelog device
14971         exec 3>/dev/changelog-$FSNAME-MDT0000
14972         stack_trap "exec 3>&-" EXIT
14973         exec 4</dev/changelog-$FSNAME-MDT0000
14974         stack_trap "exec 4<&-" EXIT
14975
14976         # umount the first lustre mount
14977         umount $MOUNT
14978         stack_trap "mount_client $MOUNT" EXIT
14979
14980         # read changelog
14981         cat <&4 >/dev/null || error "read changelog failed"
14982
14983         # clear changelog
14984         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14985         changelog_users $SINGLEMDS | grep -q $cl_user ||
14986                 error "User $cl_user not found in changelog_users"
14987
14988         printf 'clear:'$cl_user':0' >&3
14989 }
14990 run_test 160j "client can be umounted  while its chanangelog is being used"
14991
14992 test_160k() {
14993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14994         remote_mds_nodsh && skip "remote MDS with nodsh"
14995
14996         mkdir -p $DIR/$tdir/1/1
14997
14998         changelog_register || error "changelog_register failed"
14999         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15000
15001         changelog_users $SINGLEMDS | grep -q $cl_user ||
15002                 error "User '$cl_user' not found in changelog_users"
15003 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15004         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15005         rmdir $DIR/$tdir/1/1 & sleep 1
15006         mkdir $DIR/$tdir/2
15007         touch $DIR/$tdir/2/2
15008         rm -rf $DIR/$tdir/2
15009
15010         wait
15011         sleep 4
15012
15013         changelog_dump | grep rmdir || error "rmdir not recorded"
15014
15015         rm -rf $DIR/$tdir
15016         changelog_deregister
15017 }
15018 run_test 160k "Verify that changelog records are not lost"
15019
15020 # Verifies that a file passed as a parameter has recently had an operation
15021 # performed on it that has generated an MTIME changelog which contains the
15022 # correct parent FID. As files might reside on a different MDT from the
15023 # parent directory in DNE configurations, the FIDs are translated to paths
15024 # before being compared, which should be identical
15025 compare_mtime_changelog() {
15026         local file="${1}"
15027         local mdtidx
15028         local mtime
15029         local cl_fid
15030         local pdir
15031         local dir
15032
15033         mdtidx=$($LFS getstripe --mdt-index $file)
15034         mdtidx=$(printf "%04x" $mdtidx)
15035
15036         # Obtain the parent FID from the MTIME changelog
15037         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15038         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15039
15040         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15041         [ -z "$cl_fid" ] && error "parent FID not present"
15042
15043         # Verify that the path for the parent FID is the same as the path for
15044         # the test directory
15045         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15046
15047         dir=$(dirname $1)
15048
15049         [[ "${pdir%/}" == "$dir" ]] ||
15050                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15051 }
15052
15053 test_160l() {
15054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15055
15056         remote_mds_nodsh && skip "remote MDS with nodsh"
15057         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15058                 skip "Need MDS version at least 2.13.55"
15059
15060         local cl_user
15061
15062         changelog_register || error "changelog_register failed"
15063         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15064
15065         changelog_users $SINGLEMDS | grep -q $cl_user ||
15066                 error "User '$cl_user' not found in changelog_users"
15067
15068         # Clear some types so that MTIME changelogs are generated
15069         changelog_chmask "-CREAT"
15070         changelog_chmask "-CLOSE"
15071
15072         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15073
15074         # Test CL_MTIME during setattr
15075         touch $DIR/$tdir/$tfile
15076         compare_mtime_changelog $DIR/$tdir/$tfile
15077
15078         # Test CL_MTIME during close
15079         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15080                 error "cannot create file $DIR/$tdir/${tfile}_2"
15081         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15082 }
15083 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15084
15085 test_161a() {
15086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15087
15088         test_mkdir -c1 $DIR/$tdir
15089         cp /etc/hosts $DIR/$tdir/$tfile
15090         test_mkdir -c1 $DIR/$tdir/foo1
15091         test_mkdir -c1 $DIR/$tdir/foo2
15092         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15093         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15094         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15095         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15096         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15097         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15098                 $LFS fid2path $DIR $FID
15099                 error "bad link ea"
15100         fi
15101         # middle
15102         rm $DIR/$tdir/foo2/zachary
15103         # last
15104         rm $DIR/$tdir/foo2/thor
15105         # first
15106         rm $DIR/$tdir/$tfile
15107         # rename
15108         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15109         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15110                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15111         rm $DIR/$tdir/foo2/maggie
15112
15113         # overflow the EA
15114         local longname=$tfile.avg_len_is_thirty_two_
15115         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15116                 error_noexit 'failed to unlink many hardlinks'" EXIT
15117         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15118                 error "failed to hardlink many files"
15119         links=$($LFS fid2path $DIR $FID | wc -l)
15120         echo -n "${links}/1000 links in link EA"
15121         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15122 }
15123 run_test 161a "link ea sanity"
15124
15125 test_161b() {
15126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15127         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15128
15129         local MDTIDX=1
15130         local remote_dir=$DIR/$tdir/remote_dir
15131
15132         mkdir -p $DIR/$tdir
15133         $LFS mkdir -i $MDTIDX $remote_dir ||
15134                 error "create remote directory failed"
15135
15136         cp /etc/hosts $remote_dir/$tfile
15137         mkdir -p $remote_dir/foo1
15138         mkdir -p $remote_dir/foo2
15139         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15140         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15141         ln $remote_dir/$tfile $remote_dir/foo1/luna
15142         ln $remote_dir/$tfile $remote_dir/foo2/thor
15143
15144         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15145                      tr -d ']')
15146         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15147                 $LFS fid2path $DIR $FID
15148                 error "bad link ea"
15149         fi
15150         # middle
15151         rm $remote_dir/foo2/zachary
15152         # last
15153         rm $remote_dir/foo2/thor
15154         # first
15155         rm $remote_dir/$tfile
15156         # rename
15157         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15158         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15159         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15160                 $LFS fid2path $DIR $FID
15161                 error "bad link rename"
15162         fi
15163         rm $remote_dir/foo2/maggie
15164
15165         # overflow the EA
15166         local longname=filename_avg_len_is_thirty_two_
15167         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15168                 error "failed to hardlink many files"
15169         links=$($LFS fid2path $DIR $FID | wc -l)
15170         echo -n "${links}/1000 links in link EA"
15171         [[ ${links} -gt 60 ]] ||
15172                 error "expected at least 60 links in link EA"
15173         unlinkmany $remote_dir/foo2/$longname 1000 ||
15174         error "failed to unlink many hardlinks"
15175 }
15176 run_test 161b "link ea sanity under remote directory"
15177
15178 test_161c() {
15179         remote_mds_nodsh && skip "remote MDS with nodsh"
15180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15181         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15182                 skip "Need MDS version at least 2.1.5"
15183
15184         # define CLF_RENAME_LAST 0x0001
15185         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15186         changelog_register || error "changelog_register failed"
15187
15188         rm -rf $DIR/$tdir
15189         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15190         touch $DIR/$tdir/foo_161c
15191         touch $DIR/$tdir/bar_161c
15192         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15193         changelog_dump | grep RENME | tail -n 5
15194         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15195         changelog_clear 0 || error "changelog_clear failed"
15196         if [ x$flags != "x0x1" ]; then
15197                 error "flag $flags is not 0x1"
15198         fi
15199
15200         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15201         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15202         touch $DIR/$tdir/foo_161c
15203         touch $DIR/$tdir/bar_161c
15204         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15205         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15206         changelog_dump | grep RENME | tail -n 5
15207         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15208         changelog_clear 0 || error "changelog_clear failed"
15209         if [ x$flags != "x0x0" ]; then
15210                 error "flag $flags is not 0x0"
15211         fi
15212         echo "rename overwrite a target having nlink > 1," \
15213                 "changelog record has flags of $flags"
15214
15215         # rename doesn't overwrite a target (changelog flag 0x0)
15216         touch $DIR/$tdir/foo_161c
15217         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15218         changelog_dump | grep RENME | tail -n 5
15219         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15220         changelog_clear 0 || error "changelog_clear failed"
15221         if [ x$flags != "x0x0" ]; then
15222                 error "flag $flags is not 0x0"
15223         fi
15224         echo "rename doesn't overwrite a target," \
15225                 "changelog record has flags of $flags"
15226
15227         # define CLF_UNLINK_LAST 0x0001
15228         # unlink a file having nlink = 1 (changelog flag 0x1)
15229         rm -f $DIR/$tdir/foo2_161c
15230         changelog_dump | grep UNLNK | tail -n 5
15231         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15232         changelog_clear 0 || error "changelog_clear failed"
15233         if [ x$flags != "x0x1" ]; then
15234                 error "flag $flags is not 0x1"
15235         fi
15236         echo "unlink a file having nlink = 1," \
15237                 "changelog record has flags of $flags"
15238
15239         # unlink a file having nlink > 1 (changelog flag 0x0)
15240         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15241         rm -f $DIR/$tdir/foobar_161c
15242         changelog_dump | grep UNLNK | tail -n 5
15243         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15244         changelog_clear 0 || error "changelog_clear failed"
15245         if [ x$flags != "x0x0" ]; then
15246                 error "flag $flags is not 0x0"
15247         fi
15248         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15249 }
15250 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15251
15252 test_161d() {
15253         remote_mds_nodsh && skip "remote MDS with nodsh"
15254         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15255
15256         local pid
15257         local fid
15258
15259         changelog_register || error "changelog_register failed"
15260
15261         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15262         # interfer with $MOUNT/.lustre/fid/ access
15263         mkdir $DIR/$tdir
15264         [[ $? -eq 0 ]] || error "mkdir failed"
15265
15266         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15267         $LCTL set_param fail_loc=0x8000140c
15268         # 5s pause
15269         $LCTL set_param fail_val=5
15270
15271         # create file
15272         echo foofoo > $DIR/$tdir/$tfile &
15273         pid=$!
15274
15275         # wait for create to be delayed
15276         sleep 2
15277
15278         ps -p $pid
15279         [[ $? -eq 0 ]] || error "create should be blocked"
15280
15281         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15282         stack_trap "rm -f $tempfile"
15283         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15284         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15285         # some delay may occur during ChangeLog publishing and file read just
15286         # above, that could allow file write to happen finally
15287         [[ -s $tempfile ]] && echo "file should be empty"
15288
15289         $LCTL set_param fail_loc=0
15290
15291         wait $pid
15292         [[ $? -eq 0 ]] || error "create failed"
15293 }
15294 run_test 161d "create with concurrent .lustre/fid access"
15295
15296 check_path() {
15297         local expected="$1"
15298         shift
15299         local fid="$2"
15300
15301         local path
15302         path=$($LFS fid2path "$@")
15303         local rc=$?
15304
15305         if [ $rc -ne 0 ]; then
15306                 error "path looked up of '$expected' failed: rc=$rc"
15307         elif [ "$path" != "$expected" ]; then
15308                 error "path looked up '$path' instead of '$expected'"
15309         else
15310                 echo "FID '$fid' resolves to path '$path' as expected"
15311         fi
15312 }
15313
15314 test_162a() { # was test_162
15315         test_mkdir -p -c1 $DIR/$tdir/d2
15316         touch $DIR/$tdir/d2/$tfile
15317         touch $DIR/$tdir/d2/x1
15318         touch $DIR/$tdir/d2/x2
15319         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15320         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15321         # regular file
15322         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15323         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15324
15325         # softlink
15326         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15327         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15328         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15329
15330         # softlink to wrong file
15331         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15332         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15333         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15334
15335         # hardlink
15336         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15337         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15338         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15339         # fid2path dir/fsname should both work
15340         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15341         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15342
15343         # hardlink count: check that there are 2 links
15344         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15345         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15346
15347         # hardlink indexing: remove the first link
15348         rm $DIR/$tdir/d2/p/q/r/hlink
15349         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15350 }
15351 run_test 162a "path lookup sanity"
15352
15353 test_162b() {
15354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15356
15357         mkdir $DIR/$tdir
15358         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15359                                 error "create striped dir failed"
15360
15361         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15362                                         tail -n 1 | awk '{print $2}')
15363         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15364
15365         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15366         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15367
15368         # regular file
15369         for ((i=0;i<5;i++)); do
15370                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15371                         error "get fid for f$i failed"
15372                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15373
15374                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15375                         error "get fid for d$i failed"
15376                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15377         done
15378
15379         return 0
15380 }
15381 run_test 162b "striped directory path lookup sanity"
15382
15383 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15384 test_162c() {
15385         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15386                 skip "Need MDS version at least 2.7.51"
15387
15388         local lpath=$tdir.local
15389         local rpath=$tdir.remote
15390
15391         test_mkdir $DIR/$lpath
15392         test_mkdir $DIR/$rpath
15393
15394         for ((i = 0; i <= 101; i++)); do
15395                 lpath="$lpath/$i"
15396                 mkdir $DIR/$lpath
15397                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15398                         error "get fid for local directory $DIR/$lpath failed"
15399                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15400
15401                 rpath="$rpath/$i"
15402                 test_mkdir $DIR/$rpath
15403                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15404                         error "get fid for remote directory $DIR/$rpath failed"
15405                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15406         done
15407
15408         return 0
15409 }
15410 run_test 162c "fid2path works with paths 100 or more directories deep"
15411
15412 oalr_event_count() {
15413         local event="${1}"
15414         local trace="${2}"
15415
15416         awk -v name="${FSNAME}-OST0000" \
15417             -v event="${event}" \
15418             '$1 == "TRACE" && $2 == event && $3 == name' \
15419             "${trace}" |
15420         wc -l
15421 }
15422
15423 oalr_expect_event_count() {
15424         local event="${1}"
15425         local trace="${2}"
15426         local expect="${3}"
15427         local count
15428
15429         count=$(oalr_event_count "${event}" "${trace}")
15430         if ((count == expect)); then
15431                 return 0
15432         fi
15433
15434         error_noexit "${event} event count was '${count}', expected ${expect}"
15435         cat "${trace}" >&2
15436         exit 1
15437 }
15438
15439 cleanup_165() {
15440         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15441         stop ost1
15442         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15443 }
15444
15445 setup_165() {
15446         sync # Flush previous IOs so we can count log entries.
15447         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15448         stack_trap cleanup_165 EXIT
15449 }
15450
15451 test_165a() {
15452         local trace="/tmp/${tfile}.trace"
15453         local rc
15454         local count
15455
15456         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15457         setup_165
15458         sleep 5
15459
15460         do_facet ost1 ofd_access_log_reader --list
15461         stop ost1
15462
15463         do_facet ost1 killall -TERM ofd_access_log_reader
15464         wait
15465         rc=$?
15466
15467         if ((rc != 0)); then
15468                 error "ofd_access_log_reader exited with rc = '${rc}'"
15469         fi
15470
15471         # Parse trace file for discovery events:
15472         oalr_expect_event_count alr_log_add "${trace}" 1
15473         oalr_expect_event_count alr_log_eof "${trace}" 1
15474         oalr_expect_event_count alr_log_free "${trace}" 1
15475 }
15476 run_test 165a "ofd access log discovery"
15477
15478 test_165b() {
15479         local trace="/tmp/${tfile}.trace"
15480         local file="${DIR}/${tfile}"
15481         local pfid1
15482         local pfid2
15483         local -a entry
15484         local rc
15485         local count
15486         local size
15487         local flags
15488
15489         setup_165
15490
15491         lfs setstripe -c 1 -i 0 "${file}"
15492         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15493         do_facet ost1 ofd_access_log_reader --list
15494
15495         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15496         sleep 5
15497         do_facet ost1 killall -TERM ofd_access_log_reader
15498         wait
15499         rc=$?
15500
15501         if ((rc != 0)); then
15502                 error "ofd_access_log_reader exited with rc = '${rc}'"
15503         fi
15504
15505         oalr_expect_event_count alr_log_entry "${trace}" 1
15506
15507         pfid1=$($LFS path2fid "${file}")
15508
15509         # 1     2             3   4    5     6   7    8    9     10
15510         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15511         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15512
15513         echo "entry = '${entry[*]}'" >&2
15514
15515         pfid2=${entry[4]}
15516         if [[ "${pfid1}" != "${pfid2}" ]]; then
15517                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15518         fi
15519
15520         size=${entry[8]}
15521         if ((size != 1048576)); then
15522                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15523         fi
15524
15525         flags=${entry[10]}
15526         if [[ "${flags}" != "w" ]]; then
15527                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15528         fi
15529
15530         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15531         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15532         sleep 5
15533         do_facet ost1 killall -TERM ofd_access_log_reader
15534         wait
15535         rc=$?
15536
15537         if ((rc != 0)); then
15538                 error "ofd_access_log_reader exited with rc = '${rc}'"
15539         fi
15540
15541         oalr_expect_event_count alr_log_entry "${trace}" 1
15542
15543         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15544         echo "entry = '${entry[*]}'" >&2
15545
15546         pfid2=${entry[4]}
15547         if [[ "${pfid1}" != "${pfid2}" ]]; then
15548                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15549         fi
15550
15551         size=${entry[8]}
15552         if ((size != 524288)); then
15553                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15554         fi
15555
15556         flags=${entry[10]}
15557         if [[ "${flags}" != "r" ]]; then
15558                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15559         fi
15560 }
15561 run_test 165b "ofd access log entries are produced and consumed"
15562
15563 test_165c() {
15564         local file="${DIR}/${tdir}/${tfile}"
15565         test_mkdir "${DIR}/${tdir}"
15566
15567         setup_165
15568
15569         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15570
15571         # 4096 / 64 = 64. Create twice as many entries.
15572         for ((i = 0; i < 128; i++)); do
15573                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15574         done
15575
15576         sync
15577         do_facet ost1 ofd_access_log_reader --list
15578         unlinkmany  "${file}-%d" 128
15579 }
15580 run_test 165c "full ofd access logs do not block IOs"
15581
15582 oal_peek_entry_count() {
15583         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15584 }
15585
15586 oal_expect_entry_count() {
15587         local entry_count=$(oal_peek_entry_count)
15588         local expect="$1"
15589
15590         if ((entry_count == expect)); then
15591                 return 0
15592         fi
15593
15594         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15595         do_facet ost1 ofd_access_log_reader --list >&2
15596         exit 1
15597 }
15598
15599 test_165d() {
15600         local trace="/tmp/${tfile}.trace"
15601         local file="${DIR}/${tdir}/${tfile}"
15602         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15603         local entry_count
15604         test_mkdir "${DIR}/${tdir}"
15605
15606         setup_165
15607         lfs setstripe -c 1 -i 0 "${file}"
15608
15609         do_facet ost1 lctl set_param "${param}=rw"
15610         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15611         oal_expect_entry_count 1
15612
15613         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15614         oal_expect_entry_count 2
15615
15616         do_facet ost1 lctl set_param "${param}=r"
15617         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15618         oal_expect_entry_count 2
15619
15620         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15621         oal_expect_entry_count 3
15622
15623         do_facet ost1 lctl set_param "${param}=w"
15624         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15625         oal_expect_entry_count 4
15626
15627         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15628         oal_expect_entry_count 4
15629
15630         do_facet ost1 lctl set_param "${param}=0"
15631         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15632         oal_expect_entry_count 4
15633
15634         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15635         oal_expect_entry_count 4
15636 }
15637 run_test 165d "ofd_access_log mask works"
15638
15639 test_169() {
15640         # do directio so as not to populate the page cache
15641         log "creating a 10 Mb file"
15642         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15643         log "starting reads"
15644         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15645         log "truncating the file"
15646         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15647         log "killing dd"
15648         kill %+ || true # reads might have finished
15649         echo "wait until dd is finished"
15650         wait
15651         log "removing the temporary file"
15652         rm -rf $DIR/$tfile || error "tmp file removal failed"
15653 }
15654 run_test 169 "parallel read and truncate should not deadlock"
15655
15656 test_170() {
15657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15658
15659         $LCTL clear     # bug 18514
15660         $LCTL debug_daemon start $TMP/${tfile}_log_good
15661         touch $DIR/$tfile
15662         $LCTL debug_daemon stop
15663         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15664                 error "sed failed to read log_good"
15665
15666         $LCTL debug_daemon start $TMP/${tfile}_log_good
15667         rm -rf $DIR/$tfile
15668         $LCTL debug_daemon stop
15669
15670         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15671                error "lctl df log_bad failed"
15672
15673         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15674         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15675
15676         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15677         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15678
15679         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15680                 error "bad_line good_line1 good_line2 are empty"
15681
15682         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15683         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15684         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15685
15686         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15687         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15688         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15689
15690         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15691                 error "bad_line_new good_line_new are empty"
15692
15693         local expected_good=$((good_line1 + good_line2*2))
15694
15695         rm -f $TMP/${tfile}*
15696         # LU-231, short malformed line may not be counted into bad lines
15697         if [ $bad_line -ne $bad_line_new ] &&
15698                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15699                 error "expected $bad_line bad lines, but got $bad_line_new"
15700                 return 1
15701         fi
15702
15703         if [ $expected_good -ne $good_line_new ]; then
15704                 error "expected $expected_good good lines, but got $good_line_new"
15705                 return 2
15706         fi
15707         true
15708 }
15709 run_test 170 "test lctl df to handle corrupted log ====================="
15710
15711 test_171() { # bug20592
15712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15713
15714         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15715         $LCTL set_param fail_loc=0x50e
15716         $LCTL set_param fail_val=3000
15717         multiop_bg_pause $DIR/$tfile O_s || true
15718         local MULTIPID=$!
15719         kill -USR1 $MULTIPID
15720         # cause log dump
15721         sleep 3
15722         wait $MULTIPID
15723         if dmesg | grep "recursive fault"; then
15724                 error "caught a recursive fault"
15725         fi
15726         $LCTL set_param fail_loc=0
15727         true
15728 }
15729 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15730
15731 # it would be good to share it with obdfilter-survey/iokit-libecho code
15732 setup_obdecho_osc () {
15733         local rc=0
15734         local ost_nid=$1
15735         local obdfilter_name=$2
15736         echo "Creating new osc for $obdfilter_name on $ost_nid"
15737         # make sure we can find loopback nid
15738         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15739
15740         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15741                            ${obdfilter_name}_osc_UUID || rc=2; }
15742         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15743                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15744         return $rc
15745 }
15746
15747 cleanup_obdecho_osc () {
15748         local obdfilter_name=$1
15749         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15750         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15751         return 0
15752 }
15753
15754 obdecho_test() {
15755         local OBD=$1
15756         local node=$2
15757         local pages=${3:-64}
15758         local rc=0
15759         local id
15760
15761         local count=10
15762         local obd_size=$(get_obd_size $node $OBD)
15763         local page_size=$(get_page_size $node)
15764         if [[ -n "$obd_size" ]]; then
15765                 local new_count=$((obd_size / (pages * page_size / 1024)))
15766                 [[ $new_count -ge $count ]] || count=$new_count
15767         fi
15768
15769         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15770         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15771                            rc=2; }
15772         if [ $rc -eq 0 ]; then
15773             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15774             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15775         fi
15776         echo "New object id is $id"
15777         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15778                            rc=4; }
15779         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15780                            "test_brw $count w v $pages $id" || rc=4; }
15781         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15782                            rc=4; }
15783         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15784                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15785         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15786                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15787         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15788         return $rc
15789 }
15790
15791 test_180a() {
15792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15793
15794         if ! [ -d /sys/fs/lustre/echo_client ] &&
15795            ! module_loaded obdecho; then
15796                 load_module obdecho/obdecho &&
15797                         stack_trap "rmmod obdecho" EXIT ||
15798                         error "unable to load obdecho on client"
15799         fi
15800
15801         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15802         local host=$($LCTL get_param -n osc.$osc.import |
15803                      awk '/current_connection:/ { print $2 }' )
15804         local target=$($LCTL get_param -n osc.$osc.import |
15805                        awk '/target:/ { print $2 }' )
15806         target=${target%_UUID}
15807
15808         if [ -n "$target" ]; then
15809                 setup_obdecho_osc $host $target &&
15810                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15811                         { error "obdecho setup failed with $?"; return; }
15812
15813                 obdecho_test ${target}_osc client ||
15814                         error "obdecho_test failed on ${target}_osc"
15815         else
15816                 $LCTL get_param osc.$osc.import
15817                 error "there is no osc.$osc.import target"
15818         fi
15819 }
15820 run_test 180a "test obdecho on osc"
15821
15822 test_180b() {
15823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15824         remote_ost_nodsh && skip "remote OST with nodsh"
15825
15826         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15827                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15828                 error "failed to load module obdecho"
15829
15830         local target=$(do_facet ost1 $LCTL dl |
15831                        awk '/obdfilter/ { print $4; exit; }')
15832
15833         if [ -n "$target" ]; then
15834                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15835         else
15836                 do_facet ost1 $LCTL dl
15837                 error "there is no obdfilter target on ost1"
15838         fi
15839 }
15840 run_test 180b "test obdecho directly on obdfilter"
15841
15842 test_180c() { # LU-2598
15843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15844         remote_ost_nodsh && skip "remote OST with nodsh"
15845         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15846                 skip "Need MDS version at least 2.4.0"
15847
15848         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15849                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15850                 error "failed to load module obdecho"
15851
15852         local target=$(do_facet ost1 $LCTL dl |
15853                        awk '/obdfilter/ { print $4; exit; }')
15854
15855         if [ -n "$target" ]; then
15856                 local pages=16384 # 64MB bulk I/O RPC size
15857
15858                 obdecho_test "$target" ost1 "$pages" ||
15859                         error "obdecho_test with pages=$pages failed with $?"
15860         else
15861                 do_facet ost1 $LCTL dl
15862                 error "there is no obdfilter target on ost1"
15863         fi
15864 }
15865 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15866
15867 test_181() { # bug 22177
15868         test_mkdir $DIR/$tdir
15869         # create enough files to index the directory
15870         createmany -o $DIR/$tdir/foobar 4000
15871         # print attributes for debug purpose
15872         lsattr -d .
15873         # open dir
15874         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15875         MULTIPID=$!
15876         # remove the files & current working dir
15877         unlinkmany $DIR/$tdir/foobar 4000
15878         rmdir $DIR/$tdir
15879         kill -USR1 $MULTIPID
15880         wait $MULTIPID
15881         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15882         return 0
15883 }
15884 run_test 181 "Test open-unlinked dir ========================"
15885
15886 test_182() {
15887         local fcount=1000
15888         local tcount=10
15889
15890         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15891
15892         $LCTL set_param mdc.*.rpc_stats=clear
15893
15894         for (( i = 0; i < $tcount; i++ )) ; do
15895                 mkdir $DIR/$tdir/$i
15896         done
15897
15898         for (( i = 0; i < $tcount; i++ )) ; do
15899                 createmany -o $DIR/$tdir/$i/f- $fcount &
15900         done
15901         wait
15902
15903         for (( i = 0; i < $tcount; i++ )) ; do
15904                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15905         done
15906         wait
15907
15908         $LCTL get_param mdc.*.rpc_stats
15909
15910         rm -rf $DIR/$tdir
15911 }
15912 run_test 182 "Test parallel modify metadata operations ================"
15913
15914 test_183() { # LU-2275
15915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15916         remote_mds_nodsh && skip "remote MDS with nodsh"
15917         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15918                 skip "Need MDS version at least 2.3.56"
15919
15920         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15921         echo aaa > $DIR/$tdir/$tfile
15922
15923 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15925
15926         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15927         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15928
15929         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15930
15931         # Flush negative dentry cache
15932         touch $DIR/$tdir/$tfile
15933
15934         # We are not checking for any leaked references here, they'll
15935         # become evident next time we do cleanup with module unload.
15936         rm -rf $DIR/$tdir
15937 }
15938 run_test 183 "No crash or request leak in case of strange dispositions ========"
15939
15940 # test suite 184 is for LU-2016, LU-2017
15941 test_184a() {
15942         check_swap_layouts_support
15943
15944         dir0=$DIR/$tdir/$testnum
15945         test_mkdir -p -c1 $dir0
15946         ref1=/etc/passwd
15947         ref2=/etc/group
15948         file1=$dir0/f1
15949         file2=$dir0/f2
15950         $LFS setstripe -c1 $file1
15951         cp $ref1 $file1
15952         $LFS setstripe -c2 $file2
15953         cp $ref2 $file2
15954         gen1=$($LFS getstripe -g $file1)
15955         gen2=$($LFS getstripe -g $file2)
15956
15957         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15958         gen=$($LFS getstripe -g $file1)
15959         [[ $gen1 != $gen ]] ||
15960                 "Layout generation on $file1 does not change"
15961         gen=$($LFS getstripe -g $file2)
15962         [[ $gen2 != $gen ]] ||
15963                 "Layout generation on $file2 does not change"
15964
15965         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15966         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15967
15968         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15969 }
15970 run_test 184a "Basic layout swap"
15971
15972 test_184b() {
15973         check_swap_layouts_support
15974
15975         dir0=$DIR/$tdir/$testnum
15976         mkdir -p $dir0 || error "creating dir $dir0"
15977         file1=$dir0/f1
15978         file2=$dir0/f2
15979         file3=$dir0/f3
15980         dir1=$dir0/d1
15981         dir2=$dir0/d2
15982         mkdir $dir1 $dir2
15983         $LFS setstripe -c1 $file1
15984         $LFS setstripe -c2 $file2
15985         $LFS setstripe -c1 $file3
15986         chown $RUNAS_ID $file3
15987         gen1=$($LFS getstripe -g $file1)
15988         gen2=$($LFS getstripe -g $file2)
15989
15990         $LFS swap_layouts $dir1 $dir2 &&
15991                 error "swap of directories layouts should fail"
15992         $LFS swap_layouts $dir1 $file1 &&
15993                 error "swap of directory and file layouts should fail"
15994         $RUNAS $LFS swap_layouts $file1 $file2 &&
15995                 error "swap of file we cannot write should fail"
15996         $LFS swap_layouts $file1 $file3 &&
15997                 error "swap of file with different owner should fail"
15998         /bin/true # to clear error code
15999 }
16000 run_test 184b "Forbidden layout swap (will generate errors)"
16001
16002 test_184c() {
16003         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16004         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16005         check_swap_layouts_support
16006         check_swap_layout_no_dom $DIR
16007
16008         local dir0=$DIR/$tdir/$testnum
16009         mkdir -p $dir0 || error "creating dir $dir0"
16010
16011         local ref1=$dir0/ref1
16012         local ref2=$dir0/ref2
16013         local file1=$dir0/file1
16014         local file2=$dir0/file2
16015         # create a file large enough for the concurrent test
16016         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16017         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16018         echo "ref file size: ref1($(stat -c %s $ref1))," \
16019              "ref2($(stat -c %s $ref2))"
16020
16021         cp $ref2 $file2
16022         dd if=$ref1 of=$file1 bs=16k &
16023         local DD_PID=$!
16024
16025         # Make sure dd starts to copy file, but wait at most 5 seconds
16026         local loops=0
16027         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16028
16029         $LFS swap_layouts $file1 $file2
16030         local rc=$?
16031         wait $DD_PID
16032         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16033         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16034
16035         # how many bytes copied before swapping layout
16036         local copied=$(stat -c %s $file2)
16037         local remaining=$(stat -c %s $ref1)
16038         remaining=$((remaining - copied))
16039         echo "Copied $copied bytes before swapping layout..."
16040
16041         cmp -n $copied $file1 $ref2 | grep differ &&
16042                 error "Content mismatch [0, $copied) of ref2 and file1"
16043         cmp -n $copied $file2 $ref1 ||
16044                 error "Content mismatch [0, $copied) of ref1 and file2"
16045         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16046                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16047
16048         # clean up
16049         rm -f $ref1 $ref2 $file1 $file2
16050 }
16051 run_test 184c "Concurrent write and layout swap"
16052
16053 test_184d() {
16054         check_swap_layouts_support
16055         check_swap_layout_no_dom $DIR
16056         [ -z "$(which getfattr 2>/dev/null)" ] &&
16057                 skip_env "no getfattr command"
16058
16059         local file1=$DIR/$tdir/$tfile-1
16060         local file2=$DIR/$tdir/$tfile-2
16061         local file3=$DIR/$tdir/$tfile-3
16062         local lovea1
16063         local lovea2
16064
16065         mkdir -p $DIR/$tdir
16066         touch $file1 || error "create $file1 failed"
16067         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16068                 error "create $file2 failed"
16069         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16070                 error "create $file3 failed"
16071         lovea1=$(get_layout_param $file1)
16072
16073         $LFS swap_layouts $file2 $file3 ||
16074                 error "swap $file2 $file3 layouts failed"
16075         $LFS swap_layouts $file1 $file2 ||
16076                 error "swap $file1 $file2 layouts failed"
16077
16078         lovea2=$(get_layout_param $file2)
16079         echo "$lovea1"
16080         echo "$lovea2"
16081         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16082
16083         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16084         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16085 }
16086 run_test 184d "allow stripeless layouts swap"
16087
16088 test_184e() {
16089         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16090                 skip "Need MDS version at least 2.6.94"
16091         check_swap_layouts_support
16092         check_swap_layout_no_dom $DIR
16093         [ -z "$(which getfattr 2>/dev/null)" ] &&
16094                 skip_env "no getfattr command"
16095
16096         local file1=$DIR/$tdir/$tfile-1
16097         local file2=$DIR/$tdir/$tfile-2
16098         local file3=$DIR/$tdir/$tfile-3
16099         local lovea
16100
16101         mkdir -p $DIR/$tdir
16102         touch $file1 || error "create $file1 failed"
16103         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16104                 error "create $file2 failed"
16105         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16106                 error "create $file3 failed"
16107
16108         $LFS swap_layouts $file1 $file2 ||
16109                 error "swap $file1 $file2 layouts failed"
16110
16111         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16112         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16113
16114         echo 123 > $file1 || error "Should be able to write into $file1"
16115
16116         $LFS swap_layouts $file1 $file3 ||
16117                 error "swap $file1 $file3 layouts failed"
16118
16119         echo 123 > $file1 || error "Should be able to write into $file1"
16120
16121         rm -rf $file1 $file2 $file3
16122 }
16123 run_test 184e "Recreate layout after stripeless layout swaps"
16124
16125 test_184f() {
16126         # Create a file with name longer than sizeof(struct stat) ==
16127         # 144 to see if we can get chars from the file name to appear
16128         # in the returned striping. Note that 'f' == 0x66.
16129         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16130
16131         mkdir -p $DIR/$tdir
16132         mcreate $DIR/$tdir/$file
16133         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16134                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16135         fi
16136 }
16137 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16138
16139 test_185() { # LU-2441
16140         # LU-3553 - no volatile file support in old servers
16141         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16142                 skip "Need MDS version at least 2.3.60"
16143
16144         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16145         touch $DIR/$tdir/spoo
16146         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16147         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16148                 error "cannot create/write a volatile file"
16149         [ "$FILESET" == "" ] &&
16150         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16151                 error "FID is still valid after close"
16152
16153         multiop_bg_pause $DIR/$tdir vVw4096_c
16154         local multi_pid=$!
16155
16156         local OLD_IFS=$IFS
16157         IFS=":"
16158         local fidv=($fid)
16159         IFS=$OLD_IFS
16160         # assume that the next FID for this client is sequential, since stdout
16161         # is unfortunately eaten by multiop_bg_pause
16162         local n=$((${fidv[1]} + 1))
16163         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16164         if [ "$FILESET" == "" ]; then
16165                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16166                         error "FID is missing before close"
16167         fi
16168         kill -USR1 $multi_pid
16169         # 1 second delay, so if mtime change we will see it
16170         sleep 1
16171         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16172         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16173 }
16174 run_test 185 "Volatile file support"
16175
16176 function create_check_volatile() {
16177         local idx=$1
16178         local tgt
16179
16180         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16181         local PID=$!
16182         sleep 1
16183         local FID=$(cat /tmp/${tfile}.fid)
16184         [ "$FID" == "" ] && error "can't get FID for volatile"
16185         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16186         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16187         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16188         kill -USR1 $PID
16189         wait
16190         sleep 1
16191         cancel_lru_locks mdc # flush opencache
16192         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16193         return 0
16194 }
16195
16196 test_185a(){
16197         # LU-12516 - volatile creation via .lustre
16198         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16199                 skip "Need MDS version at least 2.3.55"
16200
16201         create_check_volatile 0
16202         [ $MDSCOUNT -lt 2 ] && return 0
16203
16204         # DNE case
16205         create_check_volatile 1
16206
16207         return 0
16208 }
16209 run_test 185a "Volatile file creation in .lustre/fid/"
16210
16211 test_187a() {
16212         remote_mds_nodsh && skip "remote MDS with nodsh"
16213         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16214                 skip "Need MDS version at least 2.3.0"
16215
16216         local dir0=$DIR/$tdir/$testnum
16217         mkdir -p $dir0 || error "creating dir $dir0"
16218
16219         local file=$dir0/file1
16220         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16221         local dv1=$($LFS data_version $file)
16222         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16223         local dv2=$($LFS data_version $file)
16224         [[ $dv1 != $dv2 ]] ||
16225                 error "data version did not change on write $dv1 == $dv2"
16226
16227         # clean up
16228         rm -f $file1
16229 }
16230 run_test 187a "Test data version change"
16231
16232 test_187b() {
16233         remote_mds_nodsh && skip "remote MDS with nodsh"
16234         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16235                 skip "Need MDS version at least 2.3.0"
16236
16237         local dir0=$DIR/$tdir/$testnum
16238         mkdir -p $dir0 || error "creating dir $dir0"
16239
16240         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16241         [[ ${DV[0]} != ${DV[1]} ]] ||
16242                 error "data version did not change on write"\
16243                       " ${DV[0]} == ${DV[1]}"
16244
16245         # clean up
16246         rm -f $file1
16247 }
16248 run_test 187b "Test data version change on volatile file"
16249
16250 test_200() {
16251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16252         remote_mgs_nodsh && skip "remote MGS with nodsh"
16253         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16254
16255         local POOL=${POOL:-cea1}
16256         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16257         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16258         # Pool OST targets
16259         local first_ost=0
16260         local last_ost=$(($OSTCOUNT - 1))
16261         local ost_step=2
16262         local ost_list=$(seq $first_ost $ost_step $last_ost)
16263         local ost_range="$first_ost $last_ost $ost_step"
16264         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16265         local file_dir=$POOL_ROOT/file_tst
16266         local subdir=$test_path/subdir
16267         local rc=0
16268
16269         while : ; do
16270                 # former test_200a test_200b
16271                 pool_add $POOL                          || { rc=$? ; break; }
16272                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16273                 # former test_200c test_200d
16274                 mkdir -p $test_path
16275                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16276                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16277                 mkdir -p $subdir
16278                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16279                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16280                                                         || { rc=$? ; break; }
16281                 # former test_200e test_200f
16282                 local files=$((OSTCOUNT*3))
16283                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16284                                                         || { rc=$? ; break; }
16285                 pool_create_files $POOL $file_dir $files "$ost_list" \
16286                                                         || { rc=$? ; break; }
16287                 # former test_200g test_200h
16288                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16289                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16290
16291                 # former test_201a test_201b test_201c
16292                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16293
16294                 local f=$test_path/$tfile
16295                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16296                 pool_remove $POOL $f                    || { rc=$? ; break; }
16297                 break
16298         done
16299
16300         destroy_test_pools
16301
16302         return $rc
16303 }
16304 run_test 200 "OST pools"
16305
16306 # usage: default_attr <count | size | offset>
16307 default_attr() {
16308         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16309 }
16310
16311 # usage: check_default_stripe_attr
16312 check_default_stripe_attr() {
16313         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16314         case $1 in
16315         --stripe-count|-c)
16316                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16317         --stripe-size|-S)
16318                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16319         --stripe-index|-i)
16320                 EXPECTED=-1;;
16321         *)
16322                 error "unknown getstripe attr '$1'"
16323         esac
16324
16325         [ $ACTUAL == $EXPECTED ] ||
16326                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16327 }
16328
16329 test_204a() {
16330         test_mkdir $DIR/$tdir
16331         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16332
16333         check_default_stripe_attr --stripe-count
16334         check_default_stripe_attr --stripe-size
16335         check_default_stripe_attr --stripe-index
16336 }
16337 run_test 204a "Print default stripe attributes"
16338
16339 test_204b() {
16340         test_mkdir $DIR/$tdir
16341         $LFS setstripe --stripe-count 1 $DIR/$tdir
16342
16343         check_default_stripe_attr --stripe-size
16344         check_default_stripe_attr --stripe-index
16345 }
16346 run_test 204b "Print default stripe size and offset"
16347
16348 test_204c() {
16349         test_mkdir $DIR/$tdir
16350         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16351
16352         check_default_stripe_attr --stripe-count
16353         check_default_stripe_attr --stripe-index
16354 }
16355 run_test 204c "Print default stripe count and offset"
16356
16357 test_204d() {
16358         test_mkdir $DIR/$tdir
16359         $LFS setstripe --stripe-index 0 $DIR/$tdir
16360
16361         check_default_stripe_attr --stripe-count
16362         check_default_stripe_attr --stripe-size
16363 }
16364 run_test 204d "Print default stripe count and size"
16365
16366 test_204e() {
16367         test_mkdir $DIR/$tdir
16368         $LFS setstripe -d $DIR/$tdir
16369
16370         check_default_stripe_attr --stripe-count --raw
16371         check_default_stripe_attr --stripe-size --raw
16372         check_default_stripe_attr --stripe-index --raw
16373 }
16374 run_test 204e "Print raw stripe attributes"
16375
16376 test_204f() {
16377         test_mkdir $DIR/$tdir
16378         $LFS setstripe --stripe-count 1 $DIR/$tdir
16379
16380         check_default_stripe_attr --stripe-size --raw
16381         check_default_stripe_attr --stripe-index --raw
16382 }
16383 run_test 204f "Print raw stripe size and offset"
16384
16385 test_204g() {
16386         test_mkdir $DIR/$tdir
16387         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16388
16389         check_default_stripe_attr --stripe-count --raw
16390         check_default_stripe_attr --stripe-index --raw
16391 }
16392 run_test 204g "Print raw stripe count and offset"
16393
16394 test_204h() {
16395         test_mkdir $DIR/$tdir
16396         $LFS setstripe --stripe-index 0 $DIR/$tdir
16397
16398         check_default_stripe_attr --stripe-count --raw
16399         check_default_stripe_attr --stripe-size --raw
16400 }
16401 run_test 204h "Print raw stripe count and size"
16402
16403 # Figure out which job scheduler is being used, if any,
16404 # or use a fake one
16405 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16406         JOBENV=SLURM_JOB_ID
16407 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16408         JOBENV=LSB_JOBID
16409 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16410         JOBENV=PBS_JOBID
16411 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16412         JOBENV=LOADL_STEP_ID
16413 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16414         JOBENV=JOB_ID
16415 else
16416         $LCTL list_param jobid_name > /dev/null 2>&1
16417         if [ $? -eq 0 ]; then
16418                 JOBENV=nodelocal
16419         else
16420                 JOBENV=FAKE_JOBID
16421         fi
16422 fi
16423 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16424
16425 verify_jobstats() {
16426         local cmd=($1)
16427         shift
16428         local facets="$@"
16429
16430 # we don't really need to clear the stats for this test to work, since each
16431 # command has a unique jobid, but it makes debugging easier if needed.
16432 #       for facet in $facets; do
16433 #               local dev=$(convert_facet2label $facet)
16434 #               # clear old jobstats
16435 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16436 #       done
16437
16438         # use a new JobID for each test, or we might see an old one
16439         [ "$JOBENV" = "FAKE_JOBID" ] &&
16440                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16441
16442         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16443
16444         [ "$JOBENV" = "nodelocal" ] && {
16445                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16446                 $LCTL set_param jobid_name=$FAKE_JOBID
16447                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16448         }
16449
16450         log "Test: ${cmd[*]}"
16451         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16452
16453         if [ $JOBENV = "FAKE_JOBID" ]; then
16454                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16455         else
16456                 ${cmd[*]}
16457         fi
16458
16459         # all files are created on OST0000
16460         for facet in $facets; do
16461                 local stats="*.$(convert_facet2label $facet).job_stats"
16462
16463                 # strip out libtool wrappers for in-tree executables
16464                 if [ $(do_facet $facet lctl get_param $stats |
16465                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16466                         do_facet $facet lctl get_param $stats
16467                         error "No jobstats for $JOBVAL found on $facet::$stats"
16468                 fi
16469         done
16470 }
16471
16472 jobstats_set() {
16473         local new_jobenv=$1
16474
16475         set_persistent_param_and_check client "jobid_var" \
16476                 "$FSNAME.sys.jobid_var" $new_jobenv
16477 }
16478
16479 test_205a() { # Job stats
16480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16481         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16482                 skip "Need MDS version with at least 2.7.1"
16483         remote_mgs_nodsh && skip "remote MGS with nodsh"
16484         remote_mds_nodsh && skip "remote MDS with nodsh"
16485         remote_ost_nodsh && skip "remote OST with nodsh"
16486         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16487                 skip "Server doesn't support jobstats"
16488         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16489
16490         local old_jobenv=$($LCTL get_param -n jobid_var)
16491         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16492
16493         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16494                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16495         else
16496                 stack_trap "do_facet mgs $PERM_CMD \
16497                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16498         fi
16499         changelog_register
16500
16501         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16502                                 mdt.*.job_cleanup_interval | head -n 1)
16503         local new_interval=5
16504         do_facet $SINGLEMDS \
16505                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16506         stack_trap "do_facet $SINGLEMDS \
16507                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16508         local start=$SECONDS
16509
16510         local cmd
16511         # mkdir
16512         cmd="mkdir $DIR/$tdir"
16513         verify_jobstats "$cmd" "$SINGLEMDS"
16514         # rmdir
16515         cmd="rmdir $DIR/$tdir"
16516         verify_jobstats "$cmd" "$SINGLEMDS"
16517         # mkdir on secondary MDT
16518         if [ $MDSCOUNT -gt 1 ]; then
16519                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16520                 verify_jobstats "$cmd" "mds2"
16521         fi
16522         # mknod
16523         cmd="mknod $DIR/$tfile c 1 3"
16524         verify_jobstats "$cmd" "$SINGLEMDS"
16525         # unlink
16526         cmd="rm -f $DIR/$tfile"
16527         verify_jobstats "$cmd" "$SINGLEMDS"
16528         # create all files on OST0000 so verify_jobstats can find OST stats
16529         # open & close
16530         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16531         verify_jobstats "$cmd" "$SINGLEMDS"
16532         # setattr
16533         cmd="touch $DIR/$tfile"
16534         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16535         # write
16536         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16537         verify_jobstats "$cmd" "ost1"
16538         # read
16539         cancel_lru_locks osc
16540         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16541         verify_jobstats "$cmd" "ost1"
16542         # truncate
16543         cmd="$TRUNCATE $DIR/$tfile 0"
16544         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16545         # rename
16546         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16547         verify_jobstats "$cmd" "$SINGLEMDS"
16548         # jobstats expiry - sleep until old stats should be expired
16549         local left=$((new_interval + 5 - (SECONDS - start)))
16550         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16551                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16552                         "0" $left
16553         cmd="mkdir $DIR/$tdir.expire"
16554         verify_jobstats "$cmd" "$SINGLEMDS"
16555         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16556             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16557
16558         # Ensure that jobid are present in changelog (if supported by MDS)
16559         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16560                 changelog_dump | tail -10
16561                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16562                 [ $jobids -eq 9 ] ||
16563                         error "Wrong changelog jobid count $jobids != 9"
16564
16565                 # LU-5862
16566                 JOBENV="disable"
16567                 jobstats_set $JOBENV
16568                 touch $DIR/$tfile
16569                 changelog_dump | grep $tfile
16570                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16571                 [ $jobids -eq 0 ] ||
16572                         error "Unexpected jobids when jobid_var=$JOBENV"
16573         fi
16574
16575         # test '%j' access to environment variable - if supported
16576         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16577                 JOBENV="JOBCOMPLEX"
16578                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16579
16580                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16581         fi
16582
16583         # test '%j' access to per-session jobid - if supported
16584         if lctl list_param jobid_this_session > /dev/null 2>&1
16585         then
16586                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16587                 lctl set_param jobid_this_session=$USER
16588
16589                 JOBENV="JOBCOMPLEX"
16590                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16591
16592                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16593         fi
16594 }
16595 run_test 205a "Verify job stats"
16596
16597 # LU-13117, LU-13597
16598 test_205b() {
16599         job_stats="mdt.*.job_stats"
16600         $LCTL set_param $job_stats=clear
16601         # Setting jobid_var to USER might not be supported
16602         $LCTL set_param jobid_var=USER || true
16603         $LCTL set_param jobid_name="%e.%u"
16604         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16605         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16606                 grep "job_id:.*foolish" &&
16607                         error "Unexpected jobid found"
16608         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16609                 grep "open:.*min.*max.*sum" ||
16610                         error "wrong job_stats format found"
16611 }
16612 run_test 205b "Verify job stats jobid and output format"
16613
16614 # LU-13733
16615 test_205c() {
16616         $LCTL set_param llite.*.stats=0
16617         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16618         $LCTL get_param llite.*.stats
16619         $LCTL get_param llite.*.stats | grep \
16620                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16621                         error "wrong client stats format found"
16622 }
16623 run_test 205c "Verify client stats format"
16624
16625 # LU-1480, LU-1773 and LU-1657
16626 test_206() {
16627         mkdir -p $DIR/$tdir
16628         $LFS setstripe -c -1 $DIR/$tdir
16629 #define OBD_FAIL_LOV_INIT 0x1403
16630         $LCTL set_param fail_loc=0xa0001403
16631         $LCTL set_param fail_val=1
16632         touch $DIR/$tdir/$tfile || true
16633 }
16634 run_test 206 "fail lov_init_raid0() doesn't lbug"
16635
16636 test_207a() {
16637         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16638         local fsz=`stat -c %s $DIR/$tfile`
16639         cancel_lru_locks mdc
16640
16641         # do not return layout in getattr intent
16642 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16643         $LCTL set_param fail_loc=0x170
16644         local sz=`stat -c %s $DIR/$tfile`
16645
16646         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16647
16648         rm -rf $DIR/$tfile
16649 }
16650 run_test 207a "can refresh layout at glimpse"
16651
16652 test_207b() {
16653         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16654         local cksum=`md5sum $DIR/$tfile`
16655         local fsz=`stat -c %s $DIR/$tfile`
16656         cancel_lru_locks mdc
16657         cancel_lru_locks osc
16658
16659         # do not return layout in getattr intent
16660 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16661         $LCTL set_param fail_loc=0x171
16662
16663         # it will refresh layout after the file is opened but before read issues
16664         echo checksum is "$cksum"
16665         echo "$cksum" |md5sum -c --quiet || error "file differs"
16666
16667         rm -rf $DIR/$tfile
16668 }
16669 run_test 207b "can refresh layout at open"
16670
16671 test_208() {
16672         # FIXME: in this test suite, only RD lease is used. This is okay
16673         # for now as only exclusive open is supported. After generic lease
16674         # is done, this test suite should be revised. - Jinshan
16675
16676         remote_mds_nodsh && skip "remote MDS with nodsh"
16677         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16678                 skip "Need MDS version at least 2.4.52"
16679
16680         echo "==== test 1: verify get lease work"
16681         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16682
16683         echo "==== test 2: verify lease can be broken by upcoming open"
16684         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16685         local PID=$!
16686         sleep 1
16687
16688         $MULTIOP $DIR/$tfile oO_RDONLY:c
16689         kill -USR1 $PID && wait $PID || error "break lease error"
16690
16691         echo "==== test 3: verify lease can't be granted if an open already exists"
16692         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16693         local PID=$!
16694         sleep 1
16695
16696         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16697         kill -USR1 $PID && wait $PID || error "open file error"
16698
16699         echo "==== test 4: lease can sustain over recovery"
16700         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16701         PID=$!
16702         sleep 1
16703
16704         fail mds1
16705
16706         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16707
16708         echo "==== test 5: lease broken can't be regained by replay"
16709         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16710         PID=$!
16711         sleep 1
16712
16713         # open file to break lease and then recovery
16714         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16715         fail mds1
16716
16717         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16718
16719         rm -f $DIR/$tfile
16720 }
16721 run_test 208 "Exclusive open"
16722
16723 test_209() {
16724         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16725                 skip_env "must have disp_stripe"
16726
16727         touch $DIR/$tfile
16728         sync; sleep 5; sync;
16729
16730         echo 3 > /proc/sys/vm/drop_caches
16731         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16732                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16733         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16734
16735         # open/close 500 times
16736         for i in $(seq 500); do
16737                 cat $DIR/$tfile
16738         done
16739
16740         echo 3 > /proc/sys/vm/drop_caches
16741         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16742                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16743         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16744
16745         echo "before: $req_before, after: $req_after"
16746         [ $((req_after - req_before)) -ge 300 ] &&
16747                 error "open/close requests are not freed"
16748         return 0
16749 }
16750 run_test 209 "read-only open/close requests should be freed promptly"
16751
16752 test_210() {
16753         local pid
16754
16755         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16756         pid=$!
16757         sleep 1
16758
16759         $LFS getstripe $DIR/$tfile
16760         kill -USR1 $pid
16761         wait $pid || error "multiop failed"
16762
16763         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16764         pid=$!
16765         sleep 1
16766
16767         $LFS getstripe $DIR/$tfile
16768         kill -USR1 $pid
16769         wait $pid || error "multiop failed"
16770 }
16771 run_test 210 "lfs getstripe does not break leases"
16772
16773 test_212() {
16774         size=`date +%s`
16775         size=$((size % 8192 + 1))
16776         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16777         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16778         rm -f $DIR/f212 $DIR/f212.xyz
16779 }
16780 run_test 212 "Sendfile test ============================================"
16781
16782 test_213() {
16783         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16784         cancel_lru_locks osc
16785         lctl set_param fail_loc=0x8000040f
16786         # generate a read lock
16787         cat $DIR/$tfile > /dev/null
16788         # write to the file, it will try to cancel the above read lock.
16789         cat /etc/hosts >> $DIR/$tfile
16790 }
16791 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16792
16793 test_214() { # for bug 20133
16794         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16795         for (( i=0; i < 340; i++ )) ; do
16796                 touch $DIR/$tdir/d214c/a$i
16797         done
16798
16799         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16800         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16801         ls $DIR/d214c || error "ls $DIR/d214c failed"
16802         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16803         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16804 }
16805 run_test 214 "hash-indexed directory test - bug 20133"
16806
16807 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16808 create_lnet_proc_files() {
16809         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16810 }
16811
16812 # counterpart of create_lnet_proc_files
16813 remove_lnet_proc_files() {
16814         rm -f $TMP/lnet_$1.sys
16815 }
16816
16817 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16818 # 3rd arg as regexp for body
16819 check_lnet_proc_stats() {
16820         local l=$(cat "$TMP/lnet_$1" |wc -l)
16821         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16822
16823         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16824 }
16825
16826 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16827 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16828 # optional and can be regexp for 2nd line (lnet.routes case)
16829 check_lnet_proc_entry() {
16830         local blp=2          # blp stands for 'position of 1st line of body'
16831         [ -z "$5" ] || blp=3 # lnet.routes case
16832
16833         local l=$(cat "$TMP/lnet_$1" |wc -l)
16834         # subtracting one from $blp because the body can be empty
16835         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16836
16837         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16838                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16839
16840         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16841                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16842
16843         # bail out if any unexpected line happened
16844         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16845         [ "$?" != 0 ] || error "$2 misformatted"
16846 }
16847
16848 test_215() { # for bugs 18102, 21079, 21517
16849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16850
16851         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16852         local P='[1-9][0-9]*'           # positive numeric
16853         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16854         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16855         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16856         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16857
16858         local L1 # regexp for 1st line
16859         local L2 # regexp for 2nd line (optional)
16860         local BR # regexp for the rest (body)
16861
16862         # lnet.stats should look as 11 space-separated non-negative numerics
16863         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16864         create_lnet_proc_files "stats"
16865         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16866         remove_lnet_proc_files "stats"
16867
16868         # lnet.routes should look like this:
16869         # Routing disabled/enabled
16870         # net hops priority state router
16871         # where net is a string like tcp0, hops > 0, priority >= 0,
16872         # state is up/down,
16873         # router is a string like 192.168.1.1@tcp2
16874         L1="^Routing (disabled|enabled)$"
16875         L2="^net +hops +priority +state +router$"
16876         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16877         create_lnet_proc_files "routes"
16878         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16879         remove_lnet_proc_files "routes"
16880
16881         # lnet.routers should look like this:
16882         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16883         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16884         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16885         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16886         L1="^ref +rtr_ref +alive +router$"
16887         BR="^$P +$P +(up|down) +$NID$"
16888         create_lnet_proc_files "routers"
16889         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16890         remove_lnet_proc_files "routers"
16891
16892         # lnet.peers should look like this:
16893         # nid refs state last max rtr min tx min queue
16894         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16895         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16896         # numeric (0 or >0 or <0), queue >= 0.
16897         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16898         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16899         create_lnet_proc_files "peers"
16900         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16901         remove_lnet_proc_files "peers"
16902
16903         # lnet.buffers  should look like this:
16904         # pages count credits min
16905         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16906         L1="^pages +count +credits +min$"
16907         BR="^ +$N +$N +$I +$I$"
16908         create_lnet_proc_files "buffers"
16909         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16910         remove_lnet_proc_files "buffers"
16911
16912         # lnet.nis should look like this:
16913         # nid status alive refs peer rtr max tx min
16914         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16915         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16916         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16917         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16918         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16919         create_lnet_proc_files "nis"
16920         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16921         remove_lnet_proc_files "nis"
16922
16923         # can we successfully write to lnet.stats?
16924         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16925 }
16926 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16927
16928 test_216() { # bug 20317
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16930         remote_ost_nodsh && skip "remote OST with nodsh"
16931
16932         local node
16933         local facets=$(get_facets OST)
16934         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16935
16936         save_lustre_params client "osc.*.contention_seconds" > $p
16937         save_lustre_params $facets \
16938                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16939         save_lustre_params $facets \
16940                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16941         save_lustre_params $facets \
16942                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16943         clear_stats osc.*.osc_stats
16944
16945         # agressive lockless i/o settings
16946         do_nodes $(comma_list $(osts_nodes)) \
16947                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16948                         ldlm.namespaces.filter-*.contended_locks=0 \
16949                         ldlm.namespaces.filter-*.contention_seconds=60"
16950         lctl set_param -n osc.*.contention_seconds=60
16951
16952         $DIRECTIO write $DIR/$tfile 0 10 4096
16953         $CHECKSTAT -s 40960 $DIR/$tfile
16954
16955         # disable lockless i/o
16956         do_nodes $(comma_list $(osts_nodes)) \
16957                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16958                         ldlm.namespaces.filter-*.contended_locks=32 \
16959                         ldlm.namespaces.filter-*.contention_seconds=0"
16960         lctl set_param -n osc.*.contention_seconds=0
16961         clear_stats osc.*.osc_stats
16962
16963         dd if=/dev/zero of=$DIR/$tfile count=0
16964         $CHECKSTAT -s 0 $DIR/$tfile
16965
16966         restore_lustre_params <$p
16967         rm -f $p
16968         rm $DIR/$tfile
16969 }
16970 run_test 216 "check lockless direct write updates file size and kms correctly"
16971
16972 test_217() { # bug 22430
16973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16974
16975         local node
16976         local nid
16977
16978         for node in $(nodes_list); do
16979                 nid=$(host_nids_address $node $NETTYPE)
16980                 if [[ $nid = *-* ]] ; then
16981                         echo "lctl ping $(h2nettype $nid)"
16982                         lctl ping $(h2nettype $nid)
16983                 else
16984                         echo "skipping $node (no hyphen detected)"
16985                 fi
16986         done
16987 }
16988 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16989
16990 test_218() {
16991        # do directio so as not to populate the page cache
16992        log "creating a 10 Mb file"
16993        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || 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 || error "multiop failed while truncating the file"
16998        log "killing dd"
16999        kill %+ || true # reads might have finished
17000        echo "wait until dd is finished"
17001        wait
17002        log "removing the temporary file"
17003        rm -rf $DIR/$tfile || error "tmp file removal failed"
17004 }
17005 run_test 218 "parallel read and truncate should not deadlock"
17006
17007 test_219() {
17008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17009
17010         # write one partial page
17011         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17012         # set no grant so vvp_io_commit_write will do sync write
17013         $LCTL set_param fail_loc=0x411
17014         # write a full page at the end of file
17015         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17016
17017         $LCTL set_param fail_loc=0
17018         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17019         $LCTL set_param fail_loc=0x411
17020         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17021
17022         # LU-4201
17023         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17024         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17025 }
17026 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17027
17028 test_220() { #LU-325
17029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17030         remote_ost_nodsh && skip "remote OST with nodsh"
17031         remote_mds_nodsh && skip "remote MDS with nodsh"
17032         remote_mgs_nodsh && skip "remote MGS with nodsh"
17033
17034         local OSTIDX=0
17035
17036         # create on MDT0000 so the last_id and next_id are correct
17037         mkdir $DIR/$tdir
17038         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17039         OST=${OST%_UUID}
17040
17041         # on the mdt's osc
17042         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17043         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17044                         osp.$mdtosc_proc1.prealloc_last_id)
17045         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17046                         osp.$mdtosc_proc1.prealloc_next_id)
17047
17048         $LFS df -i
17049
17050         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17051         #define OBD_FAIL_OST_ENOINO              0x229
17052         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17053         create_pool $FSNAME.$TESTNAME || return 1
17054         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17055
17056         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17057
17058         MDSOBJS=$((last_id - next_id))
17059         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17060
17061         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17062         echo "OST still has $count kbytes free"
17063
17064         echo "create $MDSOBJS files @next_id..."
17065         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17066
17067         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17068                         osp.$mdtosc_proc1.prealloc_last_id)
17069         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17070                         osp.$mdtosc_proc1.prealloc_next_id)
17071
17072         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17073         $LFS df -i
17074
17075         echo "cleanup..."
17076
17077         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17078         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17079
17080         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17081                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17082         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17083                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17084         echo "unlink $MDSOBJS files @$next_id..."
17085         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17086 }
17087 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17088
17089 test_221() {
17090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17091
17092         dd if=`which date` of=$MOUNT/date oflag=sync
17093         chmod +x $MOUNT/date
17094
17095         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17096         $LCTL set_param fail_loc=0x80001401
17097
17098         $MOUNT/date > /dev/null
17099         rm -f $MOUNT/date
17100 }
17101 run_test 221 "make sure fault and truncate race to not cause OOM"
17102
17103 test_222a () {
17104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17105
17106         rm -rf $DIR/$tdir
17107         test_mkdir $DIR/$tdir
17108         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17109         createmany -o $DIR/$tdir/$tfile 10
17110         cancel_lru_locks mdc
17111         cancel_lru_locks osc
17112         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17113         $LCTL set_param fail_loc=0x31a
17114         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17115         $LCTL set_param fail_loc=0
17116         rm -r $DIR/$tdir
17117 }
17118 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17119
17120 test_222b () {
17121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17122
17123         rm -rf $DIR/$tdir
17124         test_mkdir $DIR/$tdir
17125         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17126         createmany -o $DIR/$tdir/$tfile 10
17127         cancel_lru_locks mdc
17128         cancel_lru_locks osc
17129         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17130         $LCTL set_param fail_loc=0x31a
17131         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17132         $LCTL set_param fail_loc=0
17133 }
17134 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17135
17136 test_223 () {
17137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17138
17139         rm -rf $DIR/$tdir
17140         test_mkdir $DIR/$tdir
17141         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17142         createmany -o $DIR/$tdir/$tfile 10
17143         cancel_lru_locks mdc
17144         cancel_lru_locks osc
17145         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17146         $LCTL set_param fail_loc=0x31b
17147         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17148         $LCTL set_param fail_loc=0
17149         rm -r $DIR/$tdir
17150 }
17151 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17152
17153 test_224a() { # LU-1039, MRP-303
17154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17155
17156         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17157         $LCTL set_param fail_loc=0x508
17158         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17159         $LCTL set_param fail_loc=0
17160         df $DIR
17161 }
17162 run_test 224a "Don't panic on bulk IO failure"
17163
17164 test_224b() { # LU-1039, MRP-303
17165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17166
17167         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17168         cancel_lru_locks osc
17169         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17170         $LCTL set_param fail_loc=0x515
17171         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17172         $LCTL set_param fail_loc=0
17173         df $DIR
17174 }
17175 run_test 224b "Don't panic on bulk IO failure"
17176
17177 test_224c() { # LU-6441
17178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17179         remote_mds_nodsh && skip "remote MDS with nodsh"
17180
17181         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17182         save_writethrough $p
17183         set_cache writethrough on
17184
17185         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17186         local at_max=$($LCTL get_param -n at_max)
17187         local timeout=$($LCTL get_param -n timeout)
17188         local test_at="at_max"
17189         local param_at="$FSNAME.sys.at_max"
17190         local test_timeout="timeout"
17191         local param_timeout="$FSNAME.sys.timeout"
17192
17193         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17194
17195         set_persistent_param_and_check client "$test_at" "$param_at" 0
17196         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17197
17198         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17199         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17200         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17201         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17202         sync
17203         do_facet ost1 "$LCTL set_param fail_loc=0"
17204
17205         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17206         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17207                 $timeout
17208
17209         $LCTL set_param -n $pages_per_rpc
17210         restore_lustre_params < $p
17211         rm -f $p
17212 }
17213 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17214
17215 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17216 test_225a () {
17217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17218         if [ -z ${MDSSURVEY} ]; then
17219                 skip_env "mds-survey not found"
17220         fi
17221         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17222                 skip "Need MDS version at least 2.2.51"
17223
17224         local mds=$(facet_host $SINGLEMDS)
17225         local target=$(do_nodes $mds 'lctl dl' |
17226                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17227
17228         local cmd1="file_count=1000 thrhi=4"
17229         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17230         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17231         local cmd="$cmd1 $cmd2 $cmd3"
17232
17233         rm -f ${TMP}/mds_survey*
17234         echo + $cmd
17235         eval $cmd || error "mds-survey with zero-stripe failed"
17236         cat ${TMP}/mds_survey*
17237         rm -f ${TMP}/mds_survey*
17238 }
17239 run_test 225a "Metadata survey sanity with zero-stripe"
17240
17241 test_225b () {
17242         if [ -z ${MDSSURVEY} ]; then
17243                 skip_env "mds-survey not found"
17244         fi
17245         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17246                 skip "Need MDS version at least 2.2.51"
17247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17248         remote_mds_nodsh && skip "remote MDS with nodsh"
17249         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17250                 skip_env "Need to mount OST to test"
17251         fi
17252
17253         local mds=$(facet_host $SINGLEMDS)
17254         local target=$(do_nodes $mds 'lctl dl' |
17255                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17256
17257         local cmd1="file_count=1000 thrhi=4"
17258         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17259         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17260         local cmd="$cmd1 $cmd2 $cmd3"
17261
17262         rm -f ${TMP}/mds_survey*
17263         echo + $cmd
17264         eval $cmd || error "mds-survey with stripe_count failed"
17265         cat ${TMP}/mds_survey*
17266         rm -f ${TMP}/mds_survey*
17267 }
17268 run_test 225b "Metadata survey sanity with stripe_count = 1"
17269
17270 mcreate_path2fid () {
17271         local mode=$1
17272         local major=$2
17273         local minor=$3
17274         local name=$4
17275         local desc=$5
17276         local path=$DIR/$tdir/$name
17277         local fid
17278         local rc
17279         local fid_path
17280
17281         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17282                 error "cannot create $desc"
17283
17284         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17285         rc=$?
17286         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17287
17288         fid_path=$($LFS fid2path $MOUNT $fid)
17289         rc=$?
17290         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17291
17292         [ "$path" == "$fid_path" ] ||
17293                 error "fid2path returned $fid_path, expected $path"
17294
17295         echo "pass with $path and $fid"
17296 }
17297
17298 test_226a () {
17299         rm -rf $DIR/$tdir
17300         mkdir -p $DIR/$tdir
17301
17302         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17303         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17304         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17305         mcreate_path2fid 0040666 0 0 dir "directory"
17306         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17307         mcreate_path2fid 0100666 0 0 file "regular file"
17308         mcreate_path2fid 0120666 0 0 link "symbolic link"
17309         mcreate_path2fid 0140666 0 0 sock "socket"
17310 }
17311 run_test 226a "call path2fid and fid2path on files of all type"
17312
17313 test_226b () {
17314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17315
17316         local MDTIDX=1
17317
17318         rm -rf $DIR/$tdir
17319         mkdir -p $DIR/$tdir
17320         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17321                 error "create remote directory failed"
17322         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17323         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17324                                 "character special file (null)"
17325         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17326                                 "character special file (no device)"
17327         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17328         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17329                                 "block special file (loop)"
17330         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17331         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17332         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17333 }
17334 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17335
17336 test_226c () {
17337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17338         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17339                 skip "Need MDS version at least 2.13.55"
17340
17341         local submnt=/mnt/submnt
17342         local srcfile=/etc/passwd
17343         local dstfile=$submnt/passwd
17344         local path
17345         local fid
17346
17347         rm -rf $DIR/$tdir
17348         rm -rf $submnt
17349         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17350                 error "create remote directory failed"
17351         mkdir -p $submnt || error "create $submnt failed"
17352         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17353                 error "mount $submnt failed"
17354         stack_trap "umount $submnt" EXIT
17355
17356         cp $srcfile $dstfile
17357         fid=$($LFS path2fid $dstfile)
17358         path=$($LFS fid2path $submnt "$fid")
17359         [ "$path" = "$dstfile" ] ||
17360                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17361 }
17362 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17363
17364 # LU-1299 Executing or running ldd on a truncated executable does not
17365 # cause an out-of-memory condition.
17366 test_227() {
17367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17368         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17369
17370         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17371         chmod +x $MOUNT/date
17372
17373         $MOUNT/date > /dev/null
17374         ldd $MOUNT/date > /dev/null
17375         rm -f $MOUNT/date
17376 }
17377 run_test 227 "running truncated executable does not cause OOM"
17378
17379 # LU-1512 try to reuse idle OI blocks
17380 test_228a() {
17381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17382         remote_mds_nodsh && skip "remote MDS with nodsh"
17383         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17384
17385         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17386         local myDIR=$DIR/$tdir
17387
17388         mkdir -p $myDIR
17389         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17390         $LCTL set_param fail_loc=0x80001002
17391         createmany -o $myDIR/t- 10000
17392         $LCTL set_param fail_loc=0
17393         # The guard is current the largest FID holder
17394         touch $myDIR/guard
17395         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17396                     tr -d '[')
17397         local IDX=$(($SEQ % 64))
17398
17399         do_facet $SINGLEMDS sync
17400         # Make sure journal flushed.
17401         sleep 6
17402         local blk1=$(do_facet $SINGLEMDS \
17403                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17404                      grep Blockcount | awk '{print $4}')
17405
17406         # Remove old files, some OI blocks will become idle.
17407         unlinkmany $myDIR/t- 10000
17408         # Create new files, idle OI blocks should be reused.
17409         createmany -o $myDIR/t- 2000
17410         do_facet $SINGLEMDS sync
17411         # Make sure journal flushed.
17412         sleep 6
17413         local blk2=$(do_facet $SINGLEMDS \
17414                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17415                      grep Blockcount | awk '{print $4}')
17416
17417         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17418 }
17419 run_test 228a "try to reuse idle OI blocks"
17420
17421 test_228b() {
17422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17423         remote_mds_nodsh && skip "remote MDS with nodsh"
17424         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17425
17426         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17427         local myDIR=$DIR/$tdir
17428
17429         mkdir -p $myDIR
17430         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17431         $LCTL set_param fail_loc=0x80001002
17432         createmany -o $myDIR/t- 10000
17433         $LCTL set_param fail_loc=0
17434         # The guard is current the largest FID holder
17435         touch $myDIR/guard
17436         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17437                     tr -d '[')
17438         local IDX=$(($SEQ % 64))
17439
17440         do_facet $SINGLEMDS sync
17441         # Make sure journal flushed.
17442         sleep 6
17443         local blk1=$(do_facet $SINGLEMDS \
17444                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17445                      grep Blockcount | awk '{print $4}')
17446
17447         # Remove old files, some OI blocks will become idle.
17448         unlinkmany $myDIR/t- 10000
17449
17450         # stop the MDT
17451         stop $SINGLEMDS || error "Fail to stop MDT."
17452         # remount the MDT
17453         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17454
17455         df $MOUNT || error "Fail to df."
17456         # Create new files, idle OI blocks should be reused.
17457         createmany -o $myDIR/t- 2000
17458         do_facet $SINGLEMDS sync
17459         # Make sure journal flushed.
17460         sleep 6
17461         local blk2=$(do_facet $SINGLEMDS \
17462                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17463                      grep Blockcount | awk '{print $4}')
17464
17465         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17466 }
17467 run_test 228b "idle OI blocks can be reused after MDT restart"
17468
17469 #LU-1881
17470 test_228c() {
17471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17472         remote_mds_nodsh && skip "remote MDS with nodsh"
17473         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17474
17475         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17476         local myDIR=$DIR/$tdir
17477
17478         mkdir -p $myDIR
17479         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17480         $LCTL set_param fail_loc=0x80001002
17481         # 20000 files can guarantee there are index nodes in the OI file
17482         createmany -o $myDIR/t- 20000
17483         $LCTL set_param fail_loc=0
17484         # The guard is current the largest FID holder
17485         touch $myDIR/guard
17486         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17487                     tr -d '[')
17488         local IDX=$(($SEQ % 64))
17489
17490         do_facet $SINGLEMDS sync
17491         # Make sure journal flushed.
17492         sleep 6
17493         local blk1=$(do_facet $SINGLEMDS \
17494                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17495                      grep Blockcount | awk '{print $4}')
17496
17497         # Remove old files, some OI blocks will become idle.
17498         unlinkmany $myDIR/t- 20000
17499         rm -f $myDIR/guard
17500         # The OI file should become empty now
17501
17502         # Create new files, idle OI blocks should be reused.
17503         createmany -o $myDIR/t- 2000
17504         do_facet $SINGLEMDS sync
17505         # Make sure journal flushed.
17506         sleep 6
17507         local blk2=$(do_facet $SINGLEMDS \
17508                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17509                      grep Blockcount | awk '{print $4}')
17510
17511         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17512 }
17513 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17514
17515 test_229() { # LU-2482, LU-3448
17516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17517         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17518         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17519                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17520
17521         rm -f $DIR/$tfile
17522
17523         # Create a file with a released layout and stripe count 2.
17524         $MULTIOP $DIR/$tfile H2c ||
17525                 error "failed to create file with released layout"
17526
17527         $LFS getstripe -v $DIR/$tfile
17528
17529         local pattern=$($LFS getstripe -L $DIR/$tfile)
17530         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17531
17532         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17533                 error "getstripe"
17534         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17535         stat $DIR/$tfile || error "failed to stat released file"
17536
17537         chown $RUNAS_ID $DIR/$tfile ||
17538                 error "chown $RUNAS_ID $DIR/$tfile failed"
17539
17540         chgrp $RUNAS_ID $DIR/$tfile ||
17541                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17542
17543         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17544         rm $DIR/$tfile || error "failed to remove released file"
17545 }
17546 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17547
17548 test_230a() {
17549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17551         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17552                 skip "Need MDS version at least 2.11.52"
17553
17554         local MDTIDX=1
17555
17556         test_mkdir $DIR/$tdir
17557         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17558         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17559         [ $mdt_idx -ne 0 ] &&
17560                 error "create local directory on wrong MDT $mdt_idx"
17561
17562         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17563                         error "create remote directory failed"
17564         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17565         [ $mdt_idx -ne $MDTIDX ] &&
17566                 error "create remote directory on wrong MDT $mdt_idx"
17567
17568         createmany -o $DIR/$tdir/test_230/t- 10 ||
17569                 error "create files on remote directory failed"
17570         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17571         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17572         rm -r $DIR/$tdir || error "unlink remote directory failed"
17573 }
17574 run_test 230a "Create remote directory and files under the remote directory"
17575
17576 test_230b() {
17577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17579         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17580                 skip "Need MDS version at least 2.11.52"
17581
17582         local MDTIDX=1
17583         local mdt_index
17584         local i
17585         local file
17586         local pid
17587         local stripe_count
17588         local migrate_dir=$DIR/$tdir/migrate_dir
17589         local other_dir=$DIR/$tdir/other_dir
17590
17591         test_mkdir $DIR/$tdir
17592         test_mkdir -i0 -c1 $migrate_dir
17593         test_mkdir -i0 -c1 $other_dir
17594         for ((i=0; i<10; i++)); do
17595                 mkdir -p $migrate_dir/dir_${i}
17596                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17597                         error "create files under remote dir failed $i"
17598         done
17599
17600         cp /etc/passwd $migrate_dir/$tfile
17601         cp /etc/passwd $other_dir/$tfile
17602         chattr +SAD $migrate_dir
17603         chattr +SAD $migrate_dir/$tfile
17604
17605         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17606         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17607         local old_dir_mode=$(stat -c%f $migrate_dir)
17608         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17609
17610         mkdir -p $migrate_dir/dir_default_stripe2
17611         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17612         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17613
17614         mkdir -p $other_dir
17615         ln $migrate_dir/$tfile $other_dir/luna
17616         ln $migrate_dir/$tfile $migrate_dir/sofia
17617         ln $other_dir/$tfile $migrate_dir/david
17618         ln -s $migrate_dir/$tfile $other_dir/zachary
17619         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17620         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17621
17622         local len
17623         local lnktgt
17624
17625         # inline symlink
17626         for len in 58 59 60; do
17627                 lnktgt=$(str_repeat 'l' $len)
17628                 touch $migrate_dir/$lnktgt
17629                 ln -s $lnktgt $migrate_dir/${len}char_ln
17630         done
17631
17632         # PATH_MAX
17633         for len in 4094 4095; do
17634                 lnktgt=$(str_repeat 'l' $len)
17635                 ln -s $lnktgt $migrate_dir/${len}char_ln
17636         done
17637
17638         # NAME_MAX
17639         for len in 254 255; do
17640                 touch $migrate_dir/$(str_repeat 'l' $len)
17641         done
17642
17643         $LFS migrate -m $MDTIDX $migrate_dir ||
17644                 error "fails on migrating remote dir to MDT1"
17645
17646         echo "migratate to MDT1, then checking.."
17647         for ((i = 0; i < 10; i++)); do
17648                 for file in $(find $migrate_dir/dir_${i}); do
17649                         mdt_index=$($LFS getstripe -m $file)
17650                         # broken symlink getstripe will fail
17651                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17652                                 error "$file is not on MDT${MDTIDX}"
17653                 done
17654         done
17655
17656         # the multiple link file should still in MDT0
17657         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17658         [ $mdt_index == 0 ] ||
17659                 error "$file is not on MDT${MDTIDX}"
17660
17661         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17662         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17663                 error " expect $old_dir_flag get $new_dir_flag"
17664
17665         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17666         [ "$old_file_flag" = "$new_file_flag" ] ||
17667                 error " expect $old_file_flag get $new_file_flag"
17668
17669         local new_dir_mode=$(stat -c%f $migrate_dir)
17670         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17671                 error "expect mode $old_dir_mode get $new_dir_mode"
17672
17673         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17674         [ "$old_file_mode" = "$new_file_mode" ] ||
17675                 error "expect mode $old_file_mode get $new_file_mode"
17676
17677         diff /etc/passwd $migrate_dir/$tfile ||
17678                 error "$tfile different after migration"
17679
17680         diff /etc/passwd $other_dir/luna ||
17681                 error "luna different after migration"
17682
17683         diff /etc/passwd $migrate_dir/sofia ||
17684                 error "sofia different after migration"
17685
17686         diff /etc/passwd $migrate_dir/david ||
17687                 error "david different after migration"
17688
17689         diff /etc/passwd $other_dir/zachary ||
17690                 error "zachary different after migration"
17691
17692         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17693                 error "${tfile}_ln different after migration"
17694
17695         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17696                 error "${tfile}_ln_other different after migration"
17697
17698         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17699         [ $stripe_count = 2 ] ||
17700                 error "dir strpe_count $d != 2 after migration."
17701
17702         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17703         [ $stripe_count = 2 ] ||
17704                 error "file strpe_count $d != 2 after migration."
17705
17706         #migrate back to MDT0
17707         MDTIDX=0
17708
17709         $LFS migrate -m $MDTIDX $migrate_dir ||
17710                 error "fails on migrating remote dir to MDT0"
17711
17712         echo "migrate back to MDT0, checking.."
17713         for file in $(find $migrate_dir); do
17714                 mdt_index=$($LFS getstripe -m $file)
17715                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17716                         error "$file is not on MDT${MDTIDX}"
17717         done
17718
17719         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17720         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17721                 error " expect $old_dir_flag get $new_dir_flag"
17722
17723         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17724         [ "$old_file_flag" = "$new_file_flag" ] ||
17725                 error " expect $old_file_flag get $new_file_flag"
17726
17727         local new_dir_mode=$(stat -c%f $migrate_dir)
17728         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17729                 error "expect mode $old_dir_mode get $new_dir_mode"
17730
17731         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17732         [ "$old_file_mode" = "$new_file_mode" ] ||
17733                 error "expect mode $old_file_mode get $new_file_mode"
17734
17735         diff /etc/passwd ${migrate_dir}/$tfile ||
17736                 error "$tfile different after migration"
17737
17738         diff /etc/passwd ${other_dir}/luna ||
17739                 error "luna different after migration"
17740
17741         diff /etc/passwd ${migrate_dir}/sofia ||
17742                 error "sofia different after migration"
17743
17744         diff /etc/passwd ${other_dir}/zachary ||
17745                 error "zachary different after migration"
17746
17747         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17748                 error "${tfile}_ln different after migration"
17749
17750         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17751                 error "${tfile}_ln_other different after migration"
17752
17753         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17754         [ $stripe_count = 2 ] ||
17755                 error "dir strpe_count $d != 2 after migration."
17756
17757         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17758         [ $stripe_count = 2 ] ||
17759                 error "file strpe_count $d != 2 after migration."
17760
17761         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17762 }
17763 run_test 230b "migrate directory"
17764
17765 test_230c() {
17766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17768         remote_mds_nodsh && skip "remote MDS with nodsh"
17769         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17770                 skip "Need MDS version at least 2.11.52"
17771
17772         local MDTIDX=1
17773         local total=3
17774         local mdt_index
17775         local file
17776         local migrate_dir=$DIR/$tdir/migrate_dir
17777
17778         #If migrating directory fails in the middle, all entries of
17779         #the directory is still accessiable.
17780         test_mkdir $DIR/$tdir
17781         test_mkdir -i0 -c1 $migrate_dir
17782         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17783         stat $migrate_dir
17784         createmany -o $migrate_dir/f $total ||
17785                 error "create files under ${migrate_dir} failed"
17786
17787         # fail after migrating top dir, and this will fail only once, so the
17788         # first sub file migration will fail (currently f3), others succeed.
17789         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17790         do_facet mds1 lctl set_param fail_loc=0x1801
17791         local t=$(ls $migrate_dir | wc -l)
17792         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17793                 error "migrate should fail"
17794         local u=$(ls $migrate_dir | wc -l)
17795         [ "$u" == "$t" ] || error "$u != $t during migration"
17796
17797         # add new dir/file should succeed
17798         mkdir $migrate_dir/dir ||
17799                 error "mkdir failed under migrating directory"
17800         touch $migrate_dir/file ||
17801                 error "create file failed under migrating directory"
17802
17803         # add file with existing name should fail
17804         for file in $migrate_dir/f*; do
17805                 stat $file > /dev/null || error "stat $file failed"
17806                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17807                         error "open(O_CREAT|O_EXCL) $file should fail"
17808                 $MULTIOP $file m && error "create $file should fail"
17809                 touch $DIR/$tdir/remote_dir/$tfile ||
17810                         error "touch $tfile failed"
17811                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17812                         error "link $file should fail"
17813                 mdt_index=$($LFS getstripe -m $file)
17814                 if [ $mdt_index == 0 ]; then
17815                         # file failed to migrate is not allowed to rename to
17816                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17817                                 error "rename to $file should fail"
17818                 else
17819                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17820                                 error "rename to $file failed"
17821                 fi
17822                 echo hello >> $file || error "write $file failed"
17823         done
17824
17825         # resume migration with different options should fail
17826         $LFS migrate -m 0 $migrate_dir &&
17827                 error "migrate -m 0 $migrate_dir should fail"
17828
17829         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17830                 error "migrate -c 2 $migrate_dir should fail"
17831
17832         # resume migration should succeed
17833         $LFS migrate -m $MDTIDX $migrate_dir ||
17834                 error "migrate $migrate_dir failed"
17835
17836         echo "Finish migration, then checking.."
17837         for file in $(find $migrate_dir); do
17838                 mdt_index=$($LFS getstripe -m $file)
17839                 [ $mdt_index == $MDTIDX ] ||
17840                         error "$file is not on MDT${MDTIDX}"
17841         done
17842
17843         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17844 }
17845 run_test 230c "check directory accessiblity if migration failed"
17846
17847 test_230d() {
17848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17850         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17851                 skip "Need MDS version at least 2.11.52"
17852         # LU-11235
17853         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17854
17855         local migrate_dir=$DIR/$tdir/migrate_dir
17856         local old_index
17857         local new_index
17858         local old_count
17859         local new_count
17860         local new_hash
17861         local mdt_index
17862         local i
17863         local j
17864
17865         old_index=$((RANDOM % MDSCOUNT))
17866         old_count=$((MDSCOUNT - old_index))
17867         new_index=$((RANDOM % MDSCOUNT))
17868         new_count=$((MDSCOUNT - new_index))
17869         new_hash=1 # for all_char
17870
17871         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17872         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17873
17874         test_mkdir $DIR/$tdir
17875         test_mkdir -i $old_index -c $old_count $migrate_dir
17876
17877         for ((i=0; i<100; i++)); do
17878                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17879                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17880                         error "create files under remote dir failed $i"
17881         done
17882
17883         echo -n "Migrate from MDT$old_index "
17884         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17885         echo -n "to MDT$new_index"
17886         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17887         echo
17888
17889         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17890         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17891                 error "migrate remote dir error"
17892
17893         echo "Finish migration, then checking.."
17894         for file in $(find $migrate_dir); do
17895                 mdt_index=$($LFS getstripe -m $file)
17896                 if [ $mdt_index -lt $new_index ] ||
17897                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17898                         error "$file is on MDT$mdt_index"
17899                 fi
17900         done
17901
17902         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17903 }
17904 run_test 230d "check migrate big directory"
17905
17906 test_230e() {
17907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17909         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17910                 skip "Need MDS version at least 2.11.52"
17911
17912         local i
17913         local j
17914         local a_fid
17915         local b_fid
17916
17917         mkdir -p $DIR/$tdir
17918         mkdir $DIR/$tdir/migrate_dir
17919         mkdir $DIR/$tdir/other_dir
17920         touch $DIR/$tdir/migrate_dir/a
17921         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17922         ls $DIR/$tdir/other_dir
17923
17924         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17925                 error "migrate dir fails"
17926
17927         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17928         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17929
17930         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17931         [ $mdt_index == 0 ] || error "a is not on MDT0"
17932
17933         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17934                 error "migrate dir fails"
17935
17936         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17937         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17938
17939         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17940         [ $mdt_index == 1 ] || error "a is not on MDT1"
17941
17942         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17943         [ $mdt_index == 1 ] || error "b is not on MDT1"
17944
17945         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17946         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17947
17948         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17949
17950         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17951 }
17952 run_test 230e "migrate mulitple local link files"
17953
17954 test_230f() {
17955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17956         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17957         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17958                 skip "Need MDS version at least 2.11.52"
17959
17960         local a_fid
17961         local ln_fid
17962
17963         mkdir -p $DIR/$tdir
17964         mkdir $DIR/$tdir/migrate_dir
17965         $LFS mkdir -i1 $DIR/$tdir/other_dir
17966         touch $DIR/$tdir/migrate_dir/a
17967         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17968         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17969         ls $DIR/$tdir/other_dir
17970
17971         # a should be migrated to MDT1, since no other links on MDT0
17972         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17973                 error "#1 migrate dir fails"
17974         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17975         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17976         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17977         [ $mdt_index == 1 ] || error "a is not on MDT1"
17978
17979         # a should stay on MDT1, because it is a mulitple link file
17980         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17981                 error "#2 migrate dir fails"
17982         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17983         [ $mdt_index == 1 ] || error "a is not on MDT1"
17984
17985         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17986                 error "#3 migrate dir fails"
17987
17988         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17989         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17990         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17991
17992         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17993         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17994
17995         # a should be migrated to MDT0, since no other links on MDT1
17996         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17997                 error "#4 migrate dir fails"
17998         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17999         [ $mdt_index == 0 ] || error "a is not on MDT0"
18000
18001         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18002 }
18003 run_test 230f "migrate mulitple remote link files"
18004
18005 test_230g() {
18006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18008         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18009                 skip "Need MDS version at least 2.11.52"
18010
18011         mkdir -p $DIR/$tdir/migrate_dir
18012
18013         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18014                 error "migrating dir to non-exist MDT succeeds"
18015         true
18016 }
18017 run_test 230g "migrate dir to non-exist MDT"
18018
18019 test_230h() {
18020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18021         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18022         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18023                 skip "Need MDS version at least 2.11.52"
18024
18025         local mdt_index
18026
18027         mkdir -p $DIR/$tdir/migrate_dir
18028
18029         $LFS migrate -m1 $DIR &&
18030                 error "migrating mountpoint1 should fail"
18031
18032         $LFS migrate -m1 $DIR/$tdir/.. &&
18033                 error "migrating mountpoint2 should fail"
18034
18035         # same as mv
18036         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18037                 error "migrating $tdir/migrate_dir/.. should fail"
18038
18039         true
18040 }
18041 run_test 230h "migrate .. and root"
18042
18043 test_230i() {
18044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18046         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18047                 skip "Need MDS version at least 2.11.52"
18048
18049         mkdir -p $DIR/$tdir/migrate_dir
18050
18051         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18052                 error "migration fails with a tailing slash"
18053
18054         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18055                 error "migration fails with two tailing slashes"
18056 }
18057 run_test 230i "lfs migrate -m tolerates trailing slashes"
18058
18059 test_230j() {
18060         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18061         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18062                 skip "Need MDS version at least 2.11.52"
18063
18064         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18065         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18066                 error "create $tfile failed"
18067         cat /etc/passwd > $DIR/$tdir/$tfile
18068
18069         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18070
18071         cmp /etc/passwd $DIR/$tdir/$tfile ||
18072                 error "DoM file mismatch after migration"
18073 }
18074 run_test 230j "DoM file data not changed after dir migration"
18075
18076 test_230k() {
18077         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18078         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18079                 skip "Need MDS version at least 2.11.56"
18080
18081         local total=20
18082         local files_on_starting_mdt=0
18083
18084         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18085         $LFS getdirstripe $DIR/$tdir
18086         for i in $(seq $total); do
18087                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18088                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18089                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18090         done
18091
18092         echo "$files_on_starting_mdt files on MDT0"
18093
18094         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18095         $LFS getdirstripe $DIR/$tdir
18096
18097         files_on_starting_mdt=0
18098         for i in $(seq $total); do
18099                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18100                         error "file $tfile.$i mismatch after migration"
18101                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18102                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18103         done
18104
18105         echo "$files_on_starting_mdt files on MDT1 after migration"
18106         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18107
18108         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18109         $LFS getdirstripe $DIR/$tdir
18110
18111         files_on_starting_mdt=0
18112         for i in $(seq $total); do
18113                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18114                         error "file $tfile.$i mismatch after 2nd migration"
18115                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18116                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18117         done
18118
18119         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18120         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18121
18122         true
18123 }
18124 run_test 230k "file data not changed after dir migration"
18125
18126 test_230l() {
18127         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18128         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18129                 skip "Need MDS version at least 2.11.56"
18130
18131         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18132         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18133                 error "create files under remote dir failed $i"
18134         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18135 }
18136 run_test 230l "readdir between MDTs won't crash"
18137
18138 test_230m() {
18139         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18140         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18141                 skip "Need MDS version at least 2.11.56"
18142
18143         local MDTIDX=1
18144         local mig_dir=$DIR/$tdir/migrate_dir
18145         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18146         local shortstr="b"
18147         local val
18148
18149         echo "Creating files and dirs with xattrs"
18150         test_mkdir $DIR/$tdir
18151         test_mkdir -i0 -c1 $mig_dir
18152         mkdir $mig_dir/dir
18153         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18154                 error "cannot set xattr attr1 on dir"
18155         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18156                 error "cannot set xattr attr2 on dir"
18157         touch $mig_dir/dir/f0
18158         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18159                 error "cannot set xattr attr1 on file"
18160         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18161                 error "cannot set xattr attr2 on file"
18162         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18163         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18164         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18165         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18166         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18167         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18168         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18169         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18170         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18171
18172         echo "Migrating to MDT1"
18173         $LFS migrate -m $MDTIDX $mig_dir ||
18174                 error "fails on migrating dir to MDT1"
18175
18176         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18177         echo "Checking xattrs"
18178         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18179         [ "$val" = $longstr ] ||
18180                 error "expecting xattr1 $longstr on dir, found $val"
18181         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18182         [ "$val" = $shortstr ] ||
18183                 error "expecting xattr2 $shortstr on dir, found $val"
18184         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18185         [ "$val" = $longstr ] ||
18186                 error "expecting xattr1 $longstr on file, found $val"
18187         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18188         [ "$val" = $shortstr ] ||
18189                 error "expecting xattr2 $shortstr on file, found $val"
18190 }
18191 run_test 230m "xattrs not changed after dir migration"
18192
18193 test_230n() {
18194         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18195         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18196                 skip "Need MDS version at least 2.13.53"
18197
18198         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18199         cat /etc/hosts > $DIR/$tdir/$tfile
18200         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18201         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18202
18203         cmp /etc/hosts $DIR/$tdir/$tfile ||
18204                 error "File data mismatch after migration"
18205 }
18206 run_test 230n "Dir migration with mirrored file"
18207
18208 test_230o() {
18209         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18210         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18211                 skip "Need MDS version at least 2.13.52"
18212
18213         local mdts=$(comma_list $(mdts_nodes))
18214         local timeout=100
18215
18216         local restripe_status
18217         local delta
18218         local i
18219         local j
18220
18221         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18222
18223         # in case "crush" hash type is not set
18224         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18225
18226         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18227                            mdt.*MDT0000.enable_dir_restripe)
18228         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18229         stack_trap "do_nodes $mdts $LCTL set_param \
18230                     mdt.*.enable_dir_restripe=$restripe_status"
18231
18232         mkdir $DIR/$tdir
18233         createmany -m $DIR/$tdir/f 100 ||
18234                 error "create files under remote dir failed $i"
18235         createmany -d $DIR/$tdir/d 100 ||
18236                 error "create dirs under remote dir failed $i"
18237
18238         for i in $(seq 2 $MDSCOUNT); do
18239                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18240                 $LFS setdirstripe -c $i $DIR/$tdir ||
18241                         error "split -c $i $tdir failed"
18242                 wait_update $HOSTNAME \
18243                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18244                         error "dir split not finished"
18245                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18246                         awk '/migrate/ {sum += $2} END { print sum }')
18247                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18248                 # delta is around total_files/stripe_count
18249                 [ $delta -lt $((200 /(i - 1))) ] ||
18250                         error "$delta files migrated"
18251         done
18252 }
18253 run_test 230o "dir split"
18254
18255 test_230p() {
18256         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18257         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18258                 skip "Need MDS version at least 2.13.52"
18259
18260         local mdts=$(comma_list $(mdts_nodes))
18261         local timeout=100
18262
18263         local restripe_status
18264         local delta
18265         local i
18266         local j
18267
18268         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18269
18270         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18271
18272         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18273                            mdt.*MDT0000.enable_dir_restripe)
18274         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18275         stack_trap "do_nodes $mdts $LCTL set_param \
18276                     mdt.*.enable_dir_restripe=$restripe_status"
18277
18278         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18279         createmany -m $DIR/$tdir/f 100 ||
18280                 error "create files under remote dir failed $i"
18281         createmany -d $DIR/$tdir/d 100 ||
18282                 error "create dirs under remote dir failed $i"
18283
18284         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18285                 local mdt_hash="crush"
18286
18287                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18288                 $LFS setdirstripe -c $i $DIR/$tdir ||
18289                         error "split -c $i $tdir failed"
18290                 [ $i -eq 1 ] && mdt_hash="none"
18291                 wait_update $HOSTNAME \
18292                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18293                         error "dir merge not finished"
18294                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18295                         awk '/migrate/ {sum += $2} END { print sum }')
18296                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18297                 # delta is around total_files/stripe_count
18298                 [ $delta -lt $((200 / i)) ] ||
18299                         error "$delta files migrated"
18300         done
18301 }
18302 run_test 230p "dir merge"
18303
18304 test_230q() {
18305         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18306         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18307                 skip "Need MDS version at least 2.13.52"
18308
18309         local mdts=$(comma_list $(mdts_nodes))
18310         local saved_threshold=$(do_facet mds1 \
18311                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18312         local saved_delta=$(do_facet mds1 \
18313                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18314         local threshold=100
18315         local delta=2
18316         local total=0
18317         local stripe_count=0
18318         local stripe_index
18319         local nr_files
18320
18321         stack_trap "do_nodes $mdts $LCTL set_param \
18322                     mdt.*.dir_split_count=$saved_threshold"
18323         stack_trap "do_nodes $mdts $LCTL set_param \
18324                     mdt.*.dir_split_delta=$saved_delta"
18325         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18326         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18327         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18328         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18329         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18330         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18331
18332         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18333         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18334
18335         while [ $stripe_count -lt $MDSCOUNT ]; do
18336                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18337                         error "create sub files failed"
18338                 stat $DIR/$tdir > /dev/null
18339                 total=$((total + threshold * 3 / 2))
18340                 stripe_count=$((stripe_count + delta))
18341                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18342
18343                 wait_update $HOSTNAME \
18344                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18345                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18346
18347                 wait_update $HOSTNAME \
18348                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18349                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18350
18351                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18352                            grep -w $stripe_index | wc -l)
18353                 echo "$nr_files files on MDT$stripe_index after split"
18354                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18355                         error "$nr_files files on MDT$stripe_index after split"
18356
18357                 nr_files=$(ls $DIR/$tdir | wc -w)
18358                 [ $nr_files -eq $total ] ||
18359                         error "total sub files $nr_files != $total"
18360         done
18361 }
18362 run_test 230q "dir auto split"
18363
18364 test_230r() {
18365         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18366         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18367         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18368                 skip "Need MDS version at least 2.13.54"
18369
18370         # maximum amount of local locks:
18371         # parent striped dir - 2 locks
18372         # new stripe in parent to migrate to - 1 lock
18373         # source and target - 2 locks
18374         # Total 5 locks for regular file
18375         mkdir -p $DIR/$tdir
18376         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18377         touch $DIR/$tdir/dir1/eee
18378
18379         # create 4 hardlink for 4 more locks
18380         # Total: 9 locks > RS_MAX_LOCKS (8)
18381         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18382         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18383         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18384         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18385         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18386         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18387         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18388         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18389
18390         cancel_lru_locks mdc
18391
18392         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18393                 error "migrate dir fails"
18394
18395         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18396 }
18397 run_test 230r "migrate with too many local locks"
18398
18399 test_231a()
18400 {
18401         # For simplicity this test assumes that max_pages_per_rpc
18402         # is the same across all OSCs
18403         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18404         local bulk_size=$((max_pages * PAGE_SIZE))
18405         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18406                                        head -n 1)
18407
18408         mkdir -p $DIR/$tdir
18409         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18410                 error "failed to set stripe with -S ${brw_size}M option"
18411
18412         # clear the OSC stats
18413         $LCTL set_param osc.*.stats=0 &>/dev/null
18414         stop_writeback
18415
18416         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18417         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18418                 oflag=direct &>/dev/null || error "dd failed"
18419
18420         sync; sleep 1; sync # just to be safe
18421         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18422         if [ x$nrpcs != "x1" ]; then
18423                 $LCTL get_param osc.*.stats
18424                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18425         fi
18426
18427         start_writeback
18428         # Drop the OSC cache, otherwise we will read from it
18429         cancel_lru_locks osc
18430
18431         # clear the OSC stats
18432         $LCTL set_param osc.*.stats=0 &>/dev/null
18433
18434         # Client reads $bulk_size.
18435         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18436                 iflag=direct &>/dev/null || error "dd failed"
18437
18438         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18439         if [ x$nrpcs != "x1" ]; then
18440                 $LCTL get_param osc.*.stats
18441                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18442         fi
18443 }
18444 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18445
18446 test_231b() {
18447         mkdir -p $DIR/$tdir
18448         local i
18449         for i in {0..1023}; do
18450                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18451                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18452                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18453         done
18454         sync
18455 }
18456 run_test 231b "must not assert on fully utilized OST request buffer"
18457
18458 test_232a() {
18459         mkdir -p $DIR/$tdir
18460         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18461
18462         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18463         do_facet ost1 $LCTL set_param fail_loc=0x31c
18464
18465         # ignore dd failure
18466         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18467
18468         do_facet ost1 $LCTL set_param fail_loc=0
18469         umount_client $MOUNT || error "umount failed"
18470         mount_client $MOUNT || error "mount failed"
18471         stop ost1 || error "cannot stop ost1"
18472         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18473 }
18474 run_test 232a "failed lock should not block umount"
18475
18476 test_232b() {
18477         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18478                 skip "Need MDS version at least 2.10.58"
18479
18480         mkdir -p $DIR/$tdir
18481         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18482         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18483         sync
18484         cancel_lru_locks osc
18485
18486         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18487         do_facet ost1 $LCTL set_param fail_loc=0x31c
18488
18489         # ignore failure
18490         $LFS data_version $DIR/$tdir/$tfile || true
18491
18492         do_facet ost1 $LCTL set_param fail_loc=0
18493         umount_client $MOUNT || error "umount failed"
18494         mount_client $MOUNT || error "mount failed"
18495         stop ost1 || error "cannot stop ost1"
18496         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18497 }
18498 run_test 232b "failed data version lock should not block umount"
18499
18500 test_233a() {
18501         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18502                 skip "Need MDS version at least 2.3.64"
18503         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18504
18505         local fid=$($LFS path2fid $MOUNT)
18506
18507         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18508                 error "cannot access $MOUNT using its FID '$fid'"
18509 }
18510 run_test 233a "checking that OBF of the FS root succeeds"
18511
18512 test_233b() {
18513         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18514                 skip "Need MDS version at least 2.5.90"
18515         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18516
18517         local fid=$($LFS path2fid $MOUNT/.lustre)
18518
18519         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18520                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18521
18522         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18523         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18524                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18525 }
18526 run_test 233b "checking that OBF of the FS .lustre succeeds"
18527
18528 test_234() {
18529         local p="$TMP/sanityN-$TESTNAME.parameters"
18530         save_lustre_params client "llite.*.xattr_cache" > $p
18531         lctl set_param llite.*.xattr_cache 1 ||
18532                 skip_env "xattr cache is not supported"
18533
18534         mkdir -p $DIR/$tdir || error "mkdir failed"
18535         touch $DIR/$tdir/$tfile || error "touch failed"
18536         # OBD_FAIL_LLITE_XATTR_ENOMEM
18537         $LCTL set_param fail_loc=0x1405
18538         getfattr -n user.attr $DIR/$tdir/$tfile &&
18539                 error "getfattr should have failed with ENOMEM"
18540         $LCTL set_param fail_loc=0x0
18541         rm -rf $DIR/$tdir
18542
18543         restore_lustre_params < $p
18544         rm -f $p
18545 }
18546 run_test 234 "xattr cache should not crash on ENOMEM"
18547
18548 test_235() {
18549         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18550                 skip "Need MDS version at least 2.4.52"
18551
18552         flock_deadlock $DIR/$tfile
18553         local RC=$?
18554         case $RC in
18555                 0)
18556                 ;;
18557                 124) error "process hangs on a deadlock"
18558                 ;;
18559                 *) error "error executing flock_deadlock $DIR/$tfile"
18560                 ;;
18561         esac
18562 }
18563 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18564
18565 #LU-2935
18566 test_236() {
18567         check_swap_layouts_support
18568
18569         local ref1=/etc/passwd
18570         local ref2=/etc/group
18571         local file1=$DIR/$tdir/f1
18572         local file2=$DIR/$tdir/f2
18573
18574         test_mkdir -c1 $DIR/$tdir
18575         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18576         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18577         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18578         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18579         local fd=$(free_fd)
18580         local cmd="exec $fd<>$file2"
18581         eval $cmd
18582         rm $file2
18583         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18584                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18585         cmd="exec $fd>&-"
18586         eval $cmd
18587         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18588
18589         #cleanup
18590         rm -rf $DIR/$tdir
18591 }
18592 run_test 236 "Layout swap on open unlinked file"
18593
18594 # LU-4659 linkea consistency
18595 test_238() {
18596         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18597                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18598                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18599                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18600
18601         touch $DIR/$tfile
18602         ln $DIR/$tfile $DIR/$tfile.lnk
18603         touch $DIR/$tfile.new
18604         mv $DIR/$tfile.new $DIR/$tfile
18605         local fid1=$($LFS path2fid $DIR/$tfile)
18606         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18607         local path1=$($LFS fid2path $FSNAME "$fid1")
18608         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18609         local path2=$($LFS fid2path $FSNAME "$fid2")
18610         [ $tfile.lnk == $path2 ] ||
18611                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18612         rm -f $DIR/$tfile*
18613 }
18614 run_test 238 "Verify linkea consistency"
18615
18616 test_239A() { # was test_239
18617         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18618                 skip "Need MDS version at least 2.5.60"
18619
18620         local list=$(comma_list $(mdts_nodes))
18621
18622         mkdir -p $DIR/$tdir
18623         createmany -o $DIR/$tdir/f- 5000
18624         unlinkmany $DIR/$tdir/f- 5000
18625         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18626                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18627         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18628                         osp.*MDT*.sync_in_flight" | calc_sum)
18629         [ "$changes" -eq 0 ] || error "$changes not synced"
18630 }
18631 run_test 239A "osp_sync test"
18632
18633 test_239a() { #LU-5297
18634         remote_mds_nodsh && skip "remote MDS with nodsh"
18635
18636         touch $DIR/$tfile
18637         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18638         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18639         chgrp $RUNAS_GID $DIR/$tfile
18640         wait_delete_completed
18641 }
18642 run_test 239a "process invalid osp sync record correctly"
18643
18644 test_239b() { #LU-5297
18645         remote_mds_nodsh && skip "remote MDS with nodsh"
18646
18647         touch $DIR/$tfile1
18648         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18649         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18650         chgrp $RUNAS_GID $DIR/$tfile1
18651         wait_delete_completed
18652         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18653         touch $DIR/$tfile2
18654         chgrp $RUNAS_GID $DIR/$tfile2
18655         wait_delete_completed
18656 }
18657 run_test 239b "process osp sync record with ENOMEM error correctly"
18658
18659 test_240() {
18660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18661         remote_mds_nodsh && skip "remote MDS with nodsh"
18662
18663         mkdir -p $DIR/$tdir
18664
18665         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18666                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18667         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18668                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18669
18670         umount_client $MOUNT || error "umount failed"
18671         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18672         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18673         mount_client $MOUNT || error "failed to mount client"
18674
18675         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18676         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18677 }
18678 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18679
18680 test_241_bio() {
18681         local count=$1
18682         local bsize=$2
18683
18684         for LOOP in $(seq $count); do
18685                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18686                 cancel_lru_locks $OSC || true
18687         done
18688 }
18689
18690 test_241_dio() {
18691         local count=$1
18692         local bsize=$2
18693
18694         for LOOP in $(seq $1); do
18695                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18696                         2>/dev/null
18697         done
18698 }
18699
18700 test_241a() { # was test_241
18701         local bsize=$PAGE_SIZE
18702
18703         (( bsize < 40960 )) && bsize=40960
18704         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18705         ls -la $DIR/$tfile
18706         cancel_lru_locks $OSC
18707         test_241_bio 1000 $bsize &
18708         PID=$!
18709         test_241_dio 1000 $bsize
18710         wait $PID
18711 }
18712 run_test 241a "bio vs dio"
18713
18714 test_241b() {
18715         local bsize=$PAGE_SIZE
18716
18717         (( bsize < 40960 )) && bsize=40960
18718         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18719         ls -la $DIR/$tfile
18720         test_241_dio 1000 $bsize &
18721         PID=$!
18722         test_241_dio 1000 $bsize
18723         wait $PID
18724 }
18725 run_test 241b "dio vs dio"
18726
18727 test_242() {
18728         remote_mds_nodsh && skip "remote MDS with nodsh"
18729
18730         mkdir -p $DIR/$tdir
18731         touch $DIR/$tdir/$tfile
18732
18733         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18734         do_facet mds1 lctl set_param fail_loc=0x105
18735         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18736
18737         do_facet mds1 lctl set_param fail_loc=0
18738         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18739 }
18740 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18741
18742 test_243()
18743 {
18744         test_mkdir $DIR/$tdir
18745         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18746 }
18747 run_test 243 "various group lock tests"
18748
18749 test_244a()
18750 {
18751         test_mkdir $DIR/$tdir
18752         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18753         sendfile_grouplock $DIR/$tdir/$tfile || \
18754                 error "sendfile+grouplock failed"
18755         rm -rf $DIR/$tdir
18756 }
18757 run_test 244a "sendfile with group lock tests"
18758
18759 test_244b()
18760 {
18761         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18762
18763         local threads=50
18764         local size=$((1024*1024))
18765
18766         test_mkdir $DIR/$tdir
18767         for i in $(seq 1 $threads); do
18768                 local file=$DIR/$tdir/file_$((i / 10))
18769                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18770                 local pids[$i]=$!
18771         done
18772         for i in $(seq 1 $threads); do
18773                 wait ${pids[$i]}
18774         done
18775 }
18776 run_test 244b "multi-threaded write with group lock"
18777
18778 test_245() {
18779         local flagname="multi_mod_rpcs"
18780         local connect_data_name="max_mod_rpcs"
18781         local out
18782
18783         # check if multiple modify RPCs flag is set
18784         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18785                 grep "connect_flags:")
18786         echo "$out"
18787
18788         echo "$out" | grep -qw $flagname
18789         if [ $? -ne 0 ]; then
18790                 echo "connect flag $flagname is not set"
18791                 return
18792         fi
18793
18794         # check if multiple modify RPCs data is set
18795         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18796         echo "$out"
18797
18798         echo "$out" | grep -qw $connect_data_name ||
18799                 error "import should have connect data $connect_data_name"
18800 }
18801 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18802
18803 cleanup_247() {
18804         local submount=$1
18805
18806         trap 0
18807         umount_client $submount
18808         rmdir $submount
18809 }
18810
18811 test_247a() {
18812         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18813                 grep -q subtree ||
18814                 skip_env "Fileset feature is not supported"
18815
18816         local submount=${MOUNT}_$tdir
18817
18818         mkdir $MOUNT/$tdir
18819         mkdir -p $submount || error "mkdir $submount failed"
18820         FILESET="$FILESET/$tdir" mount_client $submount ||
18821                 error "mount $submount failed"
18822         trap "cleanup_247 $submount" EXIT
18823         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18824         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18825                 error "read $MOUNT/$tdir/$tfile failed"
18826         cleanup_247 $submount
18827 }
18828 run_test 247a "mount subdir as fileset"
18829
18830 test_247b() {
18831         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18832                 skip_env "Fileset feature is not supported"
18833
18834         local submount=${MOUNT}_$tdir
18835
18836         rm -rf $MOUNT/$tdir
18837         mkdir -p $submount || error "mkdir $submount failed"
18838         SKIP_FILESET=1
18839         FILESET="$FILESET/$tdir" mount_client $submount &&
18840                 error "mount $submount should fail"
18841         rmdir $submount
18842 }
18843 run_test 247b "mount subdir that dose not exist"
18844
18845 test_247c() {
18846         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18847                 skip_env "Fileset feature is not supported"
18848
18849         local submount=${MOUNT}_$tdir
18850
18851         mkdir -p $MOUNT/$tdir/dir1
18852         mkdir -p $submount || error "mkdir $submount failed"
18853         trap "cleanup_247 $submount" EXIT
18854         FILESET="$FILESET/$tdir" mount_client $submount ||
18855                 error "mount $submount failed"
18856         local fid=$($LFS path2fid $MOUNT/)
18857         $LFS fid2path $submount $fid && error "fid2path should fail"
18858         cleanup_247 $submount
18859 }
18860 run_test 247c "running fid2path outside subdirectory root"
18861
18862 test_247d() {
18863         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18864                 skip "Fileset feature is not supported"
18865
18866         local submount=${MOUNT}_$tdir
18867
18868         mkdir -p $MOUNT/$tdir/dir1
18869         mkdir -p $submount || error "mkdir $submount failed"
18870         FILESET="$FILESET/$tdir" mount_client $submount ||
18871                 error "mount $submount failed"
18872         trap "cleanup_247 $submount" EXIT
18873
18874         local td=$submount/dir1
18875         local fid=$($LFS path2fid $td)
18876         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18877
18878         # check that we get the same pathname back
18879         local rootpath
18880         local found
18881         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18882                 echo "$rootpath $fid"
18883                 found=$($LFS fid2path $rootpath "$fid")
18884                 [ -n "found" ] || error "fid2path should succeed"
18885                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18886         done
18887         # check wrong root path format
18888         rootpath=$submount"_wrong"
18889         found=$($LFS fid2path $rootpath "$fid")
18890         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18891
18892         cleanup_247 $submount
18893 }
18894 run_test 247d "running fid2path inside subdirectory root"
18895
18896 # LU-8037
18897 test_247e() {
18898         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18899                 grep -q subtree ||
18900                 skip "Fileset feature is not supported"
18901
18902         local submount=${MOUNT}_$tdir
18903
18904         mkdir $MOUNT/$tdir
18905         mkdir -p $submount || error "mkdir $submount failed"
18906         FILESET="$FILESET/.." mount_client $submount &&
18907                 error "mount $submount should fail"
18908         rmdir $submount
18909 }
18910 run_test 247e "mount .. as fileset"
18911
18912 test_247f() {
18913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18914         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18915                 skip "Need at least version 2.13.52"
18916         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18917                 grep -q subtree ||
18918                 skip "Fileset feature is not supported"
18919
18920         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18921         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18922                 error "mkdir remote failed"
18923         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18924         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18925                 error "mkdir striped failed"
18926         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18927
18928         local submount=${MOUNT}_$tdir
18929
18930         mkdir -p $submount || error "mkdir $submount failed"
18931
18932         local dir
18933         local fileset=$FILESET
18934
18935         for dir in $tdir/remote $tdir/remote/subdir \
18936                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18937                 FILESET="$fileset/$dir" mount_client $submount ||
18938                         error "mount $dir failed"
18939                 umount_client $submount
18940         done
18941 }
18942 run_test 247f "mount striped or remote directory as fileset"
18943
18944 test_248a() {
18945         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18946         [ -z "$fast_read_sav" ] && skip "no fast read support"
18947
18948         # create a large file for fast read verification
18949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18950
18951         # make sure the file is created correctly
18952         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18953                 { rm -f $DIR/$tfile; skip "file creation error"; }
18954
18955         echo "Test 1: verify that fast read is 4 times faster on cache read"
18956
18957         # small read with fast read enabled
18958         $LCTL set_param -n llite.*.fast_read=1
18959         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18960                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18961                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18962         # small read with fast read disabled
18963         $LCTL set_param -n llite.*.fast_read=0
18964         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18965                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18966                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18967
18968         # verify that fast read is 4 times faster for cache read
18969         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18970                 error_not_in_vm "fast read was not 4 times faster: " \
18971                            "$t_fast vs $t_slow"
18972
18973         echo "Test 2: verify the performance between big and small read"
18974         $LCTL set_param -n llite.*.fast_read=1
18975
18976         # 1k non-cache read
18977         cancel_lru_locks osc
18978         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18979                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18980                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18981
18982         # 1M non-cache read
18983         cancel_lru_locks osc
18984         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18985                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18986                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18987
18988         # verify that big IO is not 4 times faster than small IO
18989         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18990                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18991
18992         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18993         rm -f $DIR/$tfile
18994 }
18995 run_test 248a "fast read verification"
18996
18997 test_248b() {
18998         # Default short_io_bytes=16384, try both smaller and larger sizes.
18999         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19000         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19001         echo "bs=53248 count=113 normal buffered write"
19002         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19003                 error "dd of initial data file failed"
19004         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19005
19006         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19007         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19008                 error "dd with sync normal writes failed"
19009         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19010
19011         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19012         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19013                 error "dd with sync small writes failed"
19014         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19015
19016         cancel_lru_locks osc
19017
19018         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19019         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19020         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19021         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19022                 iflag=direct || error "dd with O_DIRECT small read failed"
19023         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19024         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19025                 error "compare $TMP/$tfile.1 failed"
19026
19027         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19028         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19029
19030         # just to see what the maximum tunable value is, and test parsing
19031         echo "test invalid parameter 2MB"
19032         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19033                 error "too-large short_io_bytes allowed"
19034         echo "test maximum parameter 512KB"
19035         # if we can set a larger short_io_bytes, run test regardless of version
19036         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19037                 # older clients may not allow setting it this large, that's OK
19038                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19039                         skip "Need at least client version 2.13.50"
19040                 error "medium short_io_bytes failed"
19041         fi
19042         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19043         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19044
19045         echo "test large parameter 64KB"
19046         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19047         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19048
19049         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19050         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19051                 error "dd with sync large writes failed"
19052         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19053
19054         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19055         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19056         num=$((113 * 4096 / PAGE_SIZE))
19057         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19058         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19059                 error "dd with O_DIRECT large writes failed"
19060         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19061                 error "compare $DIR/$tfile.3 failed"
19062
19063         cancel_lru_locks osc
19064
19065         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19066         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19067                 error "dd with O_DIRECT large read failed"
19068         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19069                 error "compare $TMP/$tfile.2 failed"
19070
19071         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19072         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19073                 error "dd with O_DIRECT large read failed"
19074         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19075                 error "compare $TMP/$tfile.3 failed"
19076 }
19077 run_test 248b "test short_io read and write for both small and large sizes"
19078
19079 test_249() { # LU-7890
19080         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19081                 skip "Need at least version 2.8.54"
19082
19083         rm -f $DIR/$tfile
19084         $LFS setstripe -c 1 $DIR/$tfile
19085         # Offset 2T == 4k * 512M
19086         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19087                 error "dd to 2T offset failed"
19088 }
19089 run_test 249 "Write above 2T file size"
19090
19091 test_250() {
19092         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19093          && skip "no 16TB file size limit on ZFS"
19094
19095         $LFS setstripe -c 1 $DIR/$tfile
19096         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19097         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19098         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19099         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19100                 conv=notrunc,fsync && error "append succeeded"
19101         return 0
19102 }
19103 run_test 250 "Write above 16T limit"
19104
19105 test_251() {
19106         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19107
19108         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19109         #Skip once - writing the first stripe will succeed
19110         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19111         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19112                 error "short write happened"
19113
19114         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19115         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19116                 error "short read happened"
19117
19118         rm -f $DIR/$tfile
19119 }
19120 run_test 251 "Handling short read and write correctly"
19121
19122 test_252() {
19123         remote_mds_nodsh && skip "remote MDS with nodsh"
19124         remote_ost_nodsh && skip "remote OST with nodsh"
19125         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19126                 skip_env "ldiskfs only test"
19127         fi
19128
19129         local tgt
19130         local dev
19131         local out
19132         local uuid
19133         local num
19134         local gen
19135
19136         # check lr_reader on OST0000
19137         tgt=ost1
19138         dev=$(facet_device $tgt)
19139         out=$(do_facet $tgt $LR_READER $dev)
19140         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19141         echo "$out"
19142         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19143         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19144                 error "Invalid uuid returned by $LR_READER on target $tgt"
19145         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19146
19147         # check lr_reader -c on MDT0000
19148         tgt=mds1
19149         dev=$(facet_device $tgt)
19150         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19151                 skip "$LR_READER does not support additional options"
19152         fi
19153         out=$(do_facet $tgt $LR_READER -c $dev)
19154         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19155         echo "$out"
19156         num=$(echo "$out" | grep -c "mdtlov")
19157         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19158                 error "Invalid number of mdtlov clients returned by $LR_READER"
19159         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19160
19161         # check lr_reader -cr on MDT0000
19162         out=$(do_facet $tgt $LR_READER -cr $dev)
19163         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19164         echo "$out"
19165         echo "$out" | grep -q "^reply_data:$" ||
19166                 error "$LR_READER should have returned 'reply_data' section"
19167         num=$(echo "$out" | grep -c "client_generation")
19168         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19169 }
19170 run_test 252 "check lr_reader tool"
19171
19172 test_253() {
19173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19174         remote_mds_nodsh && skip "remote MDS with nodsh"
19175         remote_mgs_nodsh && skip "remote MGS with nodsh"
19176
19177         local ostidx=0
19178         local rc=0
19179         local ost_name=$(ostname_from_index $ostidx)
19180
19181         # on the mdt's osc
19182         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19183         do_facet $SINGLEMDS $LCTL get_param -n \
19184                 osp.$mdtosc_proc1.reserved_mb_high ||
19185                 skip  "remote MDS does not support reserved_mb_high"
19186
19187         rm -rf $DIR/$tdir
19188         wait_mds_ost_sync
19189         wait_delete_completed
19190         mkdir $DIR/$tdir
19191
19192         pool_add $TESTNAME || error "Pool creation failed"
19193         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19194
19195         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19196                 error "Setstripe failed"
19197
19198         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19199
19200         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19201                     grep "watermarks")
19202         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19203
19204         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19205                         osp.$mdtosc_proc1.prealloc_status)
19206         echo "prealloc_status $oa_status"
19207
19208         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19209                 error "File creation should fail"
19210
19211         #object allocation was stopped, but we still able to append files
19212         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19213                 oflag=append || error "Append failed"
19214
19215         rm -f $DIR/$tdir/$tfile.0
19216
19217         # For this test, we want to delete the files we created to go out of
19218         # space but leave the watermark, so we remain nearly out of space
19219         ost_watermarks_enospc_delete_files $tfile $ostidx
19220
19221         wait_delete_completed
19222
19223         sleep_maxage
19224
19225         for i in $(seq 10 12); do
19226                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19227                         2>/dev/null || error "File creation failed after rm"
19228         done
19229
19230         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19231                         osp.$mdtosc_proc1.prealloc_status)
19232         echo "prealloc_status $oa_status"
19233
19234         if (( oa_status != 0 )); then
19235                 error "Object allocation still disable after rm"
19236         fi
19237 }
19238 run_test 253 "Check object allocation limit"
19239
19240 test_254() {
19241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19242         remote_mds_nodsh && skip "remote MDS with nodsh"
19243         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19244                 skip "MDS does not support changelog_size"
19245
19246         local cl_user
19247         local MDT0=$(facet_svc $SINGLEMDS)
19248
19249         changelog_register || error "changelog_register failed"
19250
19251         changelog_clear 0 || error "changelog_clear failed"
19252
19253         local size1=$(do_facet $SINGLEMDS \
19254                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19255         echo "Changelog size $size1"
19256
19257         rm -rf $DIR/$tdir
19258         $LFS mkdir -i 0 $DIR/$tdir
19259         # change something
19260         mkdir -p $DIR/$tdir/pics/2008/zachy
19261         touch $DIR/$tdir/pics/2008/zachy/timestamp
19262         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19263         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19264         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19265         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19266         rm $DIR/$tdir/pics/desktop.jpg
19267
19268         local size2=$(do_facet $SINGLEMDS \
19269                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19270         echo "Changelog size after work $size2"
19271
19272         (( $size2 > $size1 )) ||
19273                 error "new Changelog size=$size2 less than old size=$size1"
19274 }
19275 run_test 254 "Check changelog size"
19276
19277 ladvise_no_type()
19278 {
19279         local type=$1
19280         local file=$2
19281
19282         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19283                 awk -F: '{print $2}' | grep $type > /dev/null
19284         if [ $? -ne 0 ]; then
19285                 return 0
19286         fi
19287         return 1
19288 }
19289
19290 ladvise_no_ioctl()
19291 {
19292         local file=$1
19293
19294         lfs ladvise -a willread $file > /dev/null 2>&1
19295         if [ $? -eq 0 ]; then
19296                 return 1
19297         fi
19298
19299         lfs ladvise -a willread $file 2>&1 |
19300                 grep "Inappropriate ioctl for device" > /dev/null
19301         if [ $? -eq 0 ]; then
19302                 return 0
19303         fi
19304         return 1
19305 }
19306
19307 percent() {
19308         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19309 }
19310
19311 # run a random read IO workload
19312 # usage: random_read_iops <filename> <filesize> <iosize>
19313 random_read_iops() {
19314         local file=$1
19315         local fsize=$2
19316         local iosize=${3:-4096}
19317
19318         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19319                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19320 }
19321
19322 drop_file_oss_cache() {
19323         local file="$1"
19324         local nodes="$2"
19325
19326         $LFS ladvise -a dontneed $file 2>/dev/null ||
19327                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19328 }
19329
19330 ladvise_willread_performance()
19331 {
19332         local repeat=10
19333         local average_origin=0
19334         local average_cache=0
19335         local average_ladvise=0
19336
19337         for ((i = 1; i <= $repeat; i++)); do
19338                 echo "Iter $i/$repeat: reading without willread hint"
19339                 cancel_lru_locks osc
19340                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19341                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19342                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19343                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19344
19345                 cancel_lru_locks osc
19346                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19347                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19348                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19349
19350                 cancel_lru_locks osc
19351                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19352                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19353                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19354                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19355                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19356         done
19357         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19358         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19359         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19360
19361         speedup_cache=$(percent $average_cache $average_origin)
19362         speedup_ladvise=$(percent $average_ladvise $average_origin)
19363
19364         echo "Average uncached read: $average_origin"
19365         echo "Average speedup with OSS cached read: " \
19366                 "$average_cache = +$speedup_cache%"
19367         echo "Average speedup with ladvise willread: " \
19368                 "$average_ladvise = +$speedup_ladvise%"
19369
19370         local lowest_speedup=20
19371         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19372                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19373                         "got $average_cache%. Skipping ladvise willread check."
19374                 return 0
19375         fi
19376
19377         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19378         # it is still good to run until then to exercise 'ladvise willread'
19379         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19380                 [ "$ost1_FSTYPE" = "zfs" ] &&
19381                 echo "osd-zfs does not support dontneed or drop_caches" &&
19382                 return 0
19383
19384         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19385         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19386                 error_not_in_vm "Speedup with willread is less than " \
19387                         "$lowest_speedup%, got $average_ladvise%"
19388 }
19389
19390 test_255a() {
19391         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19392                 skip "lustre < 2.8.54 does not support ladvise "
19393         remote_ost_nodsh && skip "remote OST with nodsh"
19394
19395         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19396
19397         ladvise_no_type willread $DIR/$tfile &&
19398                 skip "willread ladvise is not supported"
19399
19400         ladvise_no_ioctl $DIR/$tfile &&
19401                 skip "ladvise ioctl is not supported"
19402
19403         local size_mb=100
19404         local size=$((size_mb * 1048576))
19405         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19406                 error "dd to $DIR/$tfile failed"
19407
19408         lfs ladvise -a willread $DIR/$tfile ||
19409                 error "Ladvise failed with no range argument"
19410
19411         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19412                 error "Ladvise failed with no -l or -e argument"
19413
19414         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19415                 error "Ladvise failed with only -e argument"
19416
19417         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19418                 error "Ladvise failed with only -l argument"
19419
19420         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19421                 error "End offset should not be smaller than start offset"
19422
19423         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19424                 error "End offset should not be equal to start offset"
19425
19426         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19427                 error "Ladvise failed with overflowing -s argument"
19428
19429         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19430                 error "Ladvise failed with overflowing -e argument"
19431
19432         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19433                 error "Ladvise failed with overflowing -l argument"
19434
19435         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19436                 error "Ladvise succeeded with conflicting -l and -e arguments"
19437
19438         echo "Synchronous ladvise should wait"
19439         local delay=4
19440 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19441         do_nodes $(comma_list $(osts_nodes)) \
19442                 $LCTL set_param fail_val=$delay fail_loc=0x237
19443
19444         local start_ts=$SECONDS
19445         lfs ladvise -a willread $DIR/$tfile ||
19446                 error "Ladvise failed with no range argument"
19447         local end_ts=$SECONDS
19448         local inteval_ts=$((end_ts - start_ts))
19449
19450         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19451                 error "Synchronous advice didn't wait reply"
19452         fi
19453
19454         echo "Asynchronous ladvise shouldn't wait"
19455         local start_ts=$SECONDS
19456         lfs ladvise -a willread -b $DIR/$tfile ||
19457                 error "Ladvise failed with no range argument"
19458         local end_ts=$SECONDS
19459         local inteval_ts=$((end_ts - start_ts))
19460
19461         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19462                 error "Asynchronous advice blocked"
19463         fi
19464
19465         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19466         ladvise_willread_performance
19467 }
19468 run_test 255a "check 'lfs ladvise -a willread'"
19469
19470 facet_meminfo() {
19471         local facet=$1
19472         local info=$2
19473
19474         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19475 }
19476
19477 test_255b() {
19478         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19479                 skip "lustre < 2.8.54 does not support ladvise "
19480         remote_ost_nodsh && skip "remote OST with nodsh"
19481
19482         lfs setstripe -c 1 -i 0 $DIR/$tfile
19483
19484         ladvise_no_type dontneed $DIR/$tfile &&
19485                 skip "dontneed ladvise is not supported"
19486
19487         ladvise_no_ioctl $DIR/$tfile &&
19488                 skip "ladvise ioctl is not supported"
19489
19490         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19491                 [ "$ost1_FSTYPE" = "zfs" ] &&
19492                 skip "zfs-osd does not support 'ladvise dontneed'"
19493
19494         local size_mb=100
19495         local size=$((size_mb * 1048576))
19496         # In order to prevent disturbance of other processes, only check 3/4
19497         # of the memory usage
19498         local kibibytes=$((size_mb * 1024 * 3 / 4))
19499
19500         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19501                 error "dd to $DIR/$tfile failed"
19502
19503         #force write to complete before dropping OST cache & checking memory
19504         sync
19505
19506         local total=$(facet_meminfo ost1 MemTotal)
19507         echo "Total memory: $total KiB"
19508
19509         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19510         local before_read=$(facet_meminfo ost1 Cached)
19511         echo "Cache used before read: $before_read KiB"
19512
19513         lfs ladvise -a willread $DIR/$tfile ||
19514                 error "Ladvise willread failed"
19515         local after_read=$(facet_meminfo ost1 Cached)
19516         echo "Cache used after read: $after_read KiB"
19517
19518         lfs ladvise -a dontneed $DIR/$tfile ||
19519                 error "Ladvise dontneed again failed"
19520         local no_read=$(facet_meminfo ost1 Cached)
19521         echo "Cache used after dontneed ladvise: $no_read KiB"
19522
19523         if [ $total -lt $((before_read + kibibytes)) ]; then
19524                 echo "Memory is too small, abort checking"
19525                 return 0
19526         fi
19527
19528         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19529                 error "Ladvise willread should use more memory" \
19530                         "than $kibibytes KiB"
19531         fi
19532
19533         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19534                 error "Ladvise dontneed should release more memory" \
19535                         "than $kibibytes KiB"
19536         fi
19537 }
19538 run_test 255b "check 'lfs ladvise -a dontneed'"
19539
19540 test_255c() {
19541         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19542                 skip "lustre < 2.10.50 does not support lockahead"
19543
19544         local count
19545         local new_count
19546         local difference
19547         local i
19548         local rc
19549
19550         test_mkdir -p $DIR/$tdir
19551         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19552
19553         #test 10 returns only success/failure
19554         i=10
19555         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19556         rc=$?
19557         if [ $rc -eq 255 ]; then
19558                 error "Ladvise test${i} failed, ${rc}"
19559         fi
19560
19561         #test 11 counts lock enqueue requests, all others count new locks
19562         i=11
19563         count=$(do_facet ost1 \
19564                 $LCTL get_param -n ost.OSS.ost.stats)
19565         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19566
19567         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19568         rc=$?
19569         if [ $rc -eq 255 ]; then
19570                 error "Ladvise test${i} failed, ${rc}"
19571         fi
19572
19573         new_count=$(do_facet ost1 \
19574                 $LCTL get_param -n ost.OSS.ost.stats)
19575         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19576                    awk '{ print $2 }')
19577
19578         difference="$((new_count - count))"
19579         if [ $difference -ne $rc ]; then
19580                 error "Ladvise test${i}, bad enqueue count, returned " \
19581                       "${rc}, actual ${difference}"
19582         fi
19583
19584         for i in $(seq 12 21); do
19585                 # If we do not do this, we run the risk of having too many
19586                 # locks and starting lock cancellation while we are checking
19587                 # lock counts.
19588                 cancel_lru_locks osc
19589
19590                 count=$($LCTL get_param -n \
19591                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19592
19593                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19594                 rc=$?
19595                 if [ $rc -eq 255 ]; then
19596                         error "Ladvise test ${i} failed, ${rc}"
19597                 fi
19598
19599                 new_count=$($LCTL get_param -n \
19600                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19601                 difference="$((new_count - count))"
19602
19603                 # Test 15 output is divided by 100 to map down to valid return
19604                 if [ $i -eq 15 ]; then
19605                         rc="$((rc * 100))"
19606                 fi
19607
19608                 if [ $difference -ne $rc ]; then
19609                         error "Ladvise test ${i}, bad lock count, returned " \
19610                               "${rc}, actual ${difference}"
19611                 fi
19612         done
19613
19614         #test 22 returns only success/failure
19615         i=22
19616         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19617         rc=$?
19618         if [ $rc -eq 255 ]; then
19619                 error "Ladvise test${i} failed, ${rc}"
19620         fi
19621 }
19622 run_test 255c "suite of ladvise lockahead tests"
19623
19624 test_256() {
19625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19626         remote_mds_nodsh && skip "remote MDS with nodsh"
19627         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19628         changelog_users $SINGLEMDS | grep "^cl" &&
19629                 skip "active changelog user"
19630
19631         local cl_user
19632         local cat_sl
19633         local mdt_dev
19634
19635         mdt_dev=$(mdsdevname 1)
19636         echo $mdt_dev
19637
19638         changelog_register || error "changelog_register failed"
19639
19640         rm -rf $DIR/$tdir
19641         mkdir -p $DIR/$tdir
19642
19643         changelog_clear 0 || error "changelog_clear failed"
19644
19645         # change something
19646         touch $DIR/$tdir/{1..10}
19647
19648         # stop the MDT
19649         stop $SINGLEMDS || error "Fail to stop MDT"
19650
19651         # remount the MDT
19652
19653         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19654
19655         #after mount new plainllog is used
19656         touch $DIR/$tdir/{11..19}
19657         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19658         stack_trap "rm -f $tmpfile"
19659         cat_sl=$(do_facet $SINGLEMDS "sync; \
19660                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19661                  llog_reader $tmpfile | grep -c type=1064553b")
19662         do_facet $SINGLEMDS llog_reader $tmpfile
19663
19664         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19665
19666         changelog_clear 0 || error "changelog_clear failed"
19667
19668         cat_sl=$(do_facet $SINGLEMDS "sync; \
19669                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19670                  llog_reader $tmpfile | grep -c type=1064553b")
19671
19672         if (( cat_sl == 2 )); then
19673                 error "Empty plain llog was not deleted from changelog catalog"
19674         elif (( cat_sl != 1 )); then
19675                 error "Active plain llog shouldn't be deleted from catalog"
19676         fi
19677 }
19678 run_test 256 "Check llog delete for empty and not full state"
19679
19680 test_257() {
19681         remote_mds_nodsh && skip "remote MDS with nodsh"
19682         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19683                 skip "Need MDS version at least 2.8.55"
19684
19685         test_mkdir $DIR/$tdir
19686
19687         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19688                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19689         stat $DIR/$tdir
19690
19691 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19692         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19693         local facet=mds$((mdtidx + 1))
19694         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19695         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19696
19697         stop $facet || error "stop MDS failed"
19698         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19699                 error "start MDS fail"
19700         wait_recovery_complete $facet
19701 }
19702 run_test 257 "xattr locks are not lost"
19703
19704 # Verify we take the i_mutex when security requires it
19705 test_258a() {
19706 #define OBD_FAIL_IMUTEX_SEC 0x141c
19707         $LCTL set_param fail_loc=0x141c
19708         touch $DIR/$tfile
19709         chmod u+s $DIR/$tfile
19710         chmod a+rwx $DIR/$tfile
19711         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19712         RC=$?
19713         if [ $RC -ne 0 ]; then
19714                 error "error, failed to take i_mutex, rc=$?"
19715         fi
19716         rm -f $DIR/$tfile
19717 }
19718 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19719
19720 # Verify we do NOT take the i_mutex in the normal case
19721 test_258b() {
19722 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19723         $LCTL set_param fail_loc=0x141d
19724         touch $DIR/$tfile
19725         chmod a+rwx $DIR
19726         chmod a+rw $DIR/$tfile
19727         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19728         RC=$?
19729         if [ $RC -ne 0 ]; then
19730                 error "error, took i_mutex unnecessarily, rc=$?"
19731         fi
19732         rm -f $DIR/$tfile
19733
19734 }
19735 run_test 258b "verify i_mutex security behavior"
19736
19737 test_259() {
19738         local file=$DIR/$tfile
19739         local before
19740         local after
19741
19742         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19743
19744         stack_trap "rm -f $file" EXIT
19745
19746         wait_delete_completed
19747         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19748         echo "before: $before"
19749
19750         $LFS setstripe -i 0 -c 1 $file
19751         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19752         sync_all_data
19753         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19754         echo "after write: $after"
19755
19756 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19757         do_facet ost1 $LCTL set_param fail_loc=0x2301
19758         $TRUNCATE $file 0
19759         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19760         echo "after truncate: $after"
19761
19762         stop ost1
19763         do_facet ost1 $LCTL set_param fail_loc=0
19764         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19765         sleep 2
19766         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19767         echo "after restart: $after"
19768         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19769                 error "missing truncate?"
19770
19771         return 0
19772 }
19773 run_test 259 "crash at delayed truncate"
19774
19775 test_260() {
19776 #define OBD_FAIL_MDC_CLOSE               0x806
19777         $LCTL set_param fail_loc=0x80000806
19778         touch $DIR/$tfile
19779
19780 }
19781 run_test 260 "Check mdc_close fail"
19782
19783 ### Data-on-MDT sanity tests ###
19784 test_270a() {
19785         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19786                 skip "Need MDS version at least 2.10.55 for DoM"
19787
19788         # create DoM file
19789         local dom=$DIR/$tdir/dom_file
19790         local tmp=$DIR/$tdir/tmp_file
19791
19792         mkdir -p $DIR/$tdir
19793
19794         # basic checks for DoM component creation
19795         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19796                 error "Can set MDT layout to non-first entry"
19797
19798         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19799                 error "Can define multiple entries as MDT layout"
19800
19801         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19802
19803         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19804         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19805         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19806
19807         local mdtidx=$($LFS getstripe -m $dom)
19808         local mdtname=MDT$(printf %04x $mdtidx)
19809         local facet=mds$((mdtidx + 1))
19810         local space_check=1
19811
19812         # Skip free space checks with ZFS
19813         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19814
19815         # write
19816         sync
19817         local size_tmp=$((65536 * 3))
19818         local mdtfree1=$(do_facet $facet \
19819                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19820
19821         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19822         # check also direct IO along write
19823         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19824         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19825         sync
19826         cmp $tmp $dom || error "file data is different"
19827         [ $(stat -c%s $dom) == $size_tmp ] ||
19828                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19829         if [ $space_check == 1 ]; then
19830                 local mdtfree2=$(do_facet $facet \
19831                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19832
19833                 # increase in usage from by $size_tmp
19834                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19835                         error "MDT free space wrong after write: " \
19836                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19837         fi
19838
19839         # truncate
19840         local size_dom=10000
19841
19842         $TRUNCATE $dom $size_dom
19843         [ $(stat -c%s $dom) == $size_dom ] ||
19844                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19845         if [ $space_check == 1 ]; then
19846                 mdtfree1=$(do_facet $facet \
19847                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19848                 # decrease in usage from $size_tmp to new $size_dom
19849                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19850                   $(((size_tmp - size_dom) / 1024)) ] ||
19851                         error "MDT free space is wrong after truncate: " \
19852                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19853         fi
19854
19855         # append
19856         cat $tmp >> $dom
19857         sync
19858         size_dom=$((size_dom + size_tmp))
19859         [ $(stat -c%s $dom) == $size_dom ] ||
19860                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19861         if [ $space_check == 1 ]; then
19862                 mdtfree2=$(do_facet $facet \
19863                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19864                 # increase in usage by $size_tmp from previous
19865                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19866                         error "MDT free space is wrong after append: " \
19867                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19868         fi
19869
19870         # delete
19871         rm $dom
19872         if [ $space_check == 1 ]; then
19873                 mdtfree1=$(do_facet $facet \
19874                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19875                 # decrease in usage by $size_dom from previous
19876                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19877                         error "MDT free space is wrong after removal: " \
19878                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19879         fi
19880
19881         # combined striping
19882         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19883                 error "Can't create DoM + OST striping"
19884
19885         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19886         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19887         # check also direct IO along write
19888         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19889         sync
19890         cmp $tmp $dom || error "file data is different"
19891         [ $(stat -c%s $dom) == $size_tmp ] ||
19892                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19893         rm $dom $tmp
19894
19895         return 0
19896 }
19897 run_test 270a "DoM: basic functionality tests"
19898
19899 test_270b() {
19900         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19901                 skip "Need MDS version at least 2.10.55"
19902
19903         local dom=$DIR/$tdir/dom_file
19904         local max_size=1048576
19905
19906         mkdir -p $DIR/$tdir
19907         $LFS setstripe -E $max_size -L mdt $dom
19908
19909         # truncate over the limit
19910         $TRUNCATE $dom $(($max_size + 1)) &&
19911                 error "successful truncate over the maximum size"
19912         # write over the limit
19913         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19914                 error "successful write over the maximum size"
19915         # append over the limit
19916         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19917         echo "12345" >> $dom && error "successful append over the maximum size"
19918         rm $dom
19919
19920         return 0
19921 }
19922 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19923
19924 test_270c() {
19925         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19926                 skip "Need MDS version at least 2.10.55"
19927
19928         mkdir -p $DIR/$tdir
19929         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19930
19931         # check files inherit DoM EA
19932         touch $DIR/$tdir/first
19933         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19934                 error "bad pattern"
19935         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19936                 error "bad stripe count"
19937         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19938                 error "bad stripe size"
19939
19940         # check directory inherits DoM EA and uses it as default
19941         mkdir $DIR/$tdir/subdir
19942         touch $DIR/$tdir/subdir/second
19943         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19944                 error "bad pattern in sub-directory"
19945         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19946                 error "bad stripe count in sub-directory"
19947         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19948                 error "bad stripe size in sub-directory"
19949         return 0
19950 }
19951 run_test 270c "DoM: DoM EA inheritance tests"
19952
19953 test_270d() {
19954         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19955                 skip "Need MDS version at least 2.10.55"
19956
19957         mkdir -p $DIR/$tdir
19958         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19959
19960         # inherit default DoM striping
19961         mkdir $DIR/$tdir/subdir
19962         touch $DIR/$tdir/subdir/f1
19963
19964         # change default directory striping
19965         $LFS setstripe -c 1 $DIR/$tdir/subdir
19966         touch $DIR/$tdir/subdir/f2
19967         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19968                 error "wrong default striping in file 2"
19969         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19970                 error "bad pattern in file 2"
19971         return 0
19972 }
19973 run_test 270d "DoM: change striping from DoM to RAID0"
19974
19975 test_270e() {
19976         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19977                 skip "Need MDS version at least 2.10.55"
19978
19979         mkdir -p $DIR/$tdir/dom
19980         mkdir -p $DIR/$tdir/norm
19981         DOMFILES=20
19982         NORMFILES=10
19983         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19984         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19985
19986         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19987         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19988
19989         # find DoM files by layout
19990         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19991         [ $NUM -eq  $DOMFILES ] ||
19992                 error "lfs find -L: found $NUM, expected $DOMFILES"
19993         echo "Test 1: lfs find 20 DOM files by layout: OK"
19994
19995         # there should be 1 dir with default DOM striping
19996         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19997         [ $NUM -eq  1 ] ||
19998                 error "lfs find -L: found $NUM, expected 1 dir"
19999         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20000
20001         # find DoM files by stripe size
20002         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20003         [ $NUM -eq  $DOMFILES ] ||
20004                 error "lfs find -S: found $NUM, expected $DOMFILES"
20005         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20006
20007         # find files by stripe offset except DoM files
20008         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20009         [ $NUM -eq  $NORMFILES ] ||
20010                 error "lfs find -i: found $NUM, expected $NORMFILES"
20011         echo "Test 5: lfs find no DOM files by stripe index: OK"
20012         return 0
20013 }
20014 run_test 270e "DoM: lfs find with DoM files test"
20015
20016 test_270f() {
20017         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20018                 skip "Need MDS version at least 2.10.55"
20019
20020         local mdtname=${FSNAME}-MDT0000-mdtlov
20021         local dom=$DIR/$tdir/dom_file
20022         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20023                                                 lod.$mdtname.dom_stripesize)
20024         local dom_limit=131072
20025
20026         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20027         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20028                                                 lod.$mdtname.dom_stripesize)
20029         [ ${dom_limit} -eq ${dom_current} ] ||
20030                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20031
20032         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20033         $LFS setstripe -d $DIR/$tdir
20034         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20035                 error "Can't set directory default striping"
20036
20037         # exceed maximum stripe size
20038         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20039                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20040         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20041                 error "Able to create DoM component size more than LOD limit"
20042
20043         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20044         dom_current=$(do_facet mds1 $LCTL get_param -n \
20045                                                 lod.$mdtname.dom_stripesize)
20046         [ 0 -eq ${dom_current} ] ||
20047                 error "Can't set zero DoM stripe limit"
20048         rm $dom
20049
20050         # attempt to create DoM file on server with disabled DoM should
20051         # remove DoM entry from layout and be succeed
20052         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20053                 error "Can't create DoM file (DoM is disabled)"
20054         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20055                 error "File has DoM component while DoM is disabled"
20056         rm $dom
20057
20058         # attempt to create DoM file with only DoM stripe should return error
20059         $LFS setstripe -E $dom_limit -L mdt $dom &&
20060                 error "Able to create DoM-only file while DoM is disabled"
20061
20062         # too low values to be aligned with smallest stripe size 64K
20063         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20064         dom_current=$(do_facet mds1 $LCTL get_param -n \
20065                                                 lod.$mdtname.dom_stripesize)
20066         [ 30000 -eq ${dom_current} ] &&
20067                 error "Can set too small DoM stripe limit"
20068
20069         # 64K is a minimal stripe size in Lustre, expect limit of that size
20070         [ 65536 -eq ${dom_current} ] ||
20071                 error "Limit is not set to 64K but ${dom_current}"
20072
20073         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20074         dom_current=$(do_facet mds1 $LCTL get_param -n \
20075                                                 lod.$mdtname.dom_stripesize)
20076         echo $dom_current
20077         [ 2147483648 -eq ${dom_current} ] &&
20078                 error "Can set too large DoM stripe limit"
20079
20080         do_facet mds1 $LCTL set_param -n \
20081                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20082         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20083                 error "Can't create DoM component size after limit change"
20084         do_facet mds1 $LCTL set_param -n \
20085                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20086         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20087                 error "Can't create DoM file after limit decrease"
20088         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20089                 error "Can create big DoM component after limit decrease"
20090         touch ${dom}_def ||
20091                 error "Can't create file with old default layout"
20092
20093         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20094         return 0
20095 }
20096 run_test 270f "DoM: maximum DoM stripe size checks"
20097
20098 test_270g() {
20099         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20100                 skip "Need MDS version at least 2.13.52"
20101         local dom=$DIR/$tdir/$tfile
20102
20103         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20104         local lodname=${FSNAME}-MDT0000-mdtlov
20105
20106         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20107         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20108         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20109         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20110
20111         local dom_limit=1024
20112         local dom_threshold="50%"
20113
20114         $LFS setstripe -d $DIR/$tdir
20115         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20116                 error "Can't set directory default striping"
20117
20118         do_facet mds1 $LCTL set_param -n \
20119                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20120         # set 0 threshold and create DOM file to change tunable stripesize
20121         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20122         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20123                 error "Failed to create $dom file"
20124         # now tunable dom_cur_stripesize should reach maximum
20125         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20126                                         lod.${lodname}.dom_stripesize_cur_kb)
20127         [[ $dom_current == $dom_limit ]] ||
20128                 error "Current DOM stripesize is not maximum"
20129         rm $dom
20130
20131         # set threshold for further tests
20132         do_facet mds1 $LCTL set_param -n \
20133                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20134         echo "DOM threshold is $dom_threshold free space"
20135         local dom_def
20136         local dom_set
20137         # Spoof bfree to exceed threshold
20138         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20139         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20140         for spfree in 40 20 0 15 30 55; do
20141                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20142                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20143                         error "Failed to create $dom file"
20144                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20145                                         lod.${lodname}.dom_stripesize_cur_kb)
20146                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20147                 [[ $dom_def != $dom_current ]] ||
20148                         error "Default stripe size was not changed"
20149                 if [[ $spfree > 0 ]] ; then
20150                         dom_set=$($LFS getstripe -S $dom)
20151                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20152                                 error "DOM component size is still old"
20153                 else
20154                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20155                                 error "DoM component is set with no free space"
20156                 fi
20157                 rm $dom
20158                 dom_current=$dom_def
20159         done
20160 }
20161 run_test 270g "DoM: default DoM stripe size depends on free space"
20162
20163 test_270h() {
20164         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20165                 skip "Need MDS version at least 2.13.53"
20166
20167         local mdtname=${FSNAME}-MDT0000-mdtlov
20168         local dom=$DIR/$tdir/$tfile
20169         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20170
20171         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20172         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20173
20174         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20175         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20176                 error "can't create OST file"
20177         # mirrored file with DOM entry in the second mirror
20178         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20179                 error "can't create mirror with DoM component"
20180
20181         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20182
20183         # DOM component in the middle and has other enries in the same mirror,
20184         # should succeed but lost DoM component
20185         $LFS setstripe --copy=${dom}_1 $dom ||
20186                 error "Can't create file from OST|DOM mirror layout"
20187         # check new file has no DoM layout after all
20188         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20189                 error "File has DoM component while DoM is disabled"
20190 }
20191 run_test 270h "DoM: DoM stripe removal when disabled on server"
20192
20193 test_271a() {
20194         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20195                 skip "Need MDS version at least 2.10.55"
20196
20197         local dom=$DIR/$tdir/dom
20198
20199         mkdir -p $DIR/$tdir
20200
20201         $LFS setstripe -E 1024K -L mdt $dom
20202
20203         lctl set_param -n mdc.*.stats=clear
20204         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20205         cat $dom > /dev/null
20206         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20207         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20208         ls $dom
20209         rm -f $dom
20210 }
20211 run_test 271a "DoM: data is cached for read after write"
20212
20213 test_271b() {
20214         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20215                 skip "Need MDS version at least 2.10.55"
20216
20217         local dom=$DIR/$tdir/dom
20218
20219         mkdir -p $DIR/$tdir
20220
20221         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20222
20223         lctl set_param -n mdc.*.stats=clear
20224         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20225         cancel_lru_locks mdc
20226         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20227         # second stat to check size is cached on client
20228         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20229         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20230         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20231         rm -f $dom
20232 }
20233 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20234
20235 test_271ba() {
20236         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20237                 skip "Need MDS version at least 2.10.55"
20238
20239         local dom=$DIR/$tdir/dom
20240
20241         mkdir -p $DIR/$tdir
20242
20243         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20244
20245         lctl set_param -n mdc.*.stats=clear
20246         lctl set_param -n osc.*.stats=clear
20247         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20248         cancel_lru_locks mdc
20249         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20250         # second stat to check size is cached on client
20251         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20252         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20253         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20254         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20255         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20256         rm -f $dom
20257 }
20258 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20259
20260
20261 get_mdc_stats() {
20262         local mdtidx=$1
20263         local param=$2
20264         local mdt=MDT$(printf %04x $mdtidx)
20265
20266         if [ -z $param ]; then
20267                 lctl get_param -n mdc.*$mdt*.stats
20268         else
20269                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20270         fi
20271 }
20272
20273 test_271c() {
20274         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20275                 skip "Need MDS version at least 2.10.55"
20276
20277         local dom=$DIR/$tdir/dom
20278
20279         mkdir -p $DIR/$tdir
20280
20281         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20282
20283         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20284         local facet=mds$((mdtidx + 1))
20285
20286         cancel_lru_locks mdc
20287         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20288         createmany -o $dom 1000
20289         lctl set_param -n mdc.*.stats=clear
20290         smalliomany -w $dom 1000 200
20291         get_mdc_stats $mdtidx
20292         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20293         # Each file has 1 open, 1 IO enqueues, total 2000
20294         # but now we have also +1 getxattr for security.capability, total 3000
20295         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20296         unlinkmany $dom 1000
20297
20298         cancel_lru_locks mdc
20299         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20300         createmany -o $dom 1000
20301         lctl set_param -n mdc.*.stats=clear
20302         smalliomany -w $dom 1000 200
20303         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20304         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20305         # for OPEN and IO lock.
20306         [ $((enq - enq_2)) -ge 1000 ] ||
20307                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20308         unlinkmany $dom 1000
20309         return 0
20310 }
20311 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20312
20313 cleanup_271def_tests() {
20314         trap 0
20315         rm -f $1
20316 }
20317
20318 test_271d() {
20319         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20320                 skip "Need MDS version at least 2.10.57"
20321
20322         local dom=$DIR/$tdir/dom
20323         local tmp=$TMP/$tfile
20324         trap "cleanup_271def_tests $tmp" EXIT
20325
20326         mkdir -p $DIR/$tdir
20327
20328         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20329
20330         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20331
20332         cancel_lru_locks mdc
20333         dd if=/dev/urandom of=$tmp bs=1000 count=1
20334         dd if=$tmp of=$dom bs=1000 count=1
20335         cancel_lru_locks mdc
20336
20337         cat /etc/hosts >> $tmp
20338         lctl set_param -n mdc.*.stats=clear
20339
20340         # append data to the same file it should update local page
20341         echo "Append to the same page"
20342         cat /etc/hosts >> $dom
20343         local num=$(get_mdc_stats $mdtidx ost_read)
20344         local ra=$(get_mdc_stats $mdtidx req_active)
20345         local rw=$(get_mdc_stats $mdtidx req_waittime)
20346
20347         [ -z $num ] || error "$num READ RPC occured"
20348         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20349         echo "... DONE"
20350
20351         # compare content
20352         cmp $tmp $dom || error "file miscompare"
20353
20354         cancel_lru_locks mdc
20355         lctl set_param -n mdc.*.stats=clear
20356
20357         echo "Open and read file"
20358         cat $dom > /dev/null
20359         local num=$(get_mdc_stats $mdtidx ost_read)
20360         local ra=$(get_mdc_stats $mdtidx req_active)
20361         local rw=$(get_mdc_stats $mdtidx req_waittime)
20362
20363         [ -z $num ] || error "$num READ RPC occured"
20364         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20365         echo "... DONE"
20366
20367         # compare content
20368         cmp $tmp $dom || error "file miscompare"
20369
20370         return 0
20371 }
20372 run_test 271d "DoM: read on open (1K file in reply buffer)"
20373
20374 test_271f() {
20375         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20376                 skip "Need MDS version at least 2.10.57"
20377
20378         local dom=$DIR/$tdir/dom
20379         local tmp=$TMP/$tfile
20380         trap "cleanup_271def_tests $tmp" EXIT
20381
20382         mkdir -p $DIR/$tdir
20383
20384         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20385
20386         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20387
20388         cancel_lru_locks mdc
20389         dd if=/dev/urandom of=$tmp bs=265000 count=1
20390         dd if=$tmp of=$dom bs=265000 count=1
20391         cancel_lru_locks mdc
20392         cat /etc/hosts >> $tmp
20393         lctl set_param -n mdc.*.stats=clear
20394
20395         echo "Append to the same page"
20396         cat /etc/hosts >> $dom
20397         local num=$(get_mdc_stats $mdtidx ost_read)
20398         local ra=$(get_mdc_stats $mdtidx req_active)
20399         local rw=$(get_mdc_stats $mdtidx req_waittime)
20400
20401         [ -z $num ] || error "$num READ RPC occured"
20402         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20403         echo "... DONE"
20404
20405         # compare content
20406         cmp $tmp $dom || error "file miscompare"
20407
20408         cancel_lru_locks mdc
20409         lctl set_param -n mdc.*.stats=clear
20410
20411         echo "Open and read file"
20412         cat $dom > /dev/null
20413         local num=$(get_mdc_stats $mdtidx ost_read)
20414         local ra=$(get_mdc_stats $mdtidx req_active)
20415         local rw=$(get_mdc_stats $mdtidx req_waittime)
20416
20417         [ -z $num ] && num=0
20418         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20419         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20420         echo "... DONE"
20421
20422         # compare content
20423         cmp $tmp $dom || error "file miscompare"
20424
20425         return 0
20426 }
20427 run_test 271f "DoM: read on open (200K file and read tail)"
20428
20429 test_271g() {
20430         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20431                 skip "Skipping due to old client or server version"
20432
20433         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20434         # to get layout
20435         $CHECKSTAT -t file $DIR1/$tfile
20436
20437         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20438         MULTIOP_PID=$!
20439         sleep 1
20440         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20441         $LCTL set_param fail_loc=0x80000314
20442         rm $DIR1/$tfile || error "Unlink fails"
20443         RC=$?
20444         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20445         [ $RC -eq 0 ] || error "Failed write to stale object"
20446 }
20447 run_test 271g "Discard DoM data vs client flush race"
20448
20449 test_272a() {
20450         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20451                 skip "Need MDS version at least 2.11.50"
20452
20453         local dom=$DIR/$tdir/dom
20454         mkdir -p $DIR/$tdir
20455
20456         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20457         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20458                 error "failed to write data into $dom"
20459         local old_md5=$(md5sum $dom)
20460
20461         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20462                 error "failed to migrate to the same DoM component"
20463
20464         local new_md5=$(md5sum $dom)
20465
20466         [ "$old_md5" == "$new_md5" ] ||
20467                 error "md5sum differ: $old_md5, $new_md5"
20468
20469         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20470                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20471 }
20472 run_test 272a "DoM migration: new layout with the same DOM component"
20473
20474 test_272b() {
20475         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20476                 skip "Need MDS version at least 2.11.50"
20477
20478         local dom=$DIR/$tdir/dom
20479         mkdir -p $DIR/$tdir
20480         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20481
20482         local mdtidx=$($LFS getstripe -m $dom)
20483         local mdtname=MDT$(printf %04x $mdtidx)
20484         local facet=mds$((mdtidx + 1))
20485
20486         local mdtfree1=$(do_facet $facet \
20487                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20488         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20489                 error "failed to write data into $dom"
20490         local old_md5=$(md5sum $dom)
20491         cancel_lru_locks mdc
20492         local mdtfree1=$(do_facet $facet \
20493                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20494
20495         $LFS migrate -c2 $dom ||
20496                 error "failed to migrate to the new composite layout"
20497         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20498                 error "MDT stripe was not removed"
20499
20500         cancel_lru_locks mdc
20501         local new_md5=$(md5sum $dom)
20502         [ "$old_md5" == "$new_md5" ] ||
20503                 error "$old_md5 != $new_md5"
20504
20505         # Skip free space checks with ZFS
20506         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20507                 local mdtfree2=$(do_facet $facet \
20508                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20509                 [ $mdtfree2 -gt $mdtfree1 ] ||
20510                         error "MDT space is not freed after migration"
20511         fi
20512         return 0
20513 }
20514 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20515
20516 test_272c() {
20517         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20518                 skip "Need MDS version at least 2.11.50"
20519
20520         local dom=$DIR/$tdir/$tfile
20521         mkdir -p $DIR/$tdir
20522         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20523
20524         local mdtidx=$($LFS getstripe -m $dom)
20525         local mdtname=MDT$(printf %04x $mdtidx)
20526         local facet=mds$((mdtidx + 1))
20527
20528         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20529                 error "failed to write data into $dom"
20530         local old_md5=$(md5sum $dom)
20531         cancel_lru_locks mdc
20532         local mdtfree1=$(do_facet $facet \
20533                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20534
20535         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20536                 error "failed to migrate to the new composite layout"
20537         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20538                 error "MDT stripe was not removed"
20539
20540         cancel_lru_locks mdc
20541         local new_md5=$(md5sum $dom)
20542         [ "$old_md5" == "$new_md5" ] ||
20543                 error "$old_md5 != $new_md5"
20544
20545         # Skip free space checks with ZFS
20546         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20547                 local mdtfree2=$(do_facet $facet \
20548                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20549                 [ $mdtfree2 -gt $mdtfree1 ] ||
20550                         error "MDS space is not freed after migration"
20551         fi
20552         return 0
20553 }
20554 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20555
20556 test_272d() {
20557         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20558                 skip "Need MDS version at least 2.12.55"
20559
20560         local dom=$DIR/$tdir/$tfile
20561         mkdir -p $DIR/$tdir
20562         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20563
20564         local mdtidx=$($LFS getstripe -m $dom)
20565         local mdtname=MDT$(printf %04x $mdtidx)
20566         local facet=mds$((mdtidx + 1))
20567
20568         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20569                 error "failed to write data into $dom"
20570         local old_md5=$(md5sum $dom)
20571         cancel_lru_locks mdc
20572         local mdtfree1=$(do_facet $facet \
20573                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20574
20575         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20576                 error "failed mirroring to the new composite layout"
20577         $LFS mirror resync $dom ||
20578                 error "failed mirror resync"
20579         $LFS mirror split --mirror-id 1 -d $dom ||
20580                 error "failed mirror split"
20581
20582         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20583                 error "MDT stripe was not removed"
20584
20585         cancel_lru_locks mdc
20586         local new_md5=$(md5sum $dom)
20587         [ "$old_md5" == "$new_md5" ] ||
20588                 error "$old_md5 != $new_md5"
20589
20590         # Skip free space checks with ZFS
20591         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20592                 local mdtfree2=$(do_facet $facet \
20593                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20594                 [ $mdtfree2 -gt $mdtfree1 ] ||
20595                         error "MDS space is not freed after DOM mirror deletion"
20596         fi
20597         return 0
20598 }
20599 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20600
20601 test_272e() {
20602         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20603                 skip "Need MDS version at least 2.12.55"
20604
20605         local dom=$DIR/$tdir/$tfile
20606         mkdir -p $DIR/$tdir
20607         $LFS setstripe -c 2 $dom
20608
20609         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20610                 error "failed to write data into $dom"
20611         local old_md5=$(md5sum $dom)
20612         cancel_lru_locks mdc
20613
20614         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20615                 error "failed mirroring to the DOM layout"
20616         $LFS mirror resync $dom ||
20617                 error "failed mirror resync"
20618         $LFS mirror split --mirror-id 1 -d $dom ||
20619                 error "failed mirror split"
20620
20621         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20622                 error "MDT stripe was not removed"
20623
20624         cancel_lru_locks mdc
20625         local new_md5=$(md5sum $dom)
20626         [ "$old_md5" == "$new_md5" ] ||
20627                 error "$old_md5 != $new_md5"
20628
20629         return 0
20630 }
20631 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20632
20633 test_272f() {
20634         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20635                 skip "Need MDS version at least 2.12.55"
20636
20637         local dom=$DIR/$tdir/$tfile
20638         mkdir -p $DIR/$tdir
20639         $LFS setstripe -c 2 $dom
20640
20641         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20642                 error "failed to write data into $dom"
20643         local old_md5=$(md5sum $dom)
20644         cancel_lru_locks mdc
20645
20646         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20647                 error "failed migrating to the DOM file"
20648
20649         cancel_lru_locks mdc
20650         local new_md5=$(md5sum $dom)
20651         [ "$old_md5" != "$new_md5" ] &&
20652                 error "$old_md5 != $new_md5"
20653
20654         return 0
20655 }
20656 run_test 272f "DoM migration: OST-striped file to DOM file"
20657
20658 test_273a() {
20659         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20660                 skip "Need MDS version at least 2.11.50"
20661
20662         # Layout swap cannot be done if either file has DOM component,
20663         # this will never be supported, migration should be used instead
20664
20665         local dom=$DIR/$tdir/$tfile
20666         mkdir -p $DIR/$tdir
20667
20668         $LFS setstripe -c2 ${dom}_plain
20669         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20670         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20671                 error "can swap layout with DoM component"
20672         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20673                 error "can swap layout with DoM component"
20674
20675         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20676         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20677                 error "can swap layout with DoM component"
20678         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20679                 error "can swap layout with DoM component"
20680         return 0
20681 }
20682 run_test 273a "DoM: layout swapping should fail with DOM"
20683
20684 test_275() {
20685         remote_ost_nodsh && skip "remote OST with nodsh"
20686         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20687                 skip "Need OST version >= 2.10.57"
20688
20689         local file=$DIR/$tfile
20690         local oss
20691
20692         oss=$(comma_list $(osts_nodes))
20693
20694         dd if=/dev/urandom of=$file bs=1M count=2 ||
20695                 error "failed to create a file"
20696         cancel_lru_locks osc
20697
20698         #lock 1
20699         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20700                 error "failed to read a file"
20701
20702 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20703         $LCTL set_param fail_loc=0x8000031f
20704
20705         cancel_lru_locks osc &
20706         sleep 1
20707
20708 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20709         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20710         #IO takes another lock, but matches the PENDING one
20711         #and places it to the IO RPC
20712         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20713                 error "failed to read a file with PENDING lock"
20714 }
20715 run_test 275 "Read on a canceled duplicate lock"
20716
20717 test_276() {
20718         remote_ost_nodsh && skip "remote OST with nodsh"
20719         local pid
20720
20721         do_facet ost1 "(while true; do \
20722                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20723                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20724         pid=$!
20725
20726         for LOOP in $(seq 20); do
20727                 stop ost1
20728                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20729         done
20730         kill -9 $pid
20731         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20732                 rm $TMP/sanity_276_pid"
20733 }
20734 run_test 276 "Race between mount and obd_statfs"
20735
20736 test_277() {
20737         $LCTL set_param ldlm.namespaces.*.lru_size=0
20738         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20739         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20740                         grep ^used_mb | awk '{print $2}')
20741         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20743                 oflag=direct conv=notrunc
20744         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20745                         grep ^used_mb | awk '{print $2}')
20746         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20747 }
20748 run_test 277 "Direct IO shall drop page cache"
20749
20750 test_278() {
20751         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20752         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20753         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20754                 skip "needs the same host for mdt1 mdt2" && return
20755
20756         local pid1
20757         local pid2
20758
20759 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20760         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20761         stop mds2 &
20762         pid2=$!
20763
20764         stop mds1
20765
20766         echo "Starting MDTs"
20767         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20768         wait $pid2
20769 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20770 #will return NULL
20771         do_facet mds2 $LCTL set_param fail_loc=0
20772
20773         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20774         wait_recovery_complete mds2
20775 }
20776 run_test 278 "Race starting MDS between MDTs stop/start"
20777
20778 test_280() {
20779         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20780                 skip "Need MGS version at least 2.13.52"
20781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20782         combined_mgs_mds || skip "needs combined MGS/MDT"
20783
20784         umount_client $MOUNT
20785 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20786         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20787
20788         mount_client $MOUNT &
20789         sleep 1
20790         stop mgs || error "stop mgs failed"
20791         #for a race mgs would crash
20792         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20793         mount_client $MOUNT || error "mount client failed"
20794 }
20795 run_test 280 "Race between MGS umount and client llog processing"
20796
20797 cleanup_test_300() {
20798         trap 0
20799         umask $SAVE_UMASK
20800 }
20801 test_striped_dir() {
20802         local mdt_index=$1
20803         local stripe_count
20804         local stripe_index
20805
20806         mkdir -p $DIR/$tdir
20807
20808         SAVE_UMASK=$(umask)
20809         trap cleanup_test_300 RETURN EXIT
20810
20811         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20812                                                 $DIR/$tdir/striped_dir ||
20813                 error "set striped dir error"
20814
20815         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20816         [ "$mode" = "755" ] || error "expect 755 got $mode"
20817
20818         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20819                 error "getdirstripe failed"
20820         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20821         if [ "$stripe_count" != "2" ]; then
20822                 error "1:stripe_count is $stripe_count, expect 2"
20823         fi
20824         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20825         if [ "$stripe_count" != "2" ]; then
20826                 error "2:stripe_count is $stripe_count, expect 2"
20827         fi
20828
20829         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20830         if [ "$stripe_index" != "$mdt_index" ]; then
20831                 error "stripe_index is $stripe_index, expect $mdt_index"
20832         fi
20833
20834         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20835                 error "nlink error after create striped dir"
20836
20837         mkdir $DIR/$tdir/striped_dir/a
20838         mkdir $DIR/$tdir/striped_dir/b
20839
20840         stat $DIR/$tdir/striped_dir/a ||
20841                 error "create dir under striped dir failed"
20842         stat $DIR/$tdir/striped_dir/b ||
20843                 error "create dir under striped dir failed"
20844
20845         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20846                 error "nlink error after mkdir"
20847
20848         rmdir $DIR/$tdir/striped_dir/a
20849         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20850                 error "nlink error after rmdir"
20851
20852         rmdir $DIR/$tdir/striped_dir/b
20853         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20854                 error "nlink error after rmdir"
20855
20856         chattr +i $DIR/$tdir/striped_dir
20857         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20858                 error "immutable flags not working under striped dir!"
20859         chattr -i $DIR/$tdir/striped_dir
20860
20861         rmdir $DIR/$tdir/striped_dir ||
20862                 error "rmdir striped dir error"
20863
20864         cleanup_test_300
20865
20866         true
20867 }
20868
20869 test_300a() {
20870         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20871                 skip "skipped for lustre < 2.7.0"
20872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20873         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20874
20875         test_striped_dir 0 || error "failed on striped dir on MDT0"
20876         test_striped_dir 1 || error "failed on striped dir on MDT0"
20877 }
20878 run_test 300a "basic striped dir sanity test"
20879
20880 test_300b() {
20881         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20882                 skip "skipped for lustre < 2.7.0"
20883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20885
20886         local i
20887         local mtime1
20888         local mtime2
20889         local mtime3
20890
20891         test_mkdir $DIR/$tdir || error "mkdir fail"
20892         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20893                 error "set striped dir error"
20894         for i in {0..9}; do
20895                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20896                 sleep 1
20897                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20898                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20899                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20900                 sleep 1
20901                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20902                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20903                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20904         done
20905         true
20906 }
20907 run_test 300b "check ctime/mtime for striped dir"
20908
20909 test_300c() {
20910         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20911                 skip "skipped for lustre < 2.7.0"
20912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20914
20915         local file_count
20916
20917         mkdir -p $DIR/$tdir
20918         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20919                 error "set striped dir error"
20920
20921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20922                 error "chown striped dir failed"
20923
20924         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20925                 error "create 5k files failed"
20926
20927         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20928
20929         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20930
20931         rm -rf $DIR/$tdir
20932 }
20933 run_test 300c "chown && check ls under striped directory"
20934
20935 test_300d() {
20936         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20937                 skip "skipped for lustre < 2.7.0"
20938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20940
20941         local stripe_count
20942         local file
20943
20944         mkdir -p $DIR/$tdir
20945         $LFS setstripe -c 2 $DIR/$tdir
20946
20947         #local striped directory
20948         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20949                 error "set striped dir error"
20950         #look at the directories for debug purposes
20951         ls -l $DIR/$tdir
20952         $LFS getdirstripe $DIR/$tdir
20953         ls -l $DIR/$tdir/striped_dir
20954         $LFS getdirstripe $DIR/$tdir/striped_dir
20955         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20956                 error "create 10 files failed"
20957
20958         #remote striped directory
20959         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20960                 error "set striped dir error"
20961         #look at the directories for debug purposes
20962         ls -l $DIR/$tdir
20963         $LFS getdirstripe $DIR/$tdir
20964         ls -l $DIR/$tdir/remote_striped_dir
20965         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20966         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20967                 error "create 10 files failed"
20968
20969         for file in $(find $DIR/$tdir); do
20970                 stripe_count=$($LFS getstripe -c $file)
20971                 [ $stripe_count -eq 2 ] ||
20972                         error "wrong stripe $stripe_count for $file"
20973         done
20974
20975         rm -rf $DIR/$tdir
20976 }
20977 run_test 300d "check default stripe under striped directory"
20978
20979 test_300e() {
20980         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20981                 skip "Need MDS version at least 2.7.55"
20982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20983         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20984
20985         local stripe_count
20986         local file
20987
20988         mkdir -p $DIR/$tdir
20989
20990         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20991                 error "set striped dir error"
20992
20993         touch $DIR/$tdir/striped_dir/a
20994         touch $DIR/$tdir/striped_dir/b
20995         touch $DIR/$tdir/striped_dir/c
20996
20997         mkdir $DIR/$tdir/striped_dir/dir_a
20998         mkdir $DIR/$tdir/striped_dir/dir_b
20999         mkdir $DIR/$tdir/striped_dir/dir_c
21000
21001         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21002                 error "set striped adir under striped dir error"
21003
21004         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21005                 error "set striped bdir under striped dir error"
21006
21007         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21008                 error "set striped cdir under striped dir error"
21009
21010         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21011                 error "rename dir under striped dir fails"
21012
21013         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21014                 error "rename dir under different stripes fails"
21015
21016         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21017                 error "rename file under striped dir should succeed"
21018
21019         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21020                 error "rename dir under striped dir should succeed"
21021
21022         rm -rf $DIR/$tdir
21023 }
21024 run_test 300e "check rename under striped directory"
21025
21026 test_300f() {
21027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21028         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21029         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21030                 skip "Need MDS version at least 2.7.55"
21031
21032         local stripe_count
21033         local file
21034
21035         rm -rf $DIR/$tdir
21036         mkdir -p $DIR/$tdir
21037
21038         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21039                 error "set striped dir error"
21040
21041         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21042                 error "set striped dir error"
21043
21044         touch $DIR/$tdir/striped_dir/a
21045         mkdir $DIR/$tdir/striped_dir/dir_a
21046         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21047                 error "create striped dir under striped dir fails"
21048
21049         touch $DIR/$tdir/striped_dir1/b
21050         mkdir $DIR/$tdir/striped_dir1/dir_b
21051         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21052                 error "create striped dir under striped dir fails"
21053
21054         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21055                 error "rename dir under different striped dir should fail"
21056
21057         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21058                 error "rename striped dir under diff striped dir should fail"
21059
21060         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21061                 error "rename file under diff striped dirs fails"
21062
21063         rm -rf $DIR/$tdir
21064 }
21065 run_test 300f "check rename cross striped directory"
21066
21067 test_300_check_default_striped_dir()
21068 {
21069         local dirname=$1
21070         local default_count=$2
21071         local default_index=$3
21072         local stripe_count
21073         local stripe_index
21074         local dir_stripe_index
21075         local dir
21076
21077         echo "checking $dirname $default_count $default_index"
21078         $LFS setdirstripe -D -c $default_count -i $default_index \
21079                                 -t all_char $DIR/$tdir/$dirname ||
21080                 error "set default stripe on striped dir error"
21081         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21082         [ $stripe_count -eq $default_count ] ||
21083                 error "expect $default_count get $stripe_count for $dirname"
21084
21085         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21086         [ $stripe_index -eq $default_index ] ||
21087                 error "expect $default_index get $stripe_index for $dirname"
21088
21089         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21090                                                 error "create dirs failed"
21091
21092         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21093         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21094         for dir in $(find $DIR/$tdir/$dirname/*); do
21095                 stripe_count=$($LFS getdirstripe -c $dir)
21096                 [ $stripe_count -eq $default_count ] ||
21097                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21098                 error "stripe count $default_count != $stripe_count for $dir"
21099
21100                 stripe_index=$($LFS getdirstripe -i $dir)
21101                 [ $default_index -eq -1 ] ||
21102                         [ $stripe_index -eq $default_index ] ||
21103                         error "$stripe_index != $default_index for $dir"
21104
21105                 #check default stripe
21106                 stripe_count=$($LFS getdirstripe -D -c $dir)
21107                 [ $stripe_count -eq $default_count ] ||
21108                 error "default count $default_count != $stripe_count for $dir"
21109
21110                 stripe_index=$($LFS getdirstripe -D -i $dir)
21111                 [ $stripe_index -eq $default_index ] ||
21112                 error "default index $default_index != $stripe_index for $dir"
21113         done
21114         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21115 }
21116
21117 test_300g() {
21118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21119         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21120                 skip "Need MDS version at least 2.7.55"
21121
21122         local dir
21123         local stripe_count
21124         local stripe_index
21125
21126         mkdir $DIR/$tdir
21127         mkdir $DIR/$tdir/normal_dir
21128
21129         #Checking when client cache stripe index
21130         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21131         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21132                 error "create striped_dir failed"
21133
21134         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21135                 error "create dir0 fails"
21136         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21137         [ $stripe_index -eq 0 ] ||
21138                 error "dir0 expect index 0 got $stripe_index"
21139
21140         mkdir $DIR/$tdir/striped_dir/dir1 ||
21141                 error "create dir1 fails"
21142         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21143         [ $stripe_index -eq 1 ] ||
21144                 error "dir1 expect index 1 got $stripe_index"
21145
21146         #check default stripe count/stripe index
21147         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21148         test_300_check_default_striped_dir normal_dir 1 0
21149         test_300_check_default_striped_dir normal_dir 2 1
21150         test_300_check_default_striped_dir normal_dir 2 -1
21151
21152         #delete default stripe information
21153         echo "delete default stripeEA"
21154         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21155                 error "set default stripe on striped dir error"
21156
21157         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21158         for dir in $(find $DIR/$tdir/normal_dir/*); do
21159                 stripe_count=$($LFS getdirstripe -c $dir)
21160                 [ $stripe_count -eq 0 ] ||
21161                         error "expect 1 get $stripe_count for $dir"
21162                 stripe_index=$($LFS getdirstripe -i $dir)
21163                 [ $stripe_index -eq 0 ] ||
21164                         error "expect 0 get $stripe_index for $dir"
21165         done
21166 }
21167 run_test 300g "check default striped directory for normal directory"
21168
21169 test_300h() {
21170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21171         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21172                 skip "Need MDS version at least 2.7.55"
21173
21174         local dir
21175         local stripe_count
21176
21177         mkdir $DIR/$tdir
21178         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21179                 error "set striped dir error"
21180
21181         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21182         test_300_check_default_striped_dir striped_dir 1 0
21183         test_300_check_default_striped_dir striped_dir 2 1
21184         test_300_check_default_striped_dir striped_dir 2 -1
21185
21186         #delete default stripe information
21187         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21188                 error "set default stripe on striped dir error"
21189
21190         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21191         for dir in $(find $DIR/$tdir/striped_dir/*); do
21192                 stripe_count=$($LFS getdirstripe -c $dir)
21193                 [ $stripe_count -eq 0 ] ||
21194                         error "expect 1 get $stripe_count for $dir"
21195         done
21196 }
21197 run_test 300h "check default striped directory for striped directory"
21198
21199 test_300i() {
21200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21201         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21202         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21203                 skip "Need MDS version at least 2.7.55"
21204
21205         local stripe_count
21206         local file
21207
21208         mkdir $DIR/$tdir
21209
21210         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21211                 error "set striped dir error"
21212
21213         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21214                 error "create files under striped dir failed"
21215
21216         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21217                 error "set striped hashdir error"
21218
21219         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21220                 error "create dir0 under hash dir failed"
21221         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21222                 error "create dir1 under hash dir failed"
21223
21224         # unfortunately, we need to umount to clear dir layout cache for now
21225         # once we fully implement dir layout, we can drop this
21226         umount_client $MOUNT || error "umount failed"
21227         mount_client $MOUNT || error "mount failed"
21228
21229         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21230         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21231         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21232
21233         #set the stripe to be unknown hash type
21234         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21235         $LCTL set_param fail_loc=0x1901
21236         for ((i = 0; i < 10; i++)); do
21237                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21238                         error "stat f-$i failed"
21239                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21240         done
21241
21242         touch $DIR/$tdir/striped_dir/f0 &&
21243                 error "create under striped dir with unknown hash should fail"
21244
21245         $LCTL set_param fail_loc=0
21246
21247         umount_client $MOUNT || error "umount failed"
21248         mount_client $MOUNT || error "mount failed"
21249
21250         return 0
21251 }
21252 run_test 300i "client handle unknown hash type striped directory"
21253
21254 test_300j() {
21255         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21258                 skip "Need MDS version at least 2.7.55"
21259
21260         local stripe_count
21261         local file
21262
21263         mkdir $DIR/$tdir
21264
21265         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21266         $LCTL set_param fail_loc=0x1702
21267         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21268                 error "set striped dir error"
21269
21270         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21271                 error "create files under striped dir failed"
21272
21273         $LCTL set_param fail_loc=0
21274
21275         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21276
21277         return 0
21278 }
21279 run_test 300j "test large update record"
21280
21281 test_300k() {
21282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21284         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21285                 skip "Need MDS version at least 2.7.55"
21286
21287         # this test needs a huge transaction
21288         local kb
21289         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21290              osd*.$FSNAME-MDT0000.kbytestotal")
21291         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21292
21293         local stripe_count
21294         local file
21295
21296         mkdir $DIR/$tdir
21297
21298         #define OBD_FAIL_LARGE_STRIPE   0x1703
21299         $LCTL set_param fail_loc=0x1703
21300         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21301                 error "set striped dir error"
21302         $LCTL set_param fail_loc=0
21303
21304         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21305                 error "getstripeddir fails"
21306         rm -rf $DIR/$tdir/striped_dir ||
21307                 error "unlink striped dir fails"
21308
21309         return 0
21310 }
21311 run_test 300k "test large striped directory"
21312
21313 test_300l() {
21314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21315         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21316         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21317                 skip "Need MDS version at least 2.7.55"
21318
21319         local stripe_index
21320
21321         test_mkdir -p $DIR/$tdir/striped_dir
21322         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21323                         error "chown $RUNAS_ID failed"
21324         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21325                 error "set default striped dir failed"
21326
21327         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21328         $LCTL set_param fail_loc=0x80000158
21329         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21330
21331         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21332         [ $stripe_index -eq 1 ] ||
21333                 error "expect 1 get $stripe_index for $dir"
21334 }
21335 run_test 300l "non-root user to create dir under striped dir with stale layout"
21336
21337 test_300m() {
21338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21339         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21340         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21341                 skip "Need MDS version at least 2.7.55"
21342
21343         mkdir -p $DIR/$tdir/striped_dir
21344         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21345                 error "set default stripes dir error"
21346
21347         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21348
21349         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21350         [ $stripe_count -eq 0 ] ||
21351                         error "expect 0 get $stripe_count for a"
21352
21353         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21354                 error "set default stripes dir error"
21355
21356         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21357
21358         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21359         [ $stripe_count -eq 0 ] ||
21360                         error "expect 0 get $stripe_count for b"
21361
21362         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21363                 error "set default stripes dir error"
21364
21365         mkdir $DIR/$tdir/striped_dir/c &&
21366                 error "default stripe_index is invalid, mkdir c should fails"
21367
21368         rm -rf $DIR/$tdir || error "rmdir fails"
21369 }
21370 run_test 300m "setstriped directory on single MDT FS"
21371
21372 cleanup_300n() {
21373         local list=$(comma_list $(mdts_nodes))
21374
21375         trap 0
21376         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21377 }
21378
21379 test_300n() {
21380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21382         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21383                 skip "Need MDS version at least 2.7.55"
21384         remote_mds_nodsh && skip "remote MDS with nodsh"
21385
21386         local stripe_index
21387         local list=$(comma_list $(mdts_nodes))
21388
21389         trap cleanup_300n RETURN EXIT
21390         mkdir -p $DIR/$tdir
21391         chmod 777 $DIR/$tdir
21392         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21393                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21394                 error "create striped dir succeeds with gid=0"
21395
21396         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21397         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21398                 error "create striped dir fails with gid=-1"
21399
21400         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21401         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21402                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21403                 error "set default striped dir succeeds with gid=0"
21404
21405
21406         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21407         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21408                 error "set default striped dir fails with gid=-1"
21409
21410
21411         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21412         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21413                                         error "create test_dir fails"
21414         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21415                                         error "create test_dir1 fails"
21416         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21417                                         error "create test_dir2 fails"
21418         cleanup_300n
21419 }
21420 run_test 300n "non-root user to create dir under striped dir with default EA"
21421
21422 test_300o() {
21423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21424         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21425         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21426                 skip "Need MDS version at least 2.7.55"
21427
21428         local numfree1
21429         local numfree2
21430
21431         mkdir -p $DIR/$tdir
21432
21433         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21434         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21435         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21436                 skip "not enough free inodes $numfree1 $numfree2"
21437         fi
21438
21439         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21440         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21441         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21442                 skip "not enough free space $numfree1 $numfree2"
21443         fi
21444
21445         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21446                 error "setdirstripe fails"
21447
21448         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21449                 error "create dirs fails"
21450
21451         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21452         ls $DIR/$tdir/striped_dir > /dev/null ||
21453                 error "ls striped dir fails"
21454         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21455                 error "unlink big striped dir fails"
21456 }
21457 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21458
21459 test_300p() {
21460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21462         remote_mds_nodsh && skip "remote MDS with nodsh"
21463
21464         mkdir -p $DIR/$tdir
21465
21466         #define OBD_FAIL_OUT_ENOSPC     0x1704
21467         do_facet mds2 lctl set_param fail_loc=0x80001704
21468         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21469                  && error "create striped directory should fail"
21470
21471         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21472
21473         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21474         true
21475 }
21476 run_test 300p "create striped directory without space"
21477
21478 test_300q() {
21479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21481
21482         local fd=$(free_fd)
21483         local cmd="exec $fd<$tdir"
21484         cd $DIR
21485         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21486         eval $cmd
21487         cmd="exec $fd<&-"
21488         trap "eval $cmd" EXIT
21489         cd $tdir || error "cd $tdir fails"
21490         rmdir  ../$tdir || error "rmdir $tdir fails"
21491         mkdir local_dir && error "create dir succeeds"
21492         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21493         eval $cmd
21494         return 0
21495 }
21496 run_test 300q "create remote directory under orphan directory"
21497
21498 test_300r() {
21499         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21500                 skip "Need MDS version at least 2.7.55" && return
21501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21502
21503         mkdir $DIR/$tdir
21504
21505         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21506                 error "set striped dir error"
21507
21508         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21509                 error "getstripeddir fails"
21510
21511         local stripe_count
21512         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21513                       awk '/lmv_stripe_count:/ { print $2 }')
21514
21515         [ $MDSCOUNT -ne $stripe_count ] &&
21516                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21517
21518         rm -rf $DIR/$tdir/striped_dir ||
21519                 error "unlink striped dir fails"
21520 }
21521 run_test 300r "test -1 striped directory"
21522
21523 prepare_remote_file() {
21524         mkdir $DIR/$tdir/src_dir ||
21525                 error "create remote source failed"
21526
21527         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21528                  error "cp to remote source failed"
21529         touch $DIR/$tdir/src_dir/a
21530
21531         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21532                 error "create remote target dir failed"
21533
21534         touch $DIR/$tdir/tgt_dir/b
21535
21536         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21537                 error "rename dir cross MDT failed!"
21538
21539         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21540                 error "src_child still exists after rename"
21541
21542         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21543                 error "missing file(a) after rename"
21544
21545         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21546                 error "diff after rename"
21547 }
21548
21549 test_310a() {
21550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21552
21553         local remote_file=$DIR/$tdir/tgt_dir/b
21554
21555         mkdir -p $DIR/$tdir
21556
21557         prepare_remote_file || error "prepare remote file failed"
21558
21559         #open-unlink file
21560         $OPENUNLINK $remote_file $remote_file ||
21561                 error "openunlink $remote_file failed"
21562         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21563 }
21564 run_test 310a "open unlink remote file"
21565
21566 test_310b() {
21567         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21569
21570         local remote_file=$DIR/$tdir/tgt_dir/b
21571
21572         mkdir -p $DIR/$tdir
21573
21574         prepare_remote_file || error "prepare remote file failed"
21575
21576         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21577         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21578         $CHECKSTAT -t file $remote_file || error "check file failed"
21579 }
21580 run_test 310b "unlink remote file with multiple links while open"
21581
21582 test_310c() {
21583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21584         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21585
21586         local remote_file=$DIR/$tdir/tgt_dir/b
21587
21588         mkdir -p $DIR/$tdir
21589
21590         prepare_remote_file || error "prepare remote file failed"
21591
21592         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21593         multiop_bg_pause $remote_file O_uc ||
21594                         error "mulitop failed for remote file"
21595         MULTIPID=$!
21596         $MULTIOP $DIR/$tfile Ouc
21597         kill -USR1 $MULTIPID
21598         wait $MULTIPID
21599 }
21600 run_test 310c "open-unlink remote file with multiple links"
21601
21602 #LU-4825
21603 test_311() {
21604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21605         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21606         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21607                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21608         remote_mds_nodsh && skip "remote MDS with nodsh"
21609
21610         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21611         local mdts=$(comma_list $(mdts_nodes))
21612
21613         mkdir -p $DIR/$tdir
21614         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21615         createmany -o $DIR/$tdir/$tfile. 1000
21616
21617         # statfs data is not real time, let's just calculate it
21618         old_iused=$((old_iused + 1000))
21619
21620         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21621                         osp.*OST0000*MDT0000.create_count")
21622         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21623                                 osp.*OST0000*MDT0000.max_create_count")
21624         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21625
21626         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21627         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21628         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21629
21630         unlinkmany $DIR/$tdir/$tfile. 1000
21631
21632         do_nodes $mdts "$LCTL set_param -n \
21633                         osp.*OST0000*.max_create_count=$max_count"
21634         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21635                 do_nodes $mdts "$LCTL set_param -n \
21636                                 osp.*OST0000*.create_count=$count"
21637         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21638                         grep "=0" && error "create_count is zero"
21639
21640         local new_iused
21641         for i in $(seq 120); do
21642                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21643                 # system may be too busy to destroy all objs in time, use
21644                 # a somewhat small value to not fail autotest
21645                 [ $((old_iused - new_iused)) -gt 400 ] && break
21646                 sleep 1
21647         done
21648
21649         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21650         [ $((old_iused - new_iused)) -gt 400 ] ||
21651                 error "objs not destroyed after unlink"
21652 }
21653 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21654
21655 zfs_oid_to_objid()
21656 {
21657         local ost=$1
21658         local objid=$2
21659
21660         local vdevdir=$(dirname $(facet_vdevice $ost))
21661         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21662         local zfs_zapid=$(do_facet $ost $cmd |
21663                           grep -w "/O/0/d$((objid%32))" -C 5 |
21664                           awk '/Object/{getline; print $1}')
21665         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21666                           awk "/$objid = /"'{printf $3}')
21667
21668         echo $zfs_objid
21669 }
21670
21671 zfs_object_blksz() {
21672         local ost=$1
21673         local objid=$2
21674
21675         local vdevdir=$(dirname $(facet_vdevice $ost))
21676         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21677         local blksz=$(do_facet $ost $cmd $objid |
21678                       awk '/dblk/{getline; printf $4}')
21679
21680         case "${blksz: -1}" in
21681                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21682                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21683                 *) ;;
21684         esac
21685
21686         echo $blksz
21687 }
21688
21689 test_312() { # LU-4856
21690         remote_ost_nodsh && skip "remote OST with nodsh"
21691         [ "$ost1_FSTYPE" = "zfs" ] ||
21692                 skip_env "the test only applies to zfs"
21693
21694         local max_blksz=$(do_facet ost1 \
21695                           $ZFS get -p recordsize $(facet_device ost1) |
21696                           awk '!/VALUE/{print $3}')
21697
21698         # to make life a little bit easier
21699         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21700         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21701
21702         local tf=$DIR/$tdir/$tfile
21703         touch $tf
21704         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21705
21706         # Get ZFS object id
21707         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21708         # block size change by sequential overwrite
21709         local bs
21710
21711         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21712                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21713
21714                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21715                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21716         done
21717         rm -f $tf
21718
21719         # block size change by sequential append write
21720         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21721         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21722         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21723         local count
21724
21725         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21726                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21727                         oflag=sync conv=notrunc
21728
21729                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21730                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21731                         error "blksz error, actual $blksz, " \
21732                                 "expected: 2 * $count * $PAGE_SIZE"
21733         done
21734         rm -f $tf
21735
21736         # random write
21737         touch $tf
21738         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21739         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21740
21741         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21742         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21743         [ $blksz -eq $PAGE_SIZE ] ||
21744                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21745
21746         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21747         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21748         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21749
21750         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21751         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21752         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21753 }
21754 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21755
21756 test_313() {
21757         remote_ost_nodsh && skip "remote OST with nodsh"
21758
21759         local file=$DIR/$tfile
21760
21761         rm -f $file
21762         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21763
21764         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21765         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21766         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21767                 error "write should failed"
21768         do_facet ost1 "$LCTL set_param fail_loc=0"
21769         rm -f $file
21770 }
21771 run_test 313 "io should fail after last_rcvd update fail"
21772
21773 test_314() {
21774         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21775
21776         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21777         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21778         rm -f $DIR/$tfile
21779         wait_delete_completed
21780         do_facet ost1 "$LCTL set_param fail_loc=0"
21781 }
21782 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21783
21784 test_315() { # LU-618
21785         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21786
21787         local file=$DIR/$tfile
21788         rm -f $file
21789
21790         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21791                 error "multiop file write failed"
21792         $MULTIOP $file oO_RDONLY:r4063232_c &
21793         PID=$!
21794
21795         sleep 2
21796
21797         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21798         kill -USR1 $PID
21799
21800         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21801         rm -f $file
21802 }
21803 run_test 315 "read should be accounted"
21804
21805 test_316() {
21806         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21807         large_xattr_enabled || skip_env "ea_inode feature disabled"
21808
21809         rm -rf $DIR/$tdir/d
21810         mkdir -p $DIR/$tdir/d
21811         chown nobody $DIR/$tdir/d
21812         touch $DIR/$tdir/d/file
21813
21814         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21815 }
21816 run_test 316 "lfs mv"
21817
21818 test_317() {
21819         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21820                 skip "Need MDS version at least 2.11.53"
21821         if [ "$ost1_FSTYPE" == "zfs" ]; then
21822                 skip "LU-10370: no implementation for ZFS"
21823         fi
21824
21825         local trunc_sz
21826         local grant_blk_size
21827
21828         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21829                         awk '/grant_block_size:/ { print $2; exit; }')
21830         #
21831         # Create File of size 5M. Truncate it to below size's and verify
21832         # blocks count.
21833         #
21834         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21835                 error "Create file $DIR/$tfile failed"
21836         stack_trap "rm -f $DIR/$tfile" EXIT
21837
21838         for trunc_sz in 2097152 4097 4000 509 0; do
21839                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21840                         error "truncate $tfile to $trunc_sz failed"
21841                 local sz=$(stat --format=%s $DIR/$tfile)
21842                 local blk=$(stat --format=%b $DIR/$tfile)
21843                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21844                                      grant_blk_size) * 8))
21845
21846                 if [[ $blk -ne $trunc_blk ]]; then
21847                         $(which stat) $DIR/$tfile
21848                         error "Expected Block $trunc_blk got $blk for $tfile"
21849                 fi
21850
21851                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21852                         error "Expected Size $trunc_sz got $sz for $tfile"
21853         done
21854
21855         #
21856         # sparse file test
21857         # Create file with a hole and write actual two blocks. Block count
21858         # must be 16.
21859         #
21860         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21861                 conv=fsync || error "Create file : $DIR/$tfile"
21862
21863         # Calculate the final truncate size.
21864         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21865
21866         #
21867         # truncate to size $trunc_sz bytes. Strip the last block
21868         # The block count must drop to 8
21869         #
21870         $TRUNCATE $DIR/$tfile $trunc_sz ||
21871                 error "truncate $tfile to $trunc_sz failed"
21872
21873         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21874         sz=$(stat --format=%s $DIR/$tfile)
21875         blk=$(stat --format=%b $DIR/$tfile)
21876
21877         if [[ $blk -ne $trunc_bsz ]]; then
21878                 $(which stat) $DIR/$tfile
21879                 error "Expected Block $trunc_bsz got $blk for $tfile"
21880         fi
21881
21882         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21883                 error "Expected Size $trunc_sz got $sz for $tfile"
21884 }
21885 run_test 317 "Verify blocks get correctly update after truncate"
21886
21887 test_318() {
21888         local old_max_active=$($LCTL get_param -n \
21889                             llite.*.max_read_ahead_async_active 2>/dev/null)
21890
21891         $LCTL set_param llite.*.max_read_ahead_async_active=256
21892         local max_active=$($LCTL get_param -n \
21893                            llite.*.max_read_ahead_async_active 2>/dev/null)
21894         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21895
21896         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21897                 error "set max_read_ahead_async_active should succeed"
21898
21899         $LCTL set_param llite.*.max_read_ahead_async_active=512
21900         max_active=$($LCTL get_param -n \
21901                      llite.*.max_read_ahead_async_active 2>/dev/null)
21902         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21903
21904         # restore @max_active
21905         [ $old_max_active -ne 0 ] && $LCTL set_param \
21906                 llite.*.max_read_ahead_async_active=$old_max_active
21907
21908         local old_threshold=$($LCTL get_param -n \
21909                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21910         local max_per_file_mb=$($LCTL get_param -n \
21911                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21912
21913         local invalid=$(($max_per_file_mb + 1))
21914         $LCTL set_param \
21915                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21916                         && error "set $invalid should fail"
21917
21918         local valid=$(($invalid - 1))
21919         $LCTL set_param \
21920                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21921                         error "set $valid should succeed"
21922         local threshold=$($LCTL get_param -n \
21923                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21924         [ $threshold -eq $valid ] || error \
21925                 "expect threshold $valid got $threshold"
21926         $LCTL set_param \
21927                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21928 }
21929 run_test 318 "Verify async readahead tunables"
21930
21931 test_319() {
21932         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21933
21934         local before=$(date +%s)
21935         local evict
21936         local mdir=$DIR/$tdir
21937         local file=$mdir/xxx
21938
21939         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21940         touch $file
21941
21942 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21943         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21944         $LFS mv -m1 $file &
21945
21946         sleep 1
21947         dd if=$file of=/dev/null
21948         wait
21949         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21950           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21951
21952         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21953 }
21954 run_test 319 "lost lease lock on migrate error"
21955
21956 test_398a() { # LU-4198
21957         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21958         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21959
21960         # request a new lock on client
21961         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21962
21963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21964         local lock_count=$($LCTL get_param -n \
21965                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21966         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21967
21968         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21969
21970         # no lock cached, should use lockless IO and not enqueue new lock
21971         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21972         lock_count=$($LCTL get_param -n \
21973                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21974         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21975 }
21976 run_test 398a "direct IO should cancel lock otherwise lockless"
21977
21978 test_398b() { # LU-4198
21979         which fio || skip_env "no fio installed"
21980         $LFS setstripe -c -1 $DIR/$tfile
21981
21982         local size=12
21983         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21984
21985         local njobs=4
21986         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21987         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21988                 --numjobs=$njobs --fallocate=none \
21989                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21990                 --filename=$DIR/$tfile &
21991         bg_pid=$!
21992
21993         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21994         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21995                 --numjobs=$njobs --fallocate=none \
21996                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21997                 --filename=$DIR/$tfile || true
21998         wait $bg_pid
21999
22000         rm -rf $DIR/$tfile
22001 }
22002 run_test 398b "DIO and buffer IO race"
22003
22004 test_398c() { # LU-4198
22005         which fio || skip_env "no fio installed"
22006
22007         saved_debug=$($LCTL get_param -n debug)
22008         $LCTL set_param debug=0
22009
22010         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22011         ((size /= 1024)) # by megabytes
22012         ((size /= 2)) # write half of the OST at most
22013         [ $size -gt 40 ] && size=40 #reduce test time anyway
22014
22015         $LFS setstripe -c 1 $DIR/$tfile
22016
22017         # it seems like ldiskfs reserves more space than necessary if the
22018         # writing blocks are not mapped, so it extends the file firstly
22019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22020         cancel_lru_locks osc
22021
22022         # clear and verify rpc_stats later
22023         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22024
22025         local njobs=4
22026         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22027         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22028                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22029                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22030                 --filename=$DIR/$tfile
22031         [ $? -eq 0 ] || error "fio write error"
22032
22033         [ $($LCTL get_param -n \
22034          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22035                 error "Locks were requested while doing AIO"
22036
22037         # get the percentage of 1-page I/O
22038         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22039                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22040                 awk '{print $7}')
22041         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22042
22043         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22044         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22045                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22046                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22047                 --filename=$DIR/$tfile
22048         [ $? -eq 0 ] || error "fio mixed read write error"
22049
22050         echo "AIO with large block size ${size}M"
22051         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22052                 --numjobs=1 --fallocate=none --ioengine=libaio \
22053                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22054                 --filename=$DIR/$tfile
22055         [ $? -eq 0 ] || error "fio large block size failed"
22056
22057         rm -rf $DIR/$tfile
22058         $LCTL set_param debug="$saved_debug"
22059 }
22060 run_test 398c "run fio to test AIO"
22061
22062 test_398d() { #  LU-13846
22063         test -f aiocp || skip_env "no aiocp installed"
22064         local aio_file=$DIR/aio_file
22065
22066         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22067
22068         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22069         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22070
22071         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22072
22073         # make sure we don't crash and fail properly
22074         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22075                 error "aio not aligned with PAGE SIZE should fail"
22076
22077         rm -rf $DIR/$tfile $aio_file
22078 }
22079 run_test 398d "run aiocp to verify block size > stripe size"
22080
22081 test_fake_rw() {
22082         local read_write=$1
22083         if [ "$read_write" = "write" ]; then
22084                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22085         elif [ "$read_write" = "read" ]; then
22086                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22087         else
22088                 error "argument error"
22089         fi
22090
22091         # turn off debug for performance testing
22092         local saved_debug=$($LCTL get_param -n debug)
22093         $LCTL set_param debug=0
22094
22095         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22096
22097         # get ost1 size - $FSNAME-OST0000
22098         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22099         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22100         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22101
22102         if [ "$read_write" = "read" ]; then
22103                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22104         fi
22105
22106         local start_time=$(date +%s.%N)
22107         $dd_cmd bs=1M count=$blocks oflag=sync ||
22108                 error "real dd $read_write error"
22109         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22110
22111         if [ "$read_write" = "write" ]; then
22112                 rm -f $DIR/$tfile
22113         fi
22114
22115         # define OBD_FAIL_OST_FAKE_RW           0x238
22116         do_facet ost1 $LCTL set_param fail_loc=0x238
22117
22118         local start_time=$(date +%s.%N)
22119         $dd_cmd bs=1M count=$blocks oflag=sync ||
22120                 error "fake dd $read_write error"
22121         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22122
22123         if [ "$read_write" = "write" ]; then
22124                 # verify file size
22125                 cancel_lru_locks osc
22126                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22127                         error "$tfile size not $blocks MB"
22128         fi
22129         do_facet ost1 $LCTL set_param fail_loc=0
22130
22131         echo "fake $read_write $duration_fake vs. normal $read_write" \
22132                 "$duration in seconds"
22133         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22134                 error_not_in_vm "fake write is slower"
22135
22136         $LCTL set_param -n debug="$saved_debug"
22137         rm -f $DIR/$tfile
22138 }
22139 test_399a() { # LU-7655 for OST fake write
22140         remote_ost_nodsh && skip "remote OST with nodsh"
22141
22142         test_fake_rw write
22143 }
22144 run_test 399a "fake write should not be slower than normal write"
22145
22146 test_399b() { # LU-8726 for OST fake read
22147         remote_ost_nodsh && skip "remote OST with nodsh"
22148         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22149                 skip_env "ldiskfs only test"
22150         fi
22151
22152         test_fake_rw read
22153 }
22154 run_test 399b "fake read should not be slower than normal read"
22155
22156 test_400a() { # LU-1606, was conf-sanity test_74
22157         if ! which $CC > /dev/null 2>&1; then
22158                 skip_env "$CC is not installed"
22159         fi
22160
22161         local extra_flags=''
22162         local out=$TMP/$tfile
22163         local prefix=/usr/include/lustre
22164         local prog
22165
22166         # Oleg removes c files in his test rig so test if any c files exist
22167         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22168                 skip_env "Needed c test files are missing"
22169
22170         if ! [[ -d $prefix ]]; then
22171                 # Assume we're running in tree and fixup the include path.
22172                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22173                 extra_flags+=" -L$LUSTRE/utils/.lib"
22174         fi
22175
22176         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22177                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22178                         error "client api broken"
22179         done
22180         rm -f $out
22181 }
22182 run_test 400a "Lustre client api program can compile and link"
22183
22184 test_400b() { # LU-1606, LU-5011
22185         local header
22186         local out=$TMP/$tfile
22187         local prefix=/usr/include/linux/lustre
22188
22189         # We use a hard coded prefix so that this test will not fail
22190         # when run in tree. There are headers in lustre/include/lustre/
22191         # that are not packaged (like lustre_idl.h) and have more
22192         # complicated include dependencies (like config.h and lnet/types.h).
22193         # Since this test about correct packaging we just skip them when
22194         # they don't exist (see below) rather than try to fixup cppflags.
22195
22196         if ! which $CC > /dev/null 2>&1; then
22197                 skip_env "$CC is not installed"
22198         fi
22199
22200         for header in $prefix/*.h; do
22201                 if ! [[ -f "$header" ]]; then
22202                         continue
22203                 fi
22204
22205                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22206                         continue # lustre_ioctl.h is internal header
22207                 fi
22208
22209                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22210                         error "cannot compile '$header'"
22211         done
22212         rm -f $out
22213 }
22214 run_test 400b "packaged headers can be compiled"
22215
22216 test_401a() { #LU-7437
22217         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22218         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22219
22220         #count the number of parameters by "list_param -R"
22221         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22222         #count the number of parameters by listing proc files
22223         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22224         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22225         echo "proc_dirs='$proc_dirs'"
22226         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22227         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22228                       sort -u | wc -l)
22229
22230         [ $params -eq $procs ] ||
22231                 error "found $params parameters vs. $procs proc files"
22232
22233         # test the list_param -D option only returns directories
22234         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22235         #count the number of parameters by listing proc directories
22236         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22237                 sort -u | wc -l)
22238
22239         [ $params -eq $procs ] ||
22240                 error "found $params parameters vs. $procs proc files"
22241 }
22242 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22243
22244 test_401b() {
22245         # jobid_var may not allow arbitrary values, so use jobid_name
22246         # if available
22247         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22248                 local testname=jobid_name tmp='testing%p'
22249         else
22250                 local testname=jobid_var tmp=testing
22251         fi
22252
22253         local save=$($LCTL get_param -n $testname)
22254
22255         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22256                 error "no error returned when setting bad parameters"
22257
22258         local jobid_new=$($LCTL get_param -n foe $testname baz)
22259         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22260
22261         $LCTL set_param -n fog=bam $testname=$save bat=fog
22262         local jobid_old=$($LCTL get_param -n foe $testname bag)
22263         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22264 }
22265 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22266
22267 test_401c() {
22268         # jobid_var may not allow arbitrary values, so use jobid_name
22269         # if available
22270         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22271                 local testname=jobid_name
22272         else
22273                 local testname=jobid_var
22274         fi
22275
22276         local jobid_var_old=$($LCTL get_param -n $testname)
22277         local jobid_var_new
22278
22279         $LCTL set_param $testname= &&
22280                 error "no error returned for 'set_param a='"
22281
22282         jobid_var_new=$($LCTL get_param -n $testname)
22283         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22284                 error "$testname was changed by setting without value"
22285
22286         $LCTL set_param $testname &&
22287                 error "no error returned for 'set_param a'"
22288
22289         jobid_var_new=$($LCTL get_param -n $testname)
22290         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22291                 error "$testname was changed by setting without value"
22292 }
22293 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22294
22295 test_401d() {
22296         # jobid_var may not allow arbitrary values, so use jobid_name
22297         # if available
22298         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22299                 local testname=jobid_name new_value='foo=bar%p'
22300         else
22301                 local testname=jobid_var new_valuie=foo=bar
22302         fi
22303
22304         local jobid_var_old=$($LCTL get_param -n $testname)
22305         local jobid_var_new
22306
22307         $LCTL set_param $testname=$new_value ||
22308                 error "'set_param a=b' did not accept a value containing '='"
22309
22310         jobid_var_new=$($LCTL get_param -n $testname)
22311         [[ "$jobid_var_new" == "$new_value" ]] ||
22312                 error "'set_param a=b' failed on a value containing '='"
22313
22314         # Reset the $testname to test the other format
22315         $LCTL set_param $testname=$jobid_var_old
22316         jobid_var_new=$($LCTL get_param -n $testname)
22317         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22318                 error "failed to reset $testname"
22319
22320         $LCTL set_param $testname $new_value ||
22321                 error "'set_param a b' did not accept a value containing '='"
22322
22323         jobid_var_new=$($LCTL get_param -n $testname)
22324         [[ "$jobid_var_new" == "$new_value" ]] ||
22325                 error "'set_param a b' failed on a value containing '='"
22326
22327         $LCTL set_param $testname $jobid_var_old
22328         jobid_var_new=$($LCTL get_param -n $testname)
22329         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22330                 error "failed to reset $testname"
22331 }
22332 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22333
22334 test_402() {
22335         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22336         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22337                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22338         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22339                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22340                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22341         remote_mds_nodsh && skip "remote MDS with nodsh"
22342
22343         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22344 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22345         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22346         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22347                 echo "Touch failed - OK"
22348 }
22349 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22350
22351 test_403() {
22352         local file1=$DIR/$tfile.1
22353         local file2=$DIR/$tfile.2
22354         local tfile=$TMP/$tfile
22355
22356         rm -f $file1 $file2 $tfile
22357
22358         touch $file1
22359         ln $file1 $file2
22360
22361         # 30 sec OBD_TIMEOUT in ll_getattr()
22362         # right before populating st_nlink
22363         $LCTL set_param fail_loc=0x80001409
22364         stat -c %h $file1 > $tfile &
22365
22366         # create an alias, drop all locks and reclaim the dentry
22367         < $file2
22368         cancel_lru_locks mdc
22369         cancel_lru_locks osc
22370         sysctl -w vm.drop_caches=2
22371
22372         wait
22373
22374         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22375
22376         rm -f $tfile $file1 $file2
22377 }
22378 run_test 403 "i_nlink should not drop to zero due to aliasing"
22379
22380 test_404() { # LU-6601
22381         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22382                 skip "Need server version newer than 2.8.52"
22383         remote_mds_nodsh && skip "remote MDS with nodsh"
22384
22385         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22386                 awk '/osp .*-osc-MDT/ { print $4}')
22387
22388         local osp
22389         for osp in $mosps; do
22390                 echo "Deactivate: " $osp
22391                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22392                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22393                         awk -vp=$osp '$4 == p { print $2 }')
22394                 [ $stat = IN ] || {
22395                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22396                         error "deactivate error"
22397                 }
22398                 echo "Activate: " $osp
22399                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22400                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22401                         awk -vp=$osp '$4 == p { print $2 }')
22402                 [ $stat = UP ] || {
22403                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22404                         error "activate error"
22405                 }
22406         done
22407 }
22408 run_test 404 "validate manual {de}activated works properly for OSPs"
22409
22410 test_405() {
22411         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22412         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22413                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22414                         skip "Layout swap lock is not supported"
22415
22416         check_swap_layouts_support
22417         check_swap_layout_no_dom $DIR
22418
22419         test_mkdir $DIR/$tdir
22420         swap_lock_test -d $DIR/$tdir ||
22421                 error "One layout swap locked test failed"
22422 }
22423 run_test 405 "Various layout swap lock tests"
22424
22425 test_406() {
22426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22427         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22428         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22430         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22431                 skip "Need MDS version at least 2.8.50"
22432
22433         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22434         local test_pool=$TESTNAME
22435
22436         pool_add $test_pool || error "pool_add failed"
22437         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22438                 error "pool_add_targets failed"
22439
22440         save_layout_restore_at_exit $MOUNT
22441
22442         # parent set default stripe count only, child will stripe from both
22443         # parent and fs default
22444         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22445                 error "setstripe $MOUNT failed"
22446         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22447         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22448         for i in $(seq 10); do
22449                 local f=$DIR/$tdir/$tfile.$i
22450                 touch $f || error "touch failed"
22451                 local count=$($LFS getstripe -c $f)
22452                 [ $count -eq $OSTCOUNT ] ||
22453                         error "$f stripe count $count != $OSTCOUNT"
22454                 local offset=$($LFS getstripe -i $f)
22455                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22456                 local size=$($LFS getstripe -S $f)
22457                 [ $size -eq $((def_stripe_size * 2)) ] ||
22458                         error "$f stripe size $size != $((def_stripe_size * 2))"
22459                 local pool=$($LFS getstripe -p $f)
22460                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22461         done
22462
22463         # change fs default striping, delete parent default striping, now child
22464         # will stripe from new fs default striping only
22465         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22466                 error "change $MOUNT default stripe failed"
22467         $LFS setstripe -c 0 $DIR/$tdir ||
22468                 error "delete $tdir default stripe failed"
22469         for i in $(seq 11 20); do
22470                 local f=$DIR/$tdir/$tfile.$i
22471                 touch $f || error "touch $f failed"
22472                 local count=$($LFS getstripe -c $f)
22473                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22474                 local offset=$($LFS getstripe -i $f)
22475                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22476                 local size=$($LFS getstripe -S $f)
22477                 [ $size -eq $def_stripe_size ] ||
22478                         error "$f stripe size $size != $def_stripe_size"
22479                 local pool=$($LFS getstripe -p $f)
22480                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22481         done
22482
22483         unlinkmany $DIR/$tdir/$tfile. 1 20
22484
22485         local f=$DIR/$tdir/$tfile
22486         pool_remove_all_targets $test_pool $f
22487         pool_remove $test_pool $f
22488 }
22489 run_test 406 "DNE support fs default striping"
22490
22491 test_407() {
22492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22493         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22494                 skip "Need MDS version at least 2.8.55"
22495         remote_mds_nodsh && skip "remote MDS with nodsh"
22496
22497         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22498                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22499         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22500                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22501         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22502
22503         #define OBD_FAIL_DT_TXN_STOP    0x2019
22504         for idx in $(seq $MDSCOUNT); do
22505                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22506         done
22507         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22508         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22509                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22510         true
22511 }
22512 run_test 407 "transaction fail should cause operation fail"
22513
22514 test_408() {
22515         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22516
22517         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22518         lctl set_param fail_loc=0x8000040a
22519         # let ll_prepare_partial_page() fail
22520         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22521
22522         rm -f $DIR/$tfile
22523
22524         # create at least 100 unused inodes so that
22525         # shrink_icache_memory(0) should not return 0
22526         touch $DIR/$tfile-{0..100}
22527         rm -f $DIR/$tfile-{0..100}
22528         sync
22529
22530         echo 2 > /proc/sys/vm/drop_caches
22531 }
22532 run_test 408 "drop_caches should not hang due to page leaks"
22533
22534 test_409()
22535 {
22536         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22537
22538         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22539         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22540         touch $DIR/$tdir/guard || error "(2) Fail to create"
22541
22542         local PREFIX=$(str_repeat 'A' 128)
22543         echo "Create 1K hard links start at $(date)"
22544         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22545                 error "(3) Fail to hard link"
22546
22547         echo "Links count should be right although linkEA overflow"
22548         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22549         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22550         [ $linkcount -eq 1001 ] ||
22551                 error "(5) Unexpected hard links count: $linkcount"
22552
22553         echo "List all links start at $(date)"
22554         ls -l $DIR/$tdir/foo > /dev/null ||
22555                 error "(6) Fail to list $DIR/$tdir/foo"
22556
22557         echo "Unlink hard links start at $(date)"
22558         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22559                 error "(7) Fail to unlink"
22560         echo "Unlink hard links finished at $(date)"
22561 }
22562 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22563
22564 test_410()
22565 {
22566         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22567                 skip "Need client version at least 2.9.59"
22568         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22569                 skip "Need MODULES build"
22570
22571         # Create a file, and stat it from the kernel
22572         local testfile=$DIR/$tfile
22573         touch $testfile
22574
22575         local run_id=$RANDOM
22576         local my_ino=$(stat --format "%i" $testfile)
22577
22578         # Try to insert the module. This will always fail as the
22579         # module is designed to not be inserted.
22580         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22581             &> /dev/null
22582
22583         # Anything but success is a test failure
22584         dmesg | grep -q \
22585             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22586             error "no inode match"
22587 }
22588 run_test 410 "Test inode number returned from kernel thread"
22589
22590 cleanup_test411_cgroup() {
22591         trap 0
22592         rmdir "$1"
22593 }
22594
22595 test_411() {
22596         local cg_basedir=/sys/fs/cgroup/memory
22597         # LU-9966
22598         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22599                 skip "no setup for cgroup"
22600
22601         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22602                 error "test file creation failed"
22603         cancel_lru_locks osc
22604
22605         # Create a very small memory cgroup to force a slab allocation error
22606         local cgdir=$cg_basedir/osc_slab_alloc
22607         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22608         trap "cleanup_test411_cgroup $cgdir" EXIT
22609         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22610         echo 1M > $cgdir/memory.limit_in_bytes
22611
22612         # Should not LBUG, just be killed by oom-killer
22613         # dd will return 0 even allocation failure in some environment.
22614         # So don't check return value
22615         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22616         cleanup_test411_cgroup $cgdir
22617
22618         return 0
22619 }
22620 run_test 411 "Slab allocation error with cgroup does not LBUG"
22621
22622 test_412() {
22623         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22624         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22625                 skip "Need server version at least 2.10.55"
22626         fi
22627
22628         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22629                 error "mkdir failed"
22630         $LFS getdirstripe $DIR/$tdir
22631         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22632         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22633                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22634         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22635         [ $stripe_count -eq 2 ] ||
22636                 error "expect 2 get $stripe_count"
22637 }
22638 run_test 412 "mkdir on specific MDTs"
22639
22640 test_qos_mkdir() {
22641         local mkdir_cmd=$1
22642         local stripe_count=$2
22643         local mdts=$(comma_list $(mdts_nodes))
22644
22645         local testdir
22646         local lmv_qos_prio_free
22647         local lmv_qos_threshold_rr
22648         local lmv_qos_maxage
22649         local lod_qos_prio_free
22650         local lod_qos_threshold_rr
22651         local lod_qos_maxage
22652         local count
22653         local i
22654
22655         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22656         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22657         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22658                 head -n1)
22659         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22660         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22661         stack_trap "$LCTL set_param \
22662                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22663         stack_trap "$LCTL set_param \
22664                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22665         stack_trap "$LCTL set_param \
22666                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22667
22668         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22669                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22670         lod_qos_prio_free=${lod_qos_prio_free%%%}
22671         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22672                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22673         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22674         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22675                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22676         stack_trap "do_nodes $mdts $LCTL set_param \
22677                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22678         stack_trap "do_nodes $mdts $LCTL set_param \
22679                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22680                 EXIT
22681         stack_trap "do_nodes $mdts $LCTL set_param \
22682                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22683
22684         echo
22685         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22686
22687         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22688         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22689
22690         testdir=$DIR/$tdir-s$stripe_count/rr
22691
22692         for i in $(seq $((100 * MDSCOUNT))); do
22693                 eval $mkdir_cmd $testdir/subdir$i ||
22694                         error "$mkdir_cmd subdir$i failed"
22695         done
22696
22697         for i in $(seq $MDSCOUNT); do
22698                 count=$($LFS getdirstripe -i $testdir/* |
22699                                 grep ^$((i - 1))$ | wc -l)
22700                 echo "$count directories created on MDT$((i - 1))"
22701                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22702
22703                 if [ $stripe_count -gt 1 ]; then
22704                         count=$($LFS getdirstripe $testdir/* |
22705                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22706                         echo "$count stripes created on MDT$((i - 1))"
22707                         # deviation should < 5% of average
22708                         [ $count -lt $((95 * stripe_count)) ] ||
22709                         [ $count -gt $((105 * stripe_count)) ] &&
22710                                 error "stripes are not evenly distributed"
22711                 fi
22712         done
22713
22714         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22715         do_nodes $mdts $LCTL set_param \
22716                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22717
22718         echo
22719         echo "Check for uneven MDTs: "
22720
22721         local ffree
22722         local bavail
22723         local max
22724         local min
22725         local max_index
22726         local min_index
22727         local tmp
22728
22729         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22730         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22731         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22732
22733         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22734         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22735         max_index=0
22736         min_index=0
22737         for ((i = 1; i < ${#ffree[@]}; i++)); do
22738                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22739                 if [ $tmp -gt $max ]; then
22740                         max=$tmp
22741                         max_index=$i
22742                 fi
22743                 if [ $tmp -lt $min ]; then
22744                         min=$tmp
22745                         min_index=$i
22746                 fi
22747         done
22748
22749         [ ${ffree[min_index]} -eq 0 ] &&
22750                 skip "no free files in MDT$min_index"
22751         [ ${ffree[min_index]} -gt 100000000 ] &&
22752                 skip "too much free files in MDT$min_index"
22753
22754         # Check if we need to generate uneven MDTs
22755         local threshold=50
22756         local diff=$(((max - min) * 100 / min))
22757         local value="$(generate_string 1024)"
22758
22759         while [ $diff -lt $threshold ]; do
22760                 # generate uneven MDTs, create till $threshold% diff
22761                 echo -n "weight diff=$diff% must be > $threshold% ..."
22762                 count=$((${ffree[min_index]} / 10))
22763                 # 50 sec per 10000 files in vm
22764                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22765                         skip "$count files to create"
22766                 echo "Fill MDT$min_index with $count files"
22767                 [ -d $DIR/$tdir-MDT$min_index ] ||
22768                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22769                         error "mkdir $tdir-MDT$min_index failed"
22770                 for i in $(seq $count); do
22771                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22772                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22773                                 error "create f$j_$i failed"
22774                         setfattr -n user.413b -v $value \
22775                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22776                                 error "setfattr f$j_$i failed"
22777                 done
22778
22779                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22780                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22781                 max=$(((${ffree[max_index]} >> 8) * \
22782                         (${bavail[max_index]} * bsize >> 16)))
22783                 min=$(((${ffree[min_index]} >> 8) * \
22784                         (${bavail[min_index]} * bsize >> 16)))
22785                 diff=$(((max - min) * 100 / min))
22786         done
22787
22788         echo "MDT filesfree available: ${ffree[@]}"
22789         echo "MDT blocks available: ${bavail[@]}"
22790         echo "weight diff=$diff%"
22791
22792         echo
22793         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22794
22795         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22796         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22797         # decrease statfs age, so that it can be updated in time
22798         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22799         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22800
22801         sleep 1
22802
22803         testdir=$DIR/$tdir-s$stripe_count/qos
22804
22805         for i in $(seq $((100 * MDSCOUNT))); do
22806                 eval $mkdir_cmd $testdir/subdir$i ||
22807                         error "$mkdir_cmd subdir$i failed"
22808         done
22809
22810         for i in $(seq $MDSCOUNT); do
22811                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22812                         wc -l)
22813                 echo "$count directories created on MDT$((i - 1))"
22814
22815                 if [ $stripe_count -gt 1 ]; then
22816                         count=$($LFS getdirstripe $testdir/* |
22817                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22818                         echo "$count stripes created on MDT$((i - 1))"
22819                 fi
22820         done
22821
22822         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22823         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22824
22825         # D-value should > 10% of averge
22826         [ $((max - min)) -lt 10 ] &&
22827                 error "subdirs shouldn't be evenly distributed"
22828
22829         # ditto
22830         if [ $stripe_count -gt 1 ]; then
22831                 max=$($LFS getdirstripe $testdir/* |
22832                         grep -P "^\s+$max_index\t" | wc -l)
22833                 min=$($LFS getdirstripe $testdir/* |
22834                         grep -P "^\s+$min_index\t" | wc -l)
22835                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22836                         error "stripes shouldn't be evenly distributed"|| true
22837         fi
22838 }
22839
22840 test_413a() {
22841         [ $MDSCOUNT -lt 2 ] &&
22842                 skip "We need at least 2 MDTs for this test"
22843
22844         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22845                 skip "Need server version at least 2.12.52"
22846
22847         local stripe_count
22848
22849         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22850                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22851                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22852                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22853                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22854         done
22855 }
22856 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22857
22858 test_413b() {
22859         [ $MDSCOUNT -lt 2 ] &&
22860                 skip "We need at least 2 MDTs for this test"
22861
22862         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22863                 skip "Need server version at least 2.12.52"
22864
22865         local stripe_count
22866
22867         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22868                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22869                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22870                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22871                 $LFS setdirstripe -D -c $stripe_count \
22872                         $DIR/$tdir-s$stripe_count/rr ||
22873                         error "setdirstripe failed"
22874                 $LFS setdirstripe -D -c $stripe_count \
22875                         $DIR/$tdir-s$stripe_count/qos ||
22876                         error "setdirstripe failed"
22877                 test_qos_mkdir "mkdir" $stripe_count
22878         done
22879 }
22880 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22881
22882 test_414() {
22883 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22884         $LCTL set_param fail_loc=0x80000521
22885         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22886         rm -f $DIR/$tfile
22887 }
22888 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22889
22890 test_415() {
22891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22892         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22893                 skip "Need server version at least 2.11.52"
22894
22895         # LU-11102
22896         local total
22897         local setattr_pid
22898         local start_time
22899         local end_time
22900         local duration
22901
22902         total=500
22903         # this test may be slow on ZFS
22904         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22905
22906         # though this test is designed for striped directory, let's test normal
22907         # directory too since lock is always saved as CoS lock.
22908         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22909         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22910
22911         (
22912                 while true; do
22913                         touch $DIR/$tdir
22914                 done
22915         ) &
22916         setattr_pid=$!
22917
22918         start_time=$(date +%s)
22919         for i in $(seq $total); do
22920                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22921                         > /dev/null
22922         done
22923         end_time=$(date +%s)
22924         duration=$((end_time - start_time))
22925
22926         kill -9 $setattr_pid
22927
22928         echo "rename $total files took $duration sec"
22929         [ $duration -lt 100 ] || error "rename took $duration sec"
22930 }
22931 run_test 415 "lock revoke is not missing"
22932
22933 test_416() {
22934         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22935                 skip "Need server version at least 2.11.55"
22936
22937         # define OBD_FAIL_OSD_TXN_START    0x19a
22938         do_facet mds1 lctl set_param fail_loc=0x19a
22939
22940         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22941
22942         true
22943 }
22944 run_test 416 "transaction start failure won't cause system hung"
22945
22946 cleanup_417() {
22947         trap 0
22948         do_nodes $(comma_list $(mdts_nodes)) \
22949                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22950         do_nodes $(comma_list $(mdts_nodes)) \
22951                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22952         do_nodes $(comma_list $(mdts_nodes)) \
22953                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22954 }
22955
22956 test_417() {
22957         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22958         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22959                 skip "Need MDS version at least 2.11.56"
22960
22961         trap cleanup_417 RETURN EXIT
22962
22963         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22964         do_nodes $(comma_list $(mdts_nodes)) \
22965                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22966         $LFS migrate -m 0 $DIR/$tdir.1 &&
22967                 error "migrate dir $tdir.1 should fail"
22968
22969         do_nodes $(comma_list $(mdts_nodes)) \
22970                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22971         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22972                 error "create remote dir $tdir.2 should fail"
22973
22974         do_nodes $(comma_list $(mdts_nodes)) \
22975                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22976         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22977                 error "create striped dir $tdir.3 should fail"
22978         true
22979 }
22980 run_test 417 "disable remote dir, striped dir and dir migration"
22981
22982 # Checks that the outputs of df [-i] and lfs df [-i] match
22983 #
22984 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22985 check_lfs_df() {
22986         local dir=$2
22987         local inodes
22988         local df_out
22989         local lfs_df_out
22990         local count
22991         local passed=false
22992
22993         # blocks or inodes
22994         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22995
22996         for count in {1..100}; do
22997                 cancel_lru_locks
22998                 sync; sleep 0.2
22999
23000                 # read the lines of interest
23001                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23002                         error "df $inodes $dir | tail -n +2 failed"
23003                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23004                         error "lfs df $inodes $dir | grep summary: failed"
23005
23006                 # skip first substrings of each output as they are different
23007                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23008                 # compare the two outputs
23009                 passed=true
23010                 for i in {1..5}; do
23011                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23012                 done
23013                 $passed && break
23014         done
23015
23016         if ! $passed; then
23017                 df -P $inodes $dir
23018                 echo
23019                 lfs df $inodes $dir
23020                 error "df and lfs df $1 output mismatch: "      \
23021                       "df ${inodes}: ${df_out[*]}, "            \
23022                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23023         fi
23024 }
23025
23026 test_418() {
23027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23028
23029         local dir=$DIR/$tdir
23030         local numfiles=$((RANDOM % 4096 + 2))
23031         local numblocks=$((RANDOM % 256 + 1))
23032
23033         wait_delete_completed
23034         test_mkdir $dir
23035
23036         # check block output
23037         check_lfs_df blocks $dir
23038         # check inode output
23039         check_lfs_df inodes $dir
23040
23041         # create a single file and retest
23042         echo "Creating a single file and testing"
23043         createmany -o $dir/$tfile- 1 &>/dev/null ||
23044                 error "creating 1 file in $dir failed"
23045         check_lfs_df blocks $dir
23046         check_lfs_df inodes $dir
23047
23048         # create a random number of files
23049         echo "Creating $((numfiles - 1)) files and testing"
23050         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23051                 error "creating $((numfiles - 1)) files in $dir failed"
23052
23053         # write a random number of blocks to the first test file
23054         echo "Writing $numblocks 4K blocks and testing"
23055         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23056                 count=$numblocks &>/dev/null ||
23057                 error "dd to $dir/${tfile}-0 failed"
23058
23059         # retest
23060         check_lfs_df blocks $dir
23061         check_lfs_df inodes $dir
23062
23063         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23064                 error "unlinking $numfiles files in $dir failed"
23065 }
23066 run_test 418 "df and lfs df outputs match"
23067
23068 test_419()
23069 {
23070         local dir=$DIR/$tdir
23071
23072         mkdir -p $dir
23073         touch $dir/file
23074
23075         cancel_lru_locks mdc
23076
23077         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23078         $LCTL set_param fail_loc=0x1410
23079         cat $dir/file
23080         $LCTL set_param fail_loc=0
23081         rm -rf $dir
23082 }
23083 run_test 419 "Verify open file by name doesn't crash kernel"
23084
23085 test_420()
23086 {
23087         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23088                 skip "Need MDS version at least 2.12.53"
23089
23090         local SAVE_UMASK=$(umask)
23091         local dir=$DIR/$tdir
23092         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23093
23094         mkdir -p $dir
23095         umask 0000
23096         mkdir -m03777 $dir/testdir
23097         ls -dn $dir/testdir
23098         # Need to remove trailing '.' when SELinux is enabled
23099         local dirperms=$(ls -dn $dir/testdir |
23100                          awk '{ sub(/\.$/, "", $1); print $1}')
23101         [ $dirperms == "drwxrwsrwt" ] ||
23102                 error "incorrect perms on $dir/testdir"
23103
23104         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23105                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23106         ls -n $dir/testdir/testfile
23107         local fileperms=$(ls -n $dir/testdir/testfile |
23108                           awk '{ sub(/\.$/, "", $1); print $1}')
23109         [ $fileperms == "-rwxr-xr-x" ] ||
23110                 error "incorrect perms on $dir/testdir/testfile"
23111
23112         umask $SAVE_UMASK
23113 }
23114 run_test 420 "clear SGID bit on non-directories for non-members"
23115
23116 test_421a() {
23117         local cnt
23118         local fid1
23119         local fid2
23120
23121         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23122                 skip "Need MDS version at least 2.12.54"
23123
23124         test_mkdir $DIR/$tdir
23125         createmany -o $DIR/$tdir/f 3
23126         cnt=$(ls -1 $DIR/$tdir | wc -l)
23127         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23128
23129         fid1=$(lfs path2fid $DIR/$tdir/f1)
23130         fid2=$(lfs path2fid $DIR/$tdir/f2)
23131         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23132
23133         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23134         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23135
23136         cnt=$(ls -1 $DIR/$tdir | wc -l)
23137         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23138
23139         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23140         createmany -o $DIR/$tdir/f 3
23141         cnt=$(ls -1 $DIR/$tdir | wc -l)
23142         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23143
23144         fid1=$(lfs path2fid $DIR/$tdir/f1)
23145         fid2=$(lfs path2fid $DIR/$tdir/f2)
23146         echo "remove using fsname $FSNAME"
23147         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23148
23149         cnt=$(ls -1 $DIR/$tdir | wc -l)
23150         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23151 }
23152 run_test 421a "simple rm by fid"
23153
23154 test_421b() {
23155         local cnt
23156         local FID1
23157         local FID2
23158
23159         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23160                 skip "Need MDS version at least 2.12.54"
23161
23162         test_mkdir $DIR/$tdir
23163         createmany -o $DIR/$tdir/f 3
23164         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23165         MULTIPID=$!
23166
23167         FID1=$(lfs path2fid $DIR/$tdir/f1)
23168         FID2=$(lfs path2fid $DIR/$tdir/f2)
23169         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23170
23171         kill -USR1 $MULTIPID
23172         wait
23173
23174         cnt=$(ls $DIR/$tdir | wc -l)
23175         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23176 }
23177 run_test 421b "rm by fid on open file"
23178
23179 test_421c() {
23180         local cnt
23181         local FIDS
23182
23183         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23184                 skip "Need MDS version at least 2.12.54"
23185
23186         test_mkdir $DIR/$tdir
23187         createmany -o $DIR/$tdir/f 3
23188         touch $DIR/$tdir/$tfile
23189         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23190         cnt=$(ls -1 $DIR/$tdir | wc -l)
23191         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23192
23193         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23194         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23195
23196         cnt=$(ls $DIR/$tdir | wc -l)
23197         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23198 }
23199 run_test 421c "rm by fid against hardlinked files"
23200
23201 test_421d() {
23202         local cnt
23203         local FIDS
23204
23205         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23206                 skip "Need MDS version at least 2.12.54"
23207
23208         test_mkdir $DIR/$tdir
23209         createmany -o $DIR/$tdir/f 4097
23210         cnt=$(ls -1 $DIR/$tdir | wc -l)
23211         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23212
23213         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23214         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23215
23216         cnt=$(ls $DIR/$tdir | wc -l)
23217         rm -rf $DIR/$tdir
23218         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23219 }
23220 run_test 421d "rmfid en masse"
23221
23222 test_421e() {
23223         local cnt
23224         local FID
23225
23226         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23227         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23228                 skip "Need MDS version at least 2.12.54"
23229
23230         mkdir -p $DIR/$tdir
23231         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23232         createmany -o $DIR/$tdir/striped_dir/f 512
23233         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23234         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23235
23236         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23237                 sed "s/[/][^:]*://g")
23238         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23239
23240         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23241         rm -rf $DIR/$tdir
23242         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23243 }
23244 run_test 421e "rmfid in DNE"
23245
23246 test_421f() {
23247         local cnt
23248         local FID
23249
23250         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23251                 skip "Need MDS version at least 2.12.54"
23252
23253         test_mkdir $DIR/$tdir
23254         touch $DIR/$tdir/f
23255         cnt=$(ls -1 $DIR/$tdir | wc -l)
23256         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23257
23258         FID=$(lfs path2fid $DIR/$tdir/f)
23259         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23260         # rmfid should fail
23261         cnt=$(ls -1 $DIR/$tdir | wc -l)
23262         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23263
23264         chmod a+rw $DIR/$tdir
23265         ls -la $DIR/$tdir
23266         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23267         # rmfid should fail
23268         cnt=$(ls -1 $DIR/$tdir | wc -l)
23269         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23270
23271         rm -f $DIR/$tdir/f
23272         $RUNAS touch $DIR/$tdir/f
23273         FID=$(lfs path2fid $DIR/$tdir/f)
23274         echo "rmfid as root"
23275         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23276         cnt=$(ls -1 $DIR/$tdir | wc -l)
23277         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23278
23279         rm -f $DIR/$tdir/f
23280         $RUNAS touch $DIR/$tdir/f
23281         cnt=$(ls -1 $DIR/$tdir | wc -l)
23282         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23283         FID=$(lfs path2fid $DIR/$tdir/f)
23284         # rmfid w/o user_fid2path mount option should fail
23285         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23286         cnt=$(ls -1 $DIR/$tdir | wc -l)
23287         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23288
23289         umount_client $MOUNT || error "failed to umount client"
23290         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23291                 error "failed to mount client'"
23292
23293         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23294         # rmfid should succeed
23295         cnt=$(ls -1 $DIR/$tdir | wc -l)
23296         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23297
23298         # rmfid shouldn't allow to remove files due to dir's permission
23299         chmod a+rwx $DIR/$tdir
23300         touch $DIR/$tdir/f
23301         ls -la $DIR/$tdir
23302         FID=$(lfs path2fid $DIR/$tdir/f)
23303         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23304
23305         umount_client $MOUNT || error "failed to umount client"
23306         mount_client $MOUNT "$MOUNT_OPTS" ||
23307                 error "failed to mount client'"
23308
23309 }
23310 run_test 421f "rmfid checks permissions"
23311
23312 test_421g() {
23313         local cnt
23314         local FIDS
23315
23316         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23317         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23318                 skip "Need MDS version at least 2.12.54"
23319
23320         mkdir -p $DIR/$tdir
23321         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23322         createmany -o $DIR/$tdir/striped_dir/f 512
23323         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23324         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23325
23326         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23327                 sed "s/[/][^:]*://g")
23328
23329         rm -f $DIR/$tdir/striped_dir/f1*
23330         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23331         removed=$((512 - cnt))
23332
23333         # few files have been just removed, so we expect
23334         # rmfid to fail on their fids
23335         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23336         [ $removed != $errors ] && error "$errors != $removed"
23337
23338         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23339         rm -rf $DIR/$tdir
23340         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23341 }
23342 run_test 421g "rmfid to return errors properly"
23343
23344 test_422() {
23345         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23346         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23347         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23348         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23349         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23350
23351         local amc=$(at_max_get client)
23352         local amo=$(at_max_get mds1)
23353         local timeout=`lctl get_param -n timeout`
23354
23355         at_max_set 0 client
23356         at_max_set 0 mds1
23357
23358 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23359         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23360                         fail_val=$(((2*timeout + 10)*1000))
23361         touch $DIR/$tdir/d3/file &
23362         sleep 2
23363 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23364         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23365                         fail_val=$((2*timeout + 5))
23366         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23367         local pid=$!
23368         sleep 1
23369         kill -9 $pid
23370         sleep $((2 * timeout))
23371         echo kill $pid
23372         kill -9 $pid
23373         lctl mark touch
23374         touch $DIR/$tdir/d2/file3
23375         touch $DIR/$tdir/d2/file4
23376         touch $DIR/$tdir/d2/file5
23377
23378         wait
23379         at_max_set $amc client
23380         at_max_set $amo mds1
23381
23382         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23383         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23384                 error "Watchdog is always throttled"
23385 }
23386 run_test 422 "kill a process with RPC in progress"
23387
23388 stat_test() {
23389     df -h $MOUNT &
23390     df -h $MOUNT &
23391     df -h $MOUNT &
23392     df -h $MOUNT &
23393     df -h $MOUNT &
23394     df -h $MOUNT &
23395 }
23396
23397 test_423() {
23398     local _stats
23399     # ensure statfs cache is expired
23400     sleep 2;
23401
23402     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23403     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23404
23405     return 0
23406 }
23407 run_test 423 "statfs should return a right data"
23408
23409 test_424() {
23410 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23411         $LCTL set_param fail_loc=0x80000522
23412         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23413         rm -f $DIR/$tfile
23414 }
23415 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23416
23417 test_425() {
23418         test_mkdir -c -1 $DIR/$tdir
23419         $LFS setstripe -c -1 $DIR/$tdir
23420
23421         lru_resize_disable "" 100
23422         stack_trap "lru_resize_enable" EXIT
23423
23424         sleep 5
23425
23426         for i in $(seq $((MDSCOUNT * 125))); do
23427                 local t=$DIR/$tdir/$tfile_$i
23428
23429                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23430                         error_noexit "Create file $t"
23431         done
23432         stack_trap "rm -rf $DIR/$tdir" EXIT
23433
23434         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23435                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23436                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23437
23438                 [ $lock_count -le $lru_size ] ||
23439                         error "osc lock count $lock_count > lru size $lru_size"
23440         done
23441
23442         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23443                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23444                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23445
23446                 [ $lock_count -le $lru_size ] ||
23447                         error "mdc lock count $lock_count > lru size $lru_size"
23448         done
23449 }
23450 run_test 425 "lock count should not exceed lru size"
23451
23452 prep_801() {
23453         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23454         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23455                 skip "Need server version at least 2.9.55"
23456
23457         start_full_debug_logging
23458 }
23459
23460 post_801() {
23461         stop_full_debug_logging
23462 }
23463
23464 barrier_stat() {
23465         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23466                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23467                            awk '/The barrier for/ { print $7 }')
23468                 echo $st
23469         else
23470                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23471                 echo \'$st\'
23472         fi
23473 }
23474
23475 barrier_expired() {
23476         local expired
23477
23478         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23479                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23480                           awk '/will be expired/ { print $7 }')
23481         else
23482                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23483         fi
23484
23485         echo $expired
23486 }
23487
23488 test_801a() {
23489         prep_801
23490
23491         echo "Start barrier_freeze at: $(date)"
23492         #define OBD_FAIL_BARRIER_DELAY          0x2202
23493         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23494         # Do not reduce barrier time - See LU-11873
23495         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23496
23497         sleep 2
23498         local b_status=$(barrier_stat)
23499         echo "Got barrier status at: $(date)"
23500         [ "$b_status" = "'freezing_p1'" ] ||
23501                 error "(1) unexpected barrier status $b_status"
23502
23503         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23504         wait
23505         b_status=$(barrier_stat)
23506         [ "$b_status" = "'frozen'" ] ||
23507                 error "(2) unexpected barrier status $b_status"
23508
23509         local expired=$(barrier_expired)
23510         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23511         sleep $((expired + 3))
23512
23513         b_status=$(barrier_stat)
23514         [ "$b_status" = "'expired'" ] ||
23515                 error "(3) unexpected barrier status $b_status"
23516
23517         # Do not reduce barrier time - See LU-11873
23518         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23519                 error "(4) fail to freeze barrier"
23520
23521         b_status=$(barrier_stat)
23522         [ "$b_status" = "'frozen'" ] ||
23523                 error "(5) unexpected barrier status $b_status"
23524
23525         echo "Start barrier_thaw at: $(date)"
23526         #define OBD_FAIL_BARRIER_DELAY          0x2202
23527         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23528         do_facet mgs $LCTL barrier_thaw $FSNAME &
23529
23530         sleep 2
23531         b_status=$(barrier_stat)
23532         echo "Got barrier status at: $(date)"
23533         [ "$b_status" = "'thawing'" ] ||
23534                 error "(6) unexpected barrier status $b_status"
23535
23536         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23537         wait
23538         b_status=$(barrier_stat)
23539         [ "$b_status" = "'thawed'" ] ||
23540                 error "(7) unexpected barrier status $b_status"
23541
23542         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23543         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23544         do_facet mgs $LCTL barrier_freeze $FSNAME
23545
23546         b_status=$(barrier_stat)
23547         [ "$b_status" = "'failed'" ] ||
23548                 error "(8) unexpected barrier status $b_status"
23549
23550         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23551         do_facet mgs $LCTL barrier_thaw $FSNAME
23552
23553         post_801
23554 }
23555 run_test 801a "write barrier user interfaces and stat machine"
23556
23557 test_801b() {
23558         prep_801
23559
23560         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23561         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23562         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23563         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23564         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23565
23566         cancel_lru_locks mdc
23567
23568         # 180 seconds should be long enough
23569         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23570
23571         local b_status=$(barrier_stat)
23572         [ "$b_status" = "'frozen'" ] ||
23573                 error "(6) unexpected barrier status $b_status"
23574
23575         mkdir $DIR/$tdir/d0/d10 &
23576         mkdir_pid=$!
23577
23578         touch $DIR/$tdir/d1/f13 &
23579         touch_pid=$!
23580
23581         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23582         ln_pid=$!
23583
23584         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23585         mv_pid=$!
23586
23587         rm -f $DIR/$tdir/d4/f12 &
23588         rm_pid=$!
23589
23590         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23591
23592         # To guarantee taht the 'stat' is not blocked
23593         b_status=$(barrier_stat)
23594         [ "$b_status" = "'frozen'" ] ||
23595                 error "(8) unexpected barrier status $b_status"
23596
23597         # let above commands to run at background
23598         sleep 5
23599
23600         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23601         ps -p $touch_pid || error "(10) touch should be blocked"
23602         ps -p $ln_pid || error "(11) link should be blocked"
23603         ps -p $mv_pid || error "(12) rename should be blocked"
23604         ps -p $rm_pid || error "(13) unlink should be blocked"
23605
23606         b_status=$(barrier_stat)
23607         [ "$b_status" = "'frozen'" ] ||
23608                 error "(14) unexpected barrier status $b_status"
23609
23610         do_facet mgs $LCTL barrier_thaw $FSNAME
23611         b_status=$(barrier_stat)
23612         [ "$b_status" = "'thawed'" ] ||
23613                 error "(15) unexpected barrier status $b_status"
23614
23615         wait $mkdir_pid || error "(16) mkdir should succeed"
23616         wait $touch_pid || error "(17) touch should succeed"
23617         wait $ln_pid || error "(18) link should succeed"
23618         wait $mv_pid || error "(19) rename should succeed"
23619         wait $rm_pid || error "(20) unlink should succeed"
23620
23621         post_801
23622 }
23623 run_test 801b "modification will be blocked by write barrier"
23624
23625 test_801c() {
23626         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23627
23628         prep_801
23629
23630         stop mds2 || error "(1) Fail to stop mds2"
23631
23632         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23633
23634         local b_status=$(barrier_stat)
23635         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23636                 do_facet mgs $LCTL barrier_thaw $FSNAME
23637                 error "(2) unexpected barrier status $b_status"
23638         }
23639
23640         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23641                 error "(3) Fail to rescan barrier bitmap"
23642
23643         # Do not reduce barrier time - See LU-11873
23644         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23645
23646         b_status=$(barrier_stat)
23647         [ "$b_status" = "'frozen'" ] ||
23648                 error "(4) unexpected barrier status $b_status"
23649
23650         do_facet mgs $LCTL barrier_thaw $FSNAME
23651         b_status=$(barrier_stat)
23652         [ "$b_status" = "'thawed'" ] ||
23653                 error "(5) unexpected barrier status $b_status"
23654
23655         local devname=$(mdsdevname 2)
23656
23657         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23658
23659         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23660                 error "(7) Fail to rescan barrier bitmap"
23661
23662         post_801
23663 }
23664 run_test 801c "rescan barrier bitmap"
23665
23666 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23667 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23668 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23669 saved_MOUNT_OPTS=$MOUNT_OPTS
23670
23671 cleanup_802a() {
23672         trap 0
23673
23674         stopall
23675         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23676         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23677         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23678         MOUNT_OPTS=$saved_MOUNT_OPTS
23679         setupall
23680 }
23681
23682 test_802a() {
23683         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23684         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23685         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23686                 skip "Need server version at least 2.9.55"
23687
23688         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23689
23690         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23691
23692         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23693                 error "(2) Fail to copy"
23694
23695         trap cleanup_802a EXIT
23696
23697         # sync by force before remount as readonly
23698         sync; sync_all_data; sleep 3; sync_all_data
23699
23700         stopall
23701
23702         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23703         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23704         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23705
23706         echo "Mount the server as read only"
23707         setupall server_only || error "(3) Fail to start servers"
23708
23709         echo "Mount client without ro should fail"
23710         mount_client $MOUNT &&
23711                 error "(4) Mount client without 'ro' should fail"
23712
23713         echo "Mount client with ro should succeed"
23714         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23715         mount_client $MOUNT ||
23716                 error "(5) Mount client with 'ro' should succeed"
23717
23718         echo "Modify should be refused"
23719         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23720
23721         echo "Read should be allowed"
23722         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23723                 error "(7) Read should succeed under ro mode"
23724
23725         cleanup_802a
23726 }
23727 run_test 802a "simulate readonly device"
23728
23729 test_802b() {
23730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23731         remote_mds_nodsh && skip "remote MDS with nodsh"
23732
23733         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23734                 skip "readonly option not available"
23735
23736         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23737
23738         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23739                 error "(2) Fail to copy"
23740
23741         # write back all cached data before setting MDT to readonly
23742         cancel_lru_locks
23743         sync_all_data
23744
23745         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23746         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23747
23748         echo "Modify should be refused"
23749         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23750
23751         echo "Read should be allowed"
23752         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23753                 error "(7) Read should succeed under ro mode"
23754
23755         # disable readonly
23756         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23757 }
23758 run_test 802b "be able to set MDTs to readonly"
23759
23760 test_803() {
23761         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23762         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23763                 skip "MDS needs to be newer than 2.10.54"
23764
23765         mkdir -p $DIR/$tdir
23766         # Create some objects on all MDTs to trigger related logs objects
23767         for idx in $(seq $MDSCOUNT); do
23768                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23769                         $DIR/$tdir/dir${idx} ||
23770                         error "Fail to create $DIR/$tdir/dir${idx}"
23771         done
23772
23773         sync; sleep 3
23774         wait_delete_completed # ensure old test cleanups are finished
23775         echo "before create:"
23776         $LFS df -i $MOUNT
23777         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23778
23779         for i in {1..10}; do
23780                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23781                         error "Fail to create $DIR/$tdir/foo$i"
23782         done
23783
23784         sync; sleep 3
23785         echo "after create:"
23786         $LFS df -i $MOUNT
23787         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23788
23789         # allow for an llog to be cleaned up during the test
23790         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23791                 error "before ($before_used) + 10 > after ($after_used)"
23792
23793         for i in {1..10}; do
23794                 rm -rf $DIR/$tdir/foo$i ||
23795                         error "Fail to remove $DIR/$tdir/foo$i"
23796         done
23797
23798         sleep 3 # avoid MDT return cached statfs
23799         wait_delete_completed
23800         echo "after unlink:"
23801         $LFS df -i $MOUNT
23802         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23803
23804         # allow for an llog to be created during the test
23805         [ $after_used -le $((before_used + 1)) ] ||
23806                 error "after ($after_used) > before ($before_used) + 1"
23807 }
23808 run_test 803 "verify agent object for remote object"
23809
23810 test_804() {
23811         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23812         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23813                 skip "MDS needs to be newer than 2.10.54"
23814         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23815
23816         mkdir -p $DIR/$tdir
23817         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23818                 error "Fail to create $DIR/$tdir/dir0"
23819
23820         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23821         local dev=$(mdsdevname 2)
23822
23823         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23824                 grep ${fid} || error "NOT found agent entry for dir0"
23825
23826         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23827                 error "Fail to create $DIR/$tdir/dir1"
23828
23829         touch $DIR/$tdir/dir1/foo0 ||
23830                 error "Fail to create $DIR/$tdir/dir1/foo0"
23831         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23832         local rc=0
23833
23834         for idx in $(seq $MDSCOUNT); do
23835                 dev=$(mdsdevname $idx)
23836                 do_facet mds${idx} \
23837                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23838                         grep ${fid} && rc=$idx
23839         done
23840
23841         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23842                 error "Fail to rename foo0 to foo1"
23843         if [ $rc -eq 0 ]; then
23844                 for idx in $(seq $MDSCOUNT); do
23845                         dev=$(mdsdevname $idx)
23846                         do_facet mds${idx} \
23847                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23848                         grep ${fid} && rc=$idx
23849                 done
23850         fi
23851
23852         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23853                 error "Fail to rename foo1 to foo2"
23854         if [ $rc -eq 0 ]; then
23855                 for idx in $(seq $MDSCOUNT); do
23856                         dev=$(mdsdevname $idx)
23857                         do_facet mds${idx} \
23858                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23859                         grep ${fid} && rc=$idx
23860                 done
23861         fi
23862
23863         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23864
23865         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23866                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23867         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23868                 error "Fail to rename foo2 to foo0"
23869         unlink $DIR/$tdir/dir1/foo0 ||
23870                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23871         rm -rf $DIR/$tdir/dir0 ||
23872                 error "Fail to rm $DIR/$tdir/dir0"
23873
23874         for idx in $(seq $MDSCOUNT); do
23875                 dev=$(mdsdevname $idx)
23876                 rc=0
23877
23878                 stop mds${idx}
23879                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23880                         rc=$?
23881                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23882                         error "mount mds$idx failed"
23883                 df $MOUNT > /dev/null 2>&1
23884
23885                 # e2fsck should not return error
23886                 [ $rc -eq 0 ] ||
23887                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23888         done
23889 }
23890 run_test 804 "verify agent entry for remote entry"
23891
23892 cleanup_805() {
23893         do_facet $SINGLEMDS zfs set quota=$old $fsset
23894         unlinkmany $DIR/$tdir/f- 1000000
23895         trap 0
23896 }
23897
23898 test_805() {
23899         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23900         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23901         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23902                 skip "netfree not implemented before 0.7"
23903         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23904                 skip "Need MDS version at least 2.10.57"
23905
23906         local fsset
23907         local freekb
23908         local usedkb
23909         local old
23910         local quota
23911         local pref="osd-zfs.$FSNAME-MDT0000."
23912
23913         # limit available space on MDS dataset to meet nospace issue
23914         # quickly. then ZFS 0.7.2 can use reserved space if asked
23915         # properly (using netfree flag in osd_declare_destroy()
23916         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23917         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23918                 gawk '{print $3}')
23919         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23920         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23921         let "usedkb=usedkb-freekb"
23922         let "freekb=freekb/2"
23923         if let "freekb > 5000"; then
23924                 let "freekb=5000"
23925         fi
23926         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23927         trap cleanup_805 EXIT
23928         mkdir $DIR/$tdir
23929         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23930                 error "Can't set PFL layout"
23931         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23932         rm -rf $DIR/$tdir || error "not able to remove"
23933         do_facet $SINGLEMDS zfs set quota=$old $fsset
23934         trap 0
23935 }
23936 run_test 805 "ZFS can remove from full fs"
23937
23938 # Size-on-MDS test
23939 check_lsom_data()
23940 {
23941         local file=$1
23942         local size=$($LFS getsom -s $file)
23943         local expect=$(stat -c %s $file)
23944
23945         [[ $size == $expect ]] ||
23946                 error "$file expected size: $expect, got: $size"
23947
23948         local blocks=$($LFS getsom -b $file)
23949         expect=$(stat -c %b $file)
23950         [[ $blocks == $expect ]] ||
23951                 error "$file expected blocks: $expect, got: $blocks"
23952 }
23953
23954 check_lsom_size()
23955 {
23956         local size=$($LFS getsom -s $1)
23957         local expect=$2
23958
23959         [[ $size == $expect ]] ||
23960                 error "$file expected size: $expect, got: $size"
23961 }
23962
23963 test_806() {
23964         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23965                 skip "Need MDS version at least 2.11.52"
23966
23967         local bs=1048576
23968
23969         touch $DIR/$tfile || error "touch $tfile failed"
23970
23971         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23972         save_lustre_params client "llite.*.xattr_cache" > $save
23973         lctl set_param llite.*.xattr_cache=0
23974         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23975
23976         # single-threaded write
23977         echo "Test SOM for single-threaded write"
23978         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23979                 error "write $tfile failed"
23980         check_lsom_size $DIR/$tfile $bs
23981
23982         local num=32
23983         local size=$(($num * $bs))
23984         local offset=0
23985         local i
23986
23987         echo "Test SOM for single client multi-threaded($num) write"
23988         $TRUNCATE $DIR/$tfile 0
23989         for ((i = 0; i < $num; i++)); do
23990                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23991                 local pids[$i]=$!
23992                 offset=$((offset + $bs))
23993         done
23994         for (( i=0; i < $num; i++ )); do
23995                 wait ${pids[$i]}
23996         done
23997         check_lsom_size $DIR/$tfile $size
23998
23999         $TRUNCATE $DIR/$tfile 0
24000         for ((i = 0; i < $num; i++)); do
24001                 offset=$((offset - $bs))
24002                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24003                 local pids[$i]=$!
24004         done
24005         for (( i=0; i < $num; i++ )); do
24006                 wait ${pids[$i]}
24007         done
24008         check_lsom_size $DIR/$tfile $size
24009
24010         # multi-client writes
24011         num=$(get_node_count ${CLIENTS//,/ })
24012         size=$(($num * $bs))
24013         offset=0
24014         i=0
24015
24016         echo "Test SOM for multi-client ($num) writes"
24017         $TRUNCATE $DIR/$tfile 0
24018         for client in ${CLIENTS//,/ }; do
24019                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24020                 local pids[$i]=$!
24021                 i=$((i + 1))
24022                 offset=$((offset + $bs))
24023         done
24024         for (( i=0; i < $num; i++ )); do
24025                 wait ${pids[$i]}
24026         done
24027         check_lsom_size $DIR/$tfile $offset
24028
24029         i=0
24030         $TRUNCATE $DIR/$tfile 0
24031         for client in ${CLIENTS//,/ }; do
24032                 offset=$((offset - $bs))
24033                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24034                 local pids[$i]=$!
24035                 i=$((i + 1))
24036         done
24037         for (( i=0; i < $num; i++ )); do
24038                 wait ${pids[$i]}
24039         done
24040         check_lsom_size $DIR/$tfile $size
24041
24042         # verify truncate
24043         echo "Test SOM for truncate"
24044         $TRUNCATE $DIR/$tfile 1048576
24045         check_lsom_size $DIR/$tfile 1048576
24046         $TRUNCATE $DIR/$tfile 1234
24047         check_lsom_size $DIR/$tfile 1234
24048
24049         # verify SOM blocks count
24050         echo "Verify SOM block count"
24051         $TRUNCATE $DIR/$tfile 0
24052         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24053                 error "failed to write file $tfile"
24054         check_lsom_data $DIR/$tfile
24055 }
24056 run_test 806 "Verify Lazy Size on MDS"
24057
24058 test_807() {
24059         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24060         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24061                 skip "Need MDS version at least 2.11.52"
24062
24063         # Registration step
24064         changelog_register || error "changelog_register failed"
24065         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24066         changelog_users $SINGLEMDS | grep -q $cl_user ||
24067                 error "User $cl_user not found in changelog_users"
24068
24069         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24070         save_lustre_params client "llite.*.xattr_cache" > $save
24071         lctl set_param llite.*.xattr_cache=0
24072         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24073
24074         rm -rf $DIR/$tdir || error "rm $tdir failed"
24075         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24076         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24077         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24078         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24079                 error "truncate $tdir/trunc failed"
24080
24081         local bs=1048576
24082         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24083                 error "write $tfile failed"
24084
24085         # multi-client wirtes
24086         local num=$(get_node_count ${CLIENTS//,/ })
24087         local offset=0
24088         local i=0
24089
24090         echo "Test SOM for multi-client ($num) writes"
24091         touch $DIR/$tfile || error "touch $tfile failed"
24092         $TRUNCATE $DIR/$tfile 0
24093         for client in ${CLIENTS//,/ }; do
24094                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24095                 local pids[$i]=$!
24096                 i=$((i + 1))
24097                 offset=$((offset + $bs))
24098         done
24099         for (( i=0; i < $num; i++ )); do
24100                 wait ${pids[$i]}
24101         done
24102
24103         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24104         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24105         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24106         check_lsom_data $DIR/$tdir/trunc
24107         check_lsom_data $DIR/$tdir/single_dd
24108         check_lsom_data $DIR/$tfile
24109
24110         rm -rf $DIR/$tdir
24111         # Deregistration step
24112         changelog_deregister || error "changelog_deregister failed"
24113 }
24114 run_test 807 "verify LSOM syncing tool"
24115
24116 check_som_nologged()
24117 {
24118         local lines=$($LFS changelog $FSNAME-MDT0000 |
24119                 grep 'x=trusted.som' | wc -l)
24120         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24121 }
24122
24123 test_808() {
24124         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24125                 skip "Need MDS version at least 2.11.55"
24126
24127         # Registration step
24128         changelog_register || error "changelog_register failed"
24129
24130         touch $DIR/$tfile || error "touch $tfile failed"
24131         check_som_nologged
24132
24133         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24134                 error "write $tfile failed"
24135         check_som_nologged
24136
24137         $TRUNCATE $DIR/$tfile 1234
24138         check_som_nologged
24139
24140         $TRUNCATE $DIR/$tfile 1048576
24141         check_som_nologged
24142
24143         # Deregistration step
24144         changelog_deregister || error "changelog_deregister failed"
24145 }
24146 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24147
24148 check_som_nodata()
24149 {
24150         $LFS getsom $1
24151         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24152 }
24153
24154 test_809() {
24155         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24156                 skip "Need MDS version at least 2.11.56"
24157
24158         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24159                 error "failed to create DoM-only file $DIR/$tfile"
24160         touch $DIR/$tfile || error "touch $tfile failed"
24161         check_som_nodata $DIR/$tfile
24162
24163         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24164                 error "write $tfile failed"
24165         check_som_nodata $DIR/$tfile
24166
24167         $TRUNCATE $DIR/$tfile 1234
24168         check_som_nodata $DIR/$tfile
24169
24170         $TRUNCATE $DIR/$tfile 4097
24171         check_som_nodata $DIR/$file
24172 }
24173 run_test 809 "Verify no SOM xattr store for DoM-only files"
24174
24175 test_810() {
24176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24177         $GSS && skip_env "could not run with gss"
24178         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24179                 skip "OST < 2.12.58 doesn't align checksum"
24180
24181         set_checksums 1
24182         stack_trap "set_checksums $ORIG_CSUM" EXIT
24183         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24184
24185         local csum
24186         local before
24187         local after
24188         for csum in $CKSUM_TYPES; do
24189                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24190                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24191                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24192                         eval set -- $i
24193                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24194                         before=$(md5sum $DIR/$tfile)
24195                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24196                         after=$(md5sum $DIR/$tfile)
24197                         [ "$before" == "$after" ] ||
24198                                 error "$csum: $before != $after bs=$1 seek=$2"
24199                 done
24200         done
24201 }
24202 run_test 810 "partial page writes on ZFS (LU-11663)"
24203
24204 test_812a() {
24205         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24206                 skip "OST < 2.12.51 doesn't support this fail_loc"
24207         [ "$SHARED_KEY" = true ] &&
24208                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24209
24210         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24211         # ensure ost1 is connected
24212         stat $DIR/$tfile >/dev/null || error "can't stat"
24213         wait_osc_import_state client ost1 FULL
24214         # no locks, no reqs to let the connection idle
24215         cancel_lru_locks osc
24216
24217         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24218 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24219         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24220         wait_osc_import_state client ost1 CONNECTING
24221         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24222
24223         stat $DIR/$tfile >/dev/null || error "can't stat file"
24224 }
24225 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24226
24227 test_812b() { # LU-12378
24228         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24229                 skip "OST < 2.12.51 doesn't support this fail_loc"
24230         [ "$SHARED_KEY" = true ] &&
24231                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24232
24233         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24234         # ensure ost1 is connected
24235         stat $DIR/$tfile >/dev/null || error "can't stat"
24236         wait_osc_import_state client ost1 FULL
24237         # no locks, no reqs to let the connection idle
24238         cancel_lru_locks osc
24239
24240         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24241 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24242         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24243         wait_osc_import_state client ost1 CONNECTING
24244         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24245
24246         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24247         wait_osc_import_state client ost1 IDLE
24248 }
24249 run_test 812b "do not drop no resend request for idle connect"
24250
24251 test_813() {
24252         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24253         [ -z "$file_heat_sav" ] && skip "no file heat support"
24254
24255         local readsample
24256         local writesample
24257         local readbyte
24258         local writebyte
24259         local readsample1
24260         local writesample1
24261         local readbyte1
24262         local writebyte1
24263
24264         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24265         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24266
24267         $LCTL set_param -n llite.*.file_heat=1
24268         echo "Turn on file heat"
24269         echo "Period second: $period_second, Decay percentage: $decay_pct"
24270
24271         echo "QQQQ" > $DIR/$tfile
24272         echo "QQQQ" > $DIR/$tfile
24273         echo "QQQQ" > $DIR/$tfile
24274         cat $DIR/$tfile > /dev/null
24275         cat $DIR/$tfile > /dev/null
24276         cat $DIR/$tfile > /dev/null
24277         cat $DIR/$tfile > /dev/null
24278
24279         local out=$($LFS heat_get $DIR/$tfile)
24280
24281         $LFS heat_get $DIR/$tfile
24282         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24283         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24284         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24285         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24286
24287         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24288         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24289         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24290         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24291
24292         sleep $((period_second + 3))
24293         echo "Sleep $((period_second + 3)) seconds..."
24294         # The recursion formula to calculate the heat of the file f is as
24295         # follow:
24296         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24297         # Where Hi is the heat value in the period between time points i*I and
24298         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24299         # to the weight of Ci.
24300         out=$($LFS heat_get $DIR/$tfile)
24301         $LFS heat_get $DIR/$tfile
24302         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24303         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24304         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24305         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24306
24307         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24308                 error "read sample ($readsample) is wrong"
24309         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24310                 error "write sample ($writesample) is wrong"
24311         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24312                 error "read bytes ($readbyte) is wrong"
24313         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24314                 error "write bytes ($writebyte) is wrong"
24315
24316         echo "QQQQ" > $DIR/$tfile
24317         echo "QQQQ" > $DIR/$tfile
24318         echo "QQQQ" > $DIR/$tfile
24319         cat $DIR/$tfile > /dev/null
24320         cat $DIR/$tfile > /dev/null
24321         cat $DIR/$tfile > /dev/null
24322         cat $DIR/$tfile > /dev/null
24323
24324         sleep $((period_second + 3))
24325         echo "Sleep $((period_second + 3)) seconds..."
24326
24327         out=$($LFS heat_get $DIR/$tfile)
24328         $LFS heat_get $DIR/$tfile
24329         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24330         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24331         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24332         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24333
24334         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24335                 4 * $decay_pct) / 100") -eq 1 ] ||
24336                 error "read sample ($readsample1) is wrong"
24337         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24338                 3 * $decay_pct) / 100") -eq 1 ] ||
24339                 error "write sample ($writesample1) is wrong"
24340         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24341                 20 * $decay_pct) / 100") -eq 1 ] ||
24342                 error "read bytes ($readbyte1) is wrong"
24343         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24344                 15 * $decay_pct) / 100") -eq 1 ] ||
24345                 error "write bytes ($writebyte1) is wrong"
24346
24347         echo "Turn off file heat for the file $DIR/$tfile"
24348         $LFS heat_set -o $DIR/$tfile
24349
24350         echo "QQQQ" > $DIR/$tfile
24351         echo "QQQQ" > $DIR/$tfile
24352         echo "QQQQ" > $DIR/$tfile
24353         cat $DIR/$tfile > /dev/null
24354         cat $DIR/$tfile > /dev/null
24355         cat $DIR/$tfile > /dev/null
24356         cat $DIR/$tfile > /dev/null
24357
24358         out=$($LFS heat_get $DIR/$tfile)
24359         $LFS heat_get $DIR/$tfile
24360         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24361         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24362         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24363         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24364
24365         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24366         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24367         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24368         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24369
24370         echo "Trun on file heat for the file $DIR/$tfile"
24371         $LFS heat_set -O $DIR/$tfile
24372
24373         echo "QQQQ" > $DIR/$tfile
24374         echo "QQQQ" > $DIR/$tfile
24375         echo "QQQQ" > $DIR/$tfile
24376         cat $DIR/$tfile > /dev/null
24377         cat $DIR/$tfile > /dev/null
24378         cat $DIR/$tfile > /dev/null
24379         cat $DIR/$tfile > /dev/null
24380
24381         out=$($LFS heat_get $DIR/$tfile)
24382         $LFS heat_get $DIR/$tfile
24383         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24384         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24385         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24386         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24387
24388         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24389         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24390         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24391         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24392
24393         $LFS heat_set -c $DIR/$tfile
24394         $LCTL set_param -n llite.*.file_heat=0
24395         echo "Turn off file heat support for the Lustre filesystem"
24396
24397         echo "QQQQ" > $DIR/$tfile
24398         echo "QQQQ" > $DIR/$tfile
24399         echo "QQQQ" > $DIR/$tfile
24400         cat $DIR/$tfile > /dev/null
24401         cat $DIR/$tfile > /dev/null
24402         cat $DIR/$tfile > /dev/null
24403         cat $DIR/$tfile > /dev/null
24404
24405         out=$($LFS heat_get $DIR/$tfile)
24406         $LFS heat_get $DIR/$tfile
24407         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24408         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24409         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24410         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24411
24412         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24413         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24414         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24415         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24416
24417         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24418         rm -f $DIR/$tfile
24419 }
24420 run_test 813 "File heat verfication"
24421
24422 test_814()
24423 {
24424         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24425         echo -n y >> $DIR/$tfile
24426         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24427         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24428 }
24429 run_test 814 "sparse cp works as expected (LU-12361)"
24430
24431 test_815()
24432 {
24433         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24434         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24435 }
24436 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24437
24438 test_816() {
24439         [ "$SHARED_KEY" = true ] &&
24440                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24441
24442         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24443         # ensure ost1 is connected
24444         stat $DIR/$tfile >/dev/null || error "can't stat"
24445         wait_osc_import_state client ost1 FULL
24446         # no locks, no reqs to let the connection idle
24447         cancel_lru_locks osc
24448         lru_resize_disable osc
24449         local before
24450         local now
24451         before=$($LCTL get_param -n \
24452                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24453
24454         wait_osc_import_state client ost1 IDLE
24455         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24456         now=$($LCTL get_param -n \
24457               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24458         [ $before == $now ] || error "lru_size changed $before != $now"
24459 }
24460 run_test 816 "do not reset lru_resize on idle reconnect"
24461
24462 cleanup_817() {
24463         umount $tmpdir
24464         exportfs -u localhost:$DIR/nfsexp
24465         rm -rf $DIR/nfsexp
24466 }
24467
24468 test_817() {
24469         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24470
24471         mkdir -p $DIR/nfsexp
24472         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24473                 error "failed to export nfs"
24474
24475         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24476         stack_trap cleanup_817 EXIT
24477
24478         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24479                 error "failed to mount nfs to $tmpdir"
24480
24481         cp /bin/true $tmpdir
24482         $DIR/nfsexp/true || error "failed to execute 'true' command"
24483 }
24484 run_test 817 "nfsd won't cache write lock for exec file"
24485
24486 test_818() {
24487         mkdir $DIR/$tdir
24488         $LFS setstripe -c1 -i0 $DIR/$tfile
24489         $LFS setstripe -c1 -i1 $DIR/$tfile
24490         stop $SINGLEMDS
24491         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24492         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24493         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24494                 error "start $SINGLEMDS failed"
24495         rm -rf $DIR/$tdir
24496 }
24497 run_test 818 "unlink with failed llog"
24498
24499 test_819a() {
24500         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24501         cancel_lru_locks osc
24502         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24503         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24504         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24505         rm -f $TDIR/$tfile
24506 }
24507 run_test 819a "too big niobuf in read"
24508
24509 test_819b() {
24510         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24511         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24512         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24513         cancel_lru_locks osc
24514         sleep 1
24515         rm -f $TDIR/$tfile
24516 }
24517 run_test 819b "too big niobuf in write"
24518
24519
24520 function test_820_start_ost() {
24521         sleep 5
24522
24523         for num in $(seq $OSTCOUNT); do
24524                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24525         done
24526 }
24527
24528 test_820() {
24529         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24530
24531         mkdir $DIR/$tdir
24532         umount_client $MOUNT || error "umount failed"
24533         for num in $(seq $OSTCOUNT); do
24534                 stop ost$num
24535         done
24536
24537         # mount client with no active OSTs
24538         # so that the client can't initialize max LOV EA size
24539         # from OSC notifications
24540         mount_client $MOUNT || error "mount failed"
24541         # delay OST starting to keep this 0 max EA size for a while
24542         test_820_start_ost &
24543
24544         # create a directory on MDS2
24545         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24546                 error "Failed to create directory"
24547         # open intent should update default EA size
24548         # see mdc_update_max_ea_from_body()
24549         # notice this is the very first RPC to MDS2
24550         cp /etc/services $DIR/$tdir/mds2 ||
24551                 error "Failed to copy files to mds$n"
24552 }
24553 run_test 820 "update max EA from open intent"
24554
24555 #
24556 # tests that do cleanup/setup should be run at the end
24557 #
24558
24559 test_900() {
24560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24561         local ls
24562
24563         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24564         $LCTL set_param fail_loc=0x903
24565
24566         cancel_lru_locks MGC
24567
24568         FAIL_ON_ERROR=true cleanup
24569         FAIL_ON_ERROR=true setup
24570 }
24571 run_test 900 "umount should not race with any mgc requeue thread"
24572
24573 # LUS-6253/LU-11185
24574 test_901() {
24575         local oldc
24576         local newc
24577         local olds
24578         local news
24579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24580
24581         # some get_param have a bug to handle dot in param name
24582         cancel_lru_locks MGC
24583         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24584         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24585         umount_client $MOUNT || error "umount failed"
24586         mount_client $MOUNT || error "mount failed"
24587         cancel_lru_locks MGC
24588         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24589         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24590
24591         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24592         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24593
24594         return 0
24595 }
24596 run_test 901 "don't leak a mgc lock on client umount"
24597
24598 # LU-13377
24599 test_902() {
24600         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24601                 skip "client does not have LU-13377 fix"
24602         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24603         $LCTL set_param fail_loc=0x1415
24604         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24605         cancel_lru_locks osc
24606         rm -f $DIR/$tfile
24607 }
24608 run_test 902 "test short write doesn't hang lustre"
24609
24610 complete $SECONDS
24611 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24612 check_and_cleanup_lustre
24613 if [ "$I_MOUNTED" != "yes" ]; then
24614         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24615 fi
24616 exit_status