Whamcloud - gitweb
LU-13981 tests: use $TRUNCATE consistently and correctly.
[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
16026         while [ ! -f $file1 ]; do sleep 0.1; done
16027
16028         $LFS swap_layouts $file1 $file2
16029         local rc=$?
16030         wait $DD_PID
16031         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16032         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16033
16034         # how many bytes copied before swapping layout
16035         local copied=$(stat -c %s $file2)
16036         local remaining=$(stat -c %s $ref1)
16037         remaining=$((remaining - copied))
16038         echo "Copied $copied bytes before swapping layout..."
16039
16040         cmp -n $copied $file1 $ref2 | grep differ &&
16041                 error "Content mismatch [0, $copied) of ref2 and file1"
16042         cmp -n $copied $file2 $ref1 ||
16043                 error "Content mismatch [0, $copied) of ref1 and file2"
16044         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16045                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16046
16047         # clean up
16048         rm -f $ref1 $ref2 $file1 $file2
16049 }
16050 run_test 184c "Concurrent write and layout swap"
16051
16052 test_184d() {
16053         check_swap_layouts_support
16054         check_swap_layout_no_dom $DIR
16055         [ -z "$(which getfattr 2>/dev/null)" ] &&
16056                 skip_env "no getfattr command"
16057
16058         local file1=$DIR/$tdir/$tfile-1
16059         local file2=$DIR/$tdir/$tfile-2
16060         local file3=$DIR/$tdir/$tfile-3
16061         local lovea1
16062         local lovea2
16063
16064         mkdir -p $DIR/$tdir
16065         touch $file1 || error "create $file1 failed"
16066         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16067                 error "create $file2 failed"
16068         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16069                 error "create $file3 failed"
16070         lovea1=$(get_layout_param $file1)
16071
16072         $LFS swap_layouts $file2 $file3 ||
16073                 error "swap $file2 $file3 layouts failed"
16074         $LFS swap_layouts $file1 $file2 ||
16075                 error "swap $file1 $file2 layouts failed"
16076
16077         lovea2=$(get_layout_param $file2)
16078         echo "$lovea1"
16079         echo "$lovea2"
16080         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16081
16082         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16083         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16084 }
16085 run_test 184d "allow stripeless layouts swap"
16086
16087 test_184e() {
16088         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16089                 skip "Need MDS version at least 2.6.94"
16090         check_swap_layouts_support
16091         check_swap_layout_no_dom $DIR
16092         [ -z "$(which getfattr 2>/dev/null)" ] &&
16093                 skip_env "no getfattr command"
16094
16095         local file1=$DIR/$tdir/$tfile-1
16096         local file2=$DIR/$tdir/$tfile-2
16097         local file3=$DIR/$tdir/$tfile-3
16098         local lovea
16099
16100         mkdir -p $DIR/$tdir
16101         touch $file1 || error "create $file1 failed"
16102         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16103                 error "create $file2 failed"
16104         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16105                 error "create $file3 failed"
16106
16107         $LFS swap_layouts $file1 $file2 ||
16108                 error "swap $file1 $file2 layouts failed"
16109
16110         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16111         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16112
16113         echo 123 > $file1 || error "Should be able to write into $file1"
16114
16115         $LFS swap_layouts $file1 $file3 ||
16116                 error "swap $file1 $file3 layouts failed"
16117
16118         echo 123 > $file1 || error "Should be able to write into $file1"
16119
16120         rm -rf $file1 $file2 $file3
16121 }
16122 run_test 184e "Recreate layout after stripeless layout swaps"
16123
16124 test_184f() {
16125         # Create a file with name longer than sizeof(struct stat) ==
16126         # 144 to see if we can get chars from the file name to appear
16127         # in the returned striping. Note that 'f' == 0x66.
16128         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16129
16130         mkdir -p $DIR/$tdir
16131         mcreate $DIR/$tdir/$file
16132         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16133                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16134         fi
16135 }
16136 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16137
16138 test_185() { # LU-2441
16139         # LU-3553 - no volatile file support in old servers
16140         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16141                 skip "Need MDS version at least 2.3.60"
16142
16143         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16144         touch $DIR/$tdir/spoo
16145         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16146         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16147                 error "cannot create/write a volatile file"
16148         [ "$FILESET" == "" ] &&
16149         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16150                 error "FID is still valid after close"
16151
16152         multiop_bg_pause $DIR/$tdir vVw4096_c
16153         local multi_pid=$!
16154
16155         local OLD_IFS=$IFS
16156         IFS=":"
16157         local fidv=($fid)
16158         IFS=$OLD_IFS
16159         # assume that the next FID for this client is sequential, since stdout
16160         # is unfortunately eaten by multiop_bg_pause
16161         local n=$((${fidv[1]} + 1))
16162         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16163         if [ "$FILESET" == "" ]; then
16164                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16165                         error "FID is missing before close"
16166         fi
16167         kill -USR1 $multi_pid
16168         # 1 second delay, so if mtime change we will see it
16169         sleep 1
16170         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16171         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16172 }
16173 run_test 185 "Volatile file support"
16174
16175 function create_check_volatile() {
16176         local idx=$1
16177         local tgt
16178
16179         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16180         local PID=$!
16181         sleep 1
16182         local FID=$(cat /tmp/${tfile}.fid)
16183         [ "$FID" == "" ] && error "can't get FID for volatile"
16184         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16185         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16186         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16187         kill -USR1 $PID
16188         wait
16189         sleep 1
16190         cancel_lru_locks mdc # flush opencache
16191         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16192         return 0
16193 }
16194
16195 test_185a(){
16196         # LU-12516 - volatile creation via .lustre
16197         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16198                 skip "Need MDS version at least 2.3.55"
16199
16200         create_check_volatile 0
16201         [ $MDSCOUNT -lt 2 ] && return 0
16202
16203         # DNE case
16204         create_check_volatile 1
16205
16206         return 0
16207 }
16208 run_test 185a "Volatile file creation in .lustre/fid/"
16209
16210 test_187a() {
16211         remote_mds_nodsh && skip "remote MDS with nodsh"
16212         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16213                 skip "Need MDS version at least 2.3.0"
16214
16215         local dir0=$DIR/$tdir/$testnum
16216         mkdir -p $dir0 || error "creating dir $dir0"
16217
16218         local file=$dir0/file1
16219         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16220         local dv1=$($LFS data_version $file)
16221         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16222         local dv2=$($LFS data_version $file)
16223         [[ $dv1 != $dv2 ]] ||
16224                 error "data version did not change on write $dv1 == $dv2"
16225
16226         # clean up
16227         rm -f $file1
16228 }
16229 run_test 187a "Test data version change"
16230
16231 test_187b() {
16232         remote_mds_nodsh && skip "remote MDS with nodsh"
16233         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16234                 skip "Need MDS version at least 2.3.0"
16235
16236         local dir0=$DIR/$tdir/$testnum
16237         mkdir -p $dir0 || error "creating dir $dir0"
16238
16239         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16240         [[ ${DV[0]} != ${DV[1]} ]] ||
16241                 error "data version did not change on write"\
16242                       " ${DV[0]} == ${DV[1]}"
16243
16244         # clean up
16245         rm -f $file1
16246 }
16247 run_test 187b "Test data version change on volatile file"
16248
16249 test_200() {
16250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16251         remote_mgs_nodsh && skip "remote MGS with nodsh"
16252         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16253
16254         local POOL=${POOL:-cea1}
16255         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16256         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16257         # Pool OST targets
16258         local first_ost=0
16259         local last_ost=$(($OSTCOUNT - 1))
16260         local ost_step=2
16261         local ost_list=$(seq $first_ost $ost_step $last_ost)
16262         local ost_range="$first_ost $last_ost $ost_step"
16263         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16264         local file_dir=$POOL_ROOT/file_tst
16265         local subdir=$test_path/subdir
16266         local rc=0
16267
16268         while : ; do
16269                 # former test_200a test_200b
16270                 pool_add $POOL                          || { rc=$? ; break; }
16271                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16272                 # former test_200c test_200d
16273                 mkdir -p $test_path
16274                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16275                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16276                 mkdir -p $subdir
16277                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16278                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16279                                                         || { rc=$? ; break; }
16280                 # former test_200e test_200f
16281                 local files=$((OSTCOUNT*3))
16282                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16283                                                         || { rc=$? ; break; }
16284                 pool_create_files $POOL $file_dir $files "$ost_list" \
16285                                                         || { rc=$? ; break; }
16286                 # former test_200g test_200h
16287                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16288                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16289
16290                 # former test_201a test_201b test_201c
16291                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16292
16293                 local f=$test_path/$tfile
16294                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16295                 pool_remove $POOL $f                    || { rc=$? ; break; }
16296                 break
16297         done
16298
16299         destroy_test_pools
16300
16301         return $rc
16302 }
16303 run_test 200 "OST pools"
16304
16305 # usage: default_attr <count | size | offset>
16306 default_attr() {
16307         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16308 }
16309
16310 # usage: check_default_stripe_attr
16311 check_default_stripe_attr() {
16312         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16313         case $1 in
16314         --stripe-count|-c)
16315                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16316         --stripe-size|-S)
16317                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16318         --stripe-index|-i)
16319                 EXPECTED=-1;;
16320         *)
16321                 error "unknown getstripe attr '$1'"
16322         esac
16323
16324         [ $ACTUAL == $EXPECTED ] ||
16325                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16326 }
16327
16328 test_204a() {
16329         test_mkdir $DIR/$tdir
16330         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16331
16332         check_default_stripe_attr --stripe-count
16333         check_default_stripe_attr --stripe-size
16334         check_default_stripe_attr --stripe-index
16335 }
16336 run_test 204a "Print default stripe attributes"
16337
16338 test_204b() {
16339         test_mkdir $DIR/$tdir
16340         $LFS setstripe --stripe-count 1 $DIR/$tdir
16341
16342         check_default_stripe_attr --stripe-size
16343         check_default_stripe_attr --stripe-index
16344 }
16345 run_test 204b "Print default stripe size and offset"
16346
16347 test_204c() {
16348         test_mkdir $DIR/$tdir
16349         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16350
16351         check_default_stripe_attr --stripe-count
16352         check_default_stripe_attr --stripe-index
16353 }
16354 run_test 204c "Print default stripe count and offset"
16355
16356 test_204d() {
16357         test_mkdir $DIR/$tdir
16358         $LFS setstripe --stripe-index 0 $DIR/$tdir
16359
16360         check_default_stripe_attr --stripe-count
16361         check_default_stripe_attr --stripe-size
16362 }
16363 run_test 204d "Print default stripe count and size"
16364
16365 test_204e() {
16366         test_mkdir $DIR/$tdir
16367         $LFS setstripe -d $DIR/$tdir
16368
16369         check_default_stripe_attr --stripe-count --raw
16370         check_default_stripe_attr --stripe-size --raw
16371         check_default_stripe_attr --stripe-index --raw
16372 }
16373 run_test 204e "Print raw stripe attributes"
16374
16375 test_204f() {
16376         test_mkdir $DIR/$tdir
16377         $LFS setstripe --stripe-count 1 $DIR/$tdir
16378
16379         check_default_stripe_attr --stripe-size --raw
16380         check_default_stripe_attr --stripe-index --raw
16381 }
16382 run_test 204f "Print raw stripe size and offset"
16383
16384 test_204g() {
16385         test_mkdir $DIR/$tdir
16386         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16387
16388         check_default_stripe_attr --stripe-count --raw
16389         check_default_stripe_attr --stripe-index --raw
16390 }
16391 run_test 204g "Print raw stripe count and offset"
16392
16393 test_204h() {
16394         test_mkdir $DIR/$tdir
16395         $LFS setstripe --stripe-index 0 $DIR/$tdir
16396
16397         check_default_stripe_attr --stripe-count --raw
16398         check_default_stripe_attr --stripe-size --raw
16399 }
16400 run_test 204h "Print raw stripe count and size"
16401
16402 # Figure out which job scheduler is being used, if any,
16403 # or use a fake one
16404 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16405         JOBENV=SLURM_JOB_ID
16406 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16407         JOBENV=LSB_JOBID
16408 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16409         JOBENV=PBS_JOBID
16410 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16411         JOBENV=LOADL_STEP_ID
16412 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16413         JOBENV=JOB_ID
16414 else
16415         $LCTL list_param jobid_name > /dev/null 2>&1
16416         if [ $? -eq 0 ]; then
16417                 JOBENV=nodelocal
16418         else
16419                 JOBENV=FAKE_JOBID
16420         fi
16421 fi
16422 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16423
16424 verify_jobstats() {
16425         local cmd=($1)
16426         shift
16427         local facets="$@"
16428
16429 # we don't really need to clear the stats for this test to work, since each
16430 # command has a unique jobid, but it makes debugging easier if needed.
16431 #       for facet in $facets; do
16432 #               local dev=$(convert_facet2label $facet)
16433 #               # clear old jobstats
16434 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16435 #       done
16436
16437         # use a new JobID for each test, or we might see an old one
16438         [ "$JOBENV" = "FAKE_JOBID" ] &&
16439                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16440
16441         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16442
16443         [ "$JOBENV" = "nodelocal" ] && {
16444                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16445                 $LCTL set_param jobid_name=$FAKE_JOBID
16446                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16447         }
16448
16449         log "Test: ${cmd[*]}"
16450         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16451
16452         if [ $JOBENV = "FAKE_JOBID" ]; then
16453                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16454         else
16455                 ${cmd[*]}
16456         fi
16457
16458         # all files are created on OST0000
16459         for facet in $facets; do
16460                 local stats="*.$(convert_facet2label $facet).job_stats"
16461
16462                 # strip out libtool wrappers for in-tree executables
16463                 if [ $(do_facet $facet lctl get_param $stats |
16464                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16465                         do_facet $facet lctl get_param $stats
16466                         error "No jobstats for $JOBVAL found on $facet::$stats"
16467                 fi
16468         done
16469 }
16470
16471 jobstats_set() {
16472         local new_jobenv=$1
16473
16474         set_persistent_param_and_check client "jobid_var" \
16475                 "$FSNAME.sys.jobid_var" $new_jobenv
16476 }
16477
16478 test_205a() { # Job stats
16479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16480         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16481                 skip "Need MDS version with at least 2.7.1"
16482         remote_mgs_nodsh && skip "remote MGS with nodsh"
16483         remote_mds_nodsh && skip "remote MDS with nodsh"
16484         remote_ost_nodsh && skip "remote OST with nodsh"
16485         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16486                 skip "Server doesn't support jobstats"
16487         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16488
16489         local old_jobenv=$($LCTL get_param -n jobid_var)
16490         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16491
16492         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16493                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16494         else
16495                 stack_trap "do_facet mgs $PERM_CMD \
16496                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16497         fi
16498         changelog_register
16499
16500         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16501                                 mdt.*.job_cleanup_interval | head -n 1)
16502         local new_interval=5
16503         do_facet $SINGLEMDS \
16504                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16505         stack_trap "do_facet $SINGLEMDS \
16506                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16507         local start=$SECONDS
16508
16509         local cmd
16510         # mkdir
16511         cmd="mkdir $DIR/$tdir"
16512         verify_jobstats "$cmd" "$SINGLEMDS"
16513         # rmdir
16514         cmd="rmdir $DIR/$tdir"
16515         verify_jobstats "$cmd" "$SINGLEMDS"
16516         # mkdir on secondary MDT
16517         if [ $MDSCOUNT -gt 1 ]; then
16518                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16519                 verify_jobstats "$cmd" "mds2"
16520         fi
16521         # mknod
16522         cmd="mknod $DIR/$tfile c 1 3"
16523         verify_jobstats "$cmd" "$SINGLEMDS"
16524         # unlink
16525         cmd="rm -f $DIR/$tfile"
16526         verify_jobstats "$cmd" "$SINGLEMDS"
16527         # create all files on OST0000 so verify_jobstats can find OST stats
16528         # open & close
16529         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16530         verify_jobstats "$cmd" "$SINGLEMDS"
16531         # setattr
16532         cmd="touch $DIR/$tfile"
16533         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16534         # write
16535         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16536         verify_jobstats "$cmd" "ost1"
16537         # read
16538         cancel_lru_locks osc
16539         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16540         verify_jobstats "$cmd" "ost1"
16541         # truncate
16542         cmd="$TRUNCATE $DIR/$tfile 0"
16543         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16544         # rename
16545         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16546         verify_jobstats "$cmd" "$SINGLEMDS"
16547         # jobstats expiry - sleep until old stats should be expired
16548         local left=$((new_interval + 5 - (SECONDS - start)))
16549         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16550                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16551                         "0" $left
16552         cmd="mkdir $DIR/$tdir.expire"
16553         verify_jobstats "$cmd" "$SINGLEMDS"
16554         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16555             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16556
16557         # Ensure that jobid are present in changelog (if supported by MDS)
16558         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16559                 changelog_dump | tail -10
16560                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16561                 [ $jobids -eq 9 ] ||
16562                         error "Wrong changelog jobid count $jobids != 9"
16563
16564                 # LU-5862
16565                 JOBENV="disable"
16566                 jobstats_set $JOBENV
16567                 touch $DIR/$tfile
16568                 changelog_dump | grep $tfile
16569                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16570                 [ $jobids -eq 0 ] ||
16571                         error "Unexpected jobids when jobid_var=$JOBENV"
16572         fi
16573
16574         # test '%j' access to environment variable - if supported
16575         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16576                 JOBENV="JOBCOMPLEX"
16577                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16578
16579                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16580         fi
16581
16582         # test '%j' access to per-session jobid - if supported
16583         if lctl list_param jobid_this_session > /dev/null 2>&1
16584         then
16585                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16586                 lctl set_param jobid_this_session=$USER
16587
16588                 JOBENV="JOBCOMPLEX"
16589                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16590
16591                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16592         fi
16593 }
16594 run_test 205a "Verify job stats"
16595
16596 # LU-13117, LU-13597
16597 test_205b() {
16598         job_stats="mdt.*.job_stats"
16599         $LCTL set_param $job_stats=clear
16600         # Setting jobid_var to USER might not be supported
16601         $LCTL set_param jobid_var=USER || true
16602         $LCTL set_param jobid_name="%e.%u"
16603         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16604         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16605                 grep "job_id:.*foolish" &&
16606                         error "Unexpected jobid found"
16607         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16608                 grep "open:.*min.*max.*sum" ||
16609                         error "wrong job_stats format found"
16610 }
16611 run_test 205b "Verify job stats jobid and output format"
16612
16613 # LU-13733
16614 test_205c() {
16615         $LCTL set_param llite.*.stats=0
16616         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16617         $LCTL get_param llite.*.stats
16618         $LCTL get_param llite.*.stats | grep \
16619                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16620                         error "wrong client stats format found"
16621 }
16622 run_test 205c "Verify client stats format"
16623
16624 # LU-1480, LU-1773 and LU-1657
16625 test_206() {
16626         mkdir -p $DIR/$tdir
16627         $LFS setstripe -c -1 $DIR/$tdir
16628 #define OBD_FAIL_LOV_INIT 0x1403
16629         $LCTL set_param fail_loc=0xa0001403
16630         $LCTL set_param fail_val=1
16631         touch $DIR/$tdir/$tfile || true
16632 }
16633 run_test 206 "fail lov_init_raid0() doesn't lbug"
16634
16635 test_207a() {
16636         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16637         local fsz=`stat -c %s $DIR/$tfile`
16638         cancel_lru_locks mdc
16639
16640         # do not return layout in getattr intent
16641 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16642         $LCTL set_param fail_loc=0x170
16643         local sz=`stat -c %s $DIR/$tfile`
16644
16645         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16646
16647         rm -rf $DIR/$tfile
16648 }
16649 run_test 207a "can refresh layout at glimpse"
16650
16651 test_207b() {
16652         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16653         local cksum=`md5sum $DIR/$tfile`
16654         local fsz=`stat -c %s $DIR/$tfile`
16655         cancel_lru_locks mdc
16656         cancel_lru_locks osc
16657
16658         # do not return layout in getattr intent
16659 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16660         $LCTL set_param fail_loc=0x171
16661
16662         # it will refresh layout after the file is opened but before read issues
16663         echo checksum is "$cksum"
16664         echo "$cksum" |md5sum -c --quiet || error "file differs"
16665
16666         rm -rf $DIR/$tfile
16667 }
16668 run_test 207b "can refresh layout at open"
16669
16670 test_208() {
16671         # FIXME: in this test suite, only RD lease is used. This is okay
16672         # for now as only exclusive open is supported. After generic lease
16673         # is done, this test suite should be revised. - Jinshan
16674
16675         remote_mds_nodsh && skip "remote MDS with nodsh"
16676         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16677                 skip "Need MDS version at least 2.4.52"
16678
16679         echo "==== test 1: verify get lease work"
16680         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16681
16682         echo "==== test 2: verify lease can be broken by upcoming open"
16683         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16684         local PID=$!
16685         sleep 1
16686
16687         $MULTIOP $DIR/$tfile oO_RDONLY:c
16688         kill -USR1 $PID && wait $PID || error "break lease error"
16689
16690         echo "==== test 3: verify lease can't be granted if an open already exists"
16691         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16692         local PID=$!
16693         sleep 1
16694
16695         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16696         kill -USR1 $PID && wait $PID || error "open file error"
16697
16698         echo "==== test 4: lease can sustain over recovery"
16699         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16700         PID=$!
16701         sleep 1
16702
16703         fail mds1
16704
16705         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16706
16707         echo "==== test 5: lease broken can't be regained by replay"
16708         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16709         PID=$!
16710         sleep 1
16711
16712         # open file to break lease and then recovery
16713         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16714         fail mds1
16715
16716         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16717
16718         rm -f $DIR/$tfile
16719 }
16720 run_test 208 "Exclusive open"
16721
16722 test_209() {
16723         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16724                 skip_env "must have disp_stripe"
16725
16726         touch $DIR/$tfile
16727         sync; sleep 5; sync;
16728
16729         echo 3 > /proc/sys/vm/drop_caches
16730         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16731                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16732         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16733
16734         # open/close 500 times
16735         for i in $(seq 500); do
16736                 cat $DIR/$tfile
16737         done
16738
16739         echo 3 > /proc/sys/vm/drop_caches
16740         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16741                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16742         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16743
16744         echo "before: $req_before, after: $req_after"
16745         [ $((req_after - req_before)) -ge 300 ] &&
16746                 error "open/close requests are not freed"
16747         return 0
16748 }
16749 run_test 209 "read-only open/close requests should be freed promptly"
16750
16751 test_210() {
16752         local pid
16753
16754         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16755         pid=$!
16756         sleep 1
16757
16758         $LFS getstripe $DIR/$tfile
16759         kill -USR1 $pid
16760         wait $pid || error "multiop failed"
16761
16762         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16763         pid=$!
16764         sleep 1
16765
16766         $LFS getstripe $DIR/$tfile
16767         kill -USR1 $pid
16768         wait $pid || error "multiop failed"
16769 }
16770 run_test 210 "lfs getstripe does not break leases"
16771
16772 test_212() {
16773         size=`date +%s`
16774         size=$((size % 8192 + 1))
16775         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16776         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16777         rm -f $DIR/f212 $DIR/f212.xyz
16778 }
16779 run_test 212 "Sendfile test ============================================"
16780
16781 test_213() {
16782         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16783         cancel_lru_locks osc
16784         lctl set_param fail_loc=0x8000040f
16785         # generate a read lock
16786         cat $DIR/$tfile > /dev/null
16787         # write to the file, it will try to cancel the above read lock.
16788         cat /etc/hosts >> $DIR/$tfile
16789 }
16790 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16791
16792 test_214() { # for bug 20133
16793         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16794         for (( i=0; i < 340; i++ )) ; do
16795                 touch $DIR/$tdir/d214c/a$i
16796         done
16797
16798         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16799         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16800         ls $DIR/d214c || error "ls $DIR/d214c failed"
16801         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16802         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16803 }
16804 run_test 214 "hash-indexed directory test - bug 20133"
16805
16806 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16807 create_lnet_proc_files() {
16808         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16809 }
16810
16811 # counterpart of create_lnet_proc_files
16812 remove_lnet_proc_files() {
16813         rm -f $TMP/lnet_$1.sys
16814 }
16815
16816 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16817 # 3rd arg as regexp for body
16818 check_lnet_proc_stats() {
16819         local l=$(cat "$TMP/lnet_$1" |wc -l)
16820         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16821
16822         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16823 }
16824
16825 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16826 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16827 # optional and can be regexp for 2nd line (lnet.routes case)
16828 check_lnet_proc_entry() {
16829         local blp=2          # blp stands for 'position of 1st line of body'
16830         [ -z "$5" ] || blp=3 # lnet.routes case
16831
16832         local l=$(cat "$TMP/lnet_$1" |wc -l)
16833         # subtracting one from $blp because the body can be empty
16834         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16835
16836         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16837                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16838
16839         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16840                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16841
16842         # bail out if any unexpected line happened
16843         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16844         [ "$?" != 0 ] || error "$2 misformatted"
16845 }
16846
16847 test_215() { # for bugs 18102, 21079, 21517
16848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16849
16850         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16851         local P='[1-9][0-9]*'           # positive numeric
16852         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16853         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16854         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16855         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16856
16857         local L1 # regexp for 1st line
16858         local L2 # regexp for 2nd line (optional)
16859         local BR # regexp for the rest (body)
16860
16861         # lnet.stats should look as 11 space-separated non-negative numerics
16862         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16863         create_lnet_proc_files "stats"
16864         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16865         remove_lnet_proc_files "stats"
16866
16867         # lnet.routes should look like this:
16868         # Routing disabled/enabled
16869         # net hops priority state router
16870         # where net is a string like tcp0, hops > 0, priority >= 0,
16871         # state is up/down,
16872         # router is a string like 192.168.1.1@tcp2
16873         L1="^Routing (disabled|enabled)$"
16874         L2="^net +hops +priority +state +router$"
16875         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16876         create_lnet_proc_files "routes"
16877         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16878         remove_lnet_proc_files "routes"
16879
16880         # lnet.routers should look like this:
16881         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16882         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16883         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16884         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16885         L1="^ref +rtr_ref +alive +router$"
16886         BR="^$P +$P +(up|down) +$NID$"
16887         create_lnet_proc_files "routers"
16888         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16889         remove_lnet_proc_files "routers"
16890
16891         # lnet.peers should look like this:
16892         # nid refs state last max rtr min tx min queue
16893         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16894         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16895         # numeric (0 or >0 or <0), queue >= 0.
16896         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16897         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16898         create_lnet_proc_files "peers"
16899         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16900         remove_lnet_proc_files "peers"
16901
16902         # lnet.buffers  should look like this:
16903         # pages count credits min
16904         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16905         L1="^pages +count +credits +min$"
16906         BR="^ +$N +$N +$I +$I$"
16907         create_lnet_proc_files "buffers"
16908         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16909         remove_lnet_proc_files "buffers"
16910
16911         # lnet.nis should look like this:
16912         # nid status alive refs peer rtr max tx min
16913         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16914         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16915         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16916         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16917         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16918         create_lnet_proc_files "nis"
16919         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16920         remove_lnet_proc_files "nis"
16921
16922         # can we successfully write to lnet.stats?
16923         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16924 }
16925 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16926
16927 test_216() { # bug 20317
16928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16929         remote_ost_nodsh && skip "remote OST with nodsh"
16930
16931         local node
16932         local facets=$(get_facets OST)
16933         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16934
16935         save_lustre_params client "osc.*.contention_seconds" > $p
16936         save_lustre_params $facets \
16937                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16938         save_lustre_params $facets \
16939                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16940         save_lustre_params $facets \
16941                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16942         clear_stats osc.*.osc_stats
16943
16944         # agressive lockless i/o settings
16945         do_nodes $(comma_list $(osts_nodes)) \
16946                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16947                         ldlm.namespaces.filter-*.contended_locks=0 \
16948                         ldlm.namespaces.filter-*.contention_seconds=60"
16949         lctl set_param -n osc.*.contention_seconds=60
16950
16951         $DIRECTIO write $DIR/$tfile 0 10 4096
16952         $CHECKSTAT -s 40960 $DIR/$tfile
16953
16954         # disable lockless i/o
16955         do_nodes $(comma_list $(osts_nodes)) \
16956                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16957                         ldlm.namespaces.filter-*.contended_locks=32 \
16958                         ldlm.namespaces.filter-*.contention_seconds=0"
16959         lctl set_param -n osc.*.contention_seconds=0
16960         clear_stats osc.*.osc_stats
16961
16962         dd if=/dev/zero of=$DIR/$tfile count=0
16963         $CHECKSTAT -s 0 $DIR/$tfile
16964
16965         restore_lustre_params <$p
16966         rm -f $p
16967         rm $DIR/$tfile
16968 }
16969 run_test 216 "check lockless direct write updates file size and kms correctly"
16970
16971 test_217() { # bug 22430
16972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16973
16974         local node
16975         local nid
16976
16977         for node in $(nodes_list); do
16978                 nid=$(host_nids_address $node $NETTYPE)
16979                 if [[ $nid = *-* ]] ; then
16980                         echo "lctl ping $(h2nettype $nid)"
16981                         lctl ping $(h2nettype $nid)
16982                 else
16983                         echo "skipping $node (no hyphen detected)"
16984                 fi
16985         done
16986 }
16987 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16988
16989 test_218() {
16990        # do directio so as not to populate the page cache
16991        log "creating a 10 Mb file"
16992        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16993        log "starting reads"
16994        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16995        log "truncating the file"
16996        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16997        log "killing dd"
16998        kill %+ || true # reads might have finished
16999        echo "wait until dd is finished"
17000        wait
17001        log "removing the temporary file"
17002        rm -rf $DIR/$tfile || error "tmp file removal failed"
17003 }
17004 run_test 218 "parallel read and truncate should not deadlock"
17005
17006 test_219() {
17007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17008
17009         # write one partial page
17010         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17011         # set no grant so vvp_io_commit_write will do sync write
17012         $LCTL set_param fail_loc=0x411
17013         # write a full page at the end of file
17014         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17015
17016         $LCTL set_param fail_loc=0
17017         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17018         $LCTL set_param fail_loc=0x411
17019         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17020
17021         # LU-4201
17022         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17023         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17024 }
17025 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17026
17027 test_220() { #LU-325
17028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17029         remote_ost_nodsh && skip "remote OST with nodsh"
17030         remote_mds_nodsh && skip "remote MDS with nodsh"
17031         remote_mgs_nodsh && skip "remote MGS with nodsh"
17032
17033         local OSTIDX=0
17034
17035         # create on MDT0000 so the last_id and next_id are correct
17036         mkdir $DIR/$tdir
17037         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17038         OST=${OST%_UUID}
17039
17040         # on the mdt's osc
17041         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17042         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17043                         osp.$mdtosc_proc1.prealloc_last_id)
17044         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17045                         osp.$mdtosc_proc1.prealloc_next_id)
17046
17047         $LFS df -i
17048
17049         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17050         #define OBD_FAIL_OST_ENOINO              0x229
17051         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17052         create_pool $FSNAME.$TESTNAME || return 1
17053         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17054
17055         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17056
17057         MDSOBJS=$((last_id - next_id))
17058         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17059
17060         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17061         echo "OST still has $count kbytes free"
17062
17063         echo "create $MDSOBJS files @next_id..."
17064         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17065
17066         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17067                         osp.$mdtosc_proc1.prealloc_last_id)
17068         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17069                         osp.$mdtosc_proc1.prealloc_next_id)
17070
17071         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17072         $LFS df -i
17073
17074         echo "cleanup..."
17075
17076         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17077         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17078
17079         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17080                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17081         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17082                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17083         echo "unlink $MDSOBJS files @$next_id..."
17084         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17085 }
17086 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17087
17088 test_221() {
17089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17090
17091         dd if=`which date` of=$MOUNT/date oflag=sync
17092         chmod +x $MOUNT/date
17093
17094         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17095         $LCTL set_param fail_loc=0x80001401
17096
17097         $MOUNT/date > /dev/null
17098         rm -f $MOUNT/date
17099 }
17100 run_test 221 "make sure fault and truncate race to not cause OOM"
17101
17102 test_222a () {
17103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17104
17105         rm -rf $DIR/$tdir
17106         test_mkdir $DIR/$tdir
17107         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17108         createmany -o $DIR/$tdir/$tfile 10
17109         cancel_lru_locks mdc
17110         cancel_lru_locks osc
17111         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17112         $LCTL set_param fail_loc=0x31a
17113         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17114         $LCTL set_param fail_loc=0
17115         rm -r $DIR/$tdir
17116 }
17117 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17118
17119 test_222b () {
17120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17121
17122         rm -rf $DIR/$tdir
17123         test_mkdir $DIR/$tdir
17124         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17125         createmany -o $DIR/$tdir/$tfile 10
17126         cancel_lru_locks mdc
17127         cancel_lru_locks osc
17128         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17129         $LCTL set_param fail_loc=0x31a
17130         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17131         $LCTL set_param fail_loc=0
17132 }
17133 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17134
17135 test_223 () {
17136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17137
17138         rm -rf $DIR/$tdir
17139         test_mkdir $DIR/$tdir
17140         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17141         createmany -o $DIR/$tdir/$tfile 10
17142         cancel_lru_locks mdc
17143         cancel_lru_locks osc
17144         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17145         $LCTL set_param fail_loc=0x31b
17146         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17147         $LCTL set_param fail_loc=0
17148         rm -r $DIR/$tdir
17149 }
17150 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17151
17152 test_224a() { # LU-1039, MRP-303
17153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17154
17155         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17156         $LCTL set_param fail_loc=0x508
17157         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17158         $LCTL set_param fail_loc=0
17159         df $DIR
17160 }
17161 run_test 224a "Don't panic on bulk IO failure"
17162
17163 test_224b() { # LU-1039, MRP-303
17164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17165
17166         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17167         cancel_lru_locks osc
17168         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17169         $LCTL set_param fail_loc=0x515
17170         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17171         $LCTL set_param fail_loc=0
17172         df $DIR
17173 }
17174 run_test 224b "Don't panic on bulk IO failure"
17175
17176 test_224c() { # LU-6441
17177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17178         remote_mds_nodsh && skip "remote MDS with nodsh"
17179
17180         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17181         save_writethrough $p
17182         set_cache writethrough on
17183
17184         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17185         local at_max=$($LCTL get_param -n at_max)
17186         local timeout=$($LCTL get_param -n timeout)
17187         local test_at="at_max"
17188         local param_at="$FSNAME.sys.at_max"
17189         local test_timeout="timeout"
17190         local param_timeout="$FSNAME.sys.timeout"
17191
17192         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17193
17194         set_persistent_param_and_check client "$test_at" "$param_at" 0
17195         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17196
17197         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17198         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17199         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17200         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17201         sync
17202         do_facet ost1 "$LCTL set_param fail_loc=0"
17203
17204         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17205         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17206                 $timeout
17207
17208         $LCTL set_param -n $pages_per_rpc
17209         restore_lustre_params < $p
17210         rm -f $p
17211 }
17212 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17213
17214 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17215 test_225a () {
17216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17217         if [ -z ${MDSSURVEY} ]; then
17218                 skip_env "mds-survey not found"
17219         fi
17220         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17221                 skip "Need MDS version at least 2.2.51"
17222
17223         local mds=$(facet_host $SINGLEMDS)
17224         local target=$(do_nodes $mds 'lctl dl' |
17225                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17226
17227         local cmd1="file_count=1000 thrhi=4"
17228         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17229         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17230         local cmd="$cmd1 $cmd2 $cmd3"
17231
17232         rm -f ${TMP}/mds_survey*
17233         echo + $cmd
17234         eval $cmd || error "mds-survey with zero-stripe failed"
17235         cat ${TMP}/mds_survey*
17236         rm -f ${TMP}/mds_survey*
17237 }
17238 run_test 225a "Metadata survey sanity with zero-stripe"
17239
17240 test_225b () {
17241         if [ -z ${MDSSURVEY} ]; then
17242                 skip_env "mds-survey not found"
17243         fi
17244         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17245                 skip "Need MDS version at least 2.2.51"
17246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17247         remote_mds_nodsh && skip "remote MDS with nodsh"
17248         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17249                 skip_env "Need to mount OST to test"
17250         fi
17251
17252         local mds=$(facet_host $SINGLEMDS)
17253         local target=$(do_nodes $mds 'lctl dl' |
17254                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17255
17256         local cmd1="file_count=1000 thrhi=4"
17257         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17258         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17259         local cmd="$cmd1 $cmd2 $cmd3"
17260
17261         rm -f ${TMP}/mds_survey*
17262         echo + $cmd
17263         eval $cmd || error "mds-survey with stripe_count failed"
17264         cat ${TMP}/mds_survey*
17265         rm -f ${TMP}/mds_survey*
17266 }
17267 run_test 225b "Metadata survey sanity with stripe_count = 1"
17268
17269 mcreate_path2fid () {
17270         local mode=$1
17271         local major=$2
17272         local minor=$3
17273         local name=$4
17274         local desc=$5
17275         local path=$DIR/$tdir/$name
17276         local fid
17277         local rc
17278         local fid_path
17279
17280         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17281                 error "cannot create $desc"
17282
17283         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17284         rc=$?
17285         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17286
17287         fid_path=$($LFS fid2path $MOUNT $fid)
17288         rc=$?
17289         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17290
17291         [ "$path" == "$fid_path" ] ||
17292                 error "fid2path returned $fid_path, expected $path"
17293
17294         echo "pass with $path and $fid"
17295 }
17296
17297 test_226a () {
17298         rm -rf $DIR/$tdir
17299         mkdir -p $DIR/$tdir
17300
17301         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17302         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17303         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17304         mcreate_path2fid 0040666 0 0 dir "directory"
17305         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17306         mcreate_path2fid 0100666 0 0 file "regular file"
17307         mcreate_path2fid 0120666 0 0 link "symbolic link"
17308         mcreate_path2fid 0140666 0 0 sock "socket"
17309 }
17310 run_test 226a "call path2fid and fid2path on files of all type"
17311
17312 test_226b () {
17313         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17314
17315         local MDTIDX=1
17316
17317         rm -rf $DIR/$tdir
17318         mkdir -p $DIR/$tdir
17319         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17320                 error "create remote directory failed"
17321         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17322         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17323                                 "character special file (null)"
17324         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17325                                 "character special file (no device)"
17326         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17327         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17328                                 "block special file (loop)"
17329         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17330         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17331         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17332 }
17333 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17334
17335 test_226c () {
17336         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17337         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17338                 skip "Need MDS version at least 2.13.55"
17339
17340         local submnt=/mnt/submnt
17341         local srcfile=/etc/passwd
17342         local dstfile=$submnt/passwd
17343         local path
17344         local fid
17345
17346         rm -rf $DIR/$tdir
17347         rm -rf $submnt
17348         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17349                 error "create remote directory failed"
17350         mkdir -p $submnt || error "create $submnt failed"
17351         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17352                 error "mount $submnt failed"
17353         stack_trap "umount $submnt" EXIT
17354
17355         cp $srcfile $dstfile
17356         fid=$($LFS path2fid $dstfile)
17357         path=$($LFS fid2path $submnt "$fid")
17358         [ "$path" = "$dstfile" ] ||
17359                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17360 }
17361 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17362
17363 # LU-1299 Executing or running ldd on a truncated executable does not
17364 # cause an out-of-memory condition.
17365 test_227() {
17366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17367         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17368
17369         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17370         chmod +x $MOUNT/date
17371
17372         $MOUNT/date > /dev/null
17373         ldd $MOUNT/date > /dev/null
17374         rm -f $MOUNT/date
17375 }
17376 run_test 227 "running truncated executable does not cause OOM"
17377
17378 # LU-1512 try to reuse idle OI blocks
17379 test_228a() {
17380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17381         remote_mds_nodsh && skip "remote MDS with nodsh"
17382         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17383
17384         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17385         local myDIR=$DIR/$tdir
17386
17387         mkdir -p $myDIR
17388         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17389         $LCTL set_param fail_loc=0x80001002
17390         createmany -o $myDIR/t- 10000
17391         $LCTL set_param fail_loc=0
17392         # The guard is current the largest FID holder
17393         touch $myDIR/guard
17394         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17395                     tr -d '[')
17396         local IDX=$(($SEQ % 64))
17397
17398         do_facet $SINGLEMDS sync
17399         # Make sure journal flushed.
17400         sleep 6
17401         local blk1=$(do_facet $SINGLEMDS \
17402                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17403                      grep Blockcount | awk '{print $4}')
17404
17405         # Remove old files, some OI blocks will become idle.
17406         unlinkmany $myDIR/t- 10000
17407         # Create new files, idle OI blocks should be reused.
17408         createmany -o $myDIR/t- 2000
17409         do_facet $SINGLEMDS sync
17410         # Make sure journal flushed.
17411         sleep 6
17412         local blk2=$(do_facet $SINGLEMDS \
17413                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17414                      grep Blockcount | awk '{print $4}')
17415
17416         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17417 }
17418 run_test 228a "try to reuse idle OI blocks"
17419
17420 test_228b() {
17421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17422         remote_mds_nodsh && skip "remote MDS with nodsh"
17423         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17424
17425         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17426         local myDIR=$DIR/$tdir
17427
17428         mkdir -p $myDIR
17429         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17430         $LCTL set_param fail_loc=0x80001002
17431         createmany -o $myDIR/t- 10000
17432         $LCTL set_param fail_loc=0
17433         # The guard is current the largest FID holder
17434         touch $myDIR/guard
17435         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17436                     tr -d '[')
17437         local IDX=$(($SEQ % 64))
17438
17439         do_facet $SINGLEMDS sync
17440         # Make sure journal flushed.
17441         sleep 6
17442         local blk1=$(do_facet $SINGLEMDS \
17443                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17444                      grep Blockcount | awk '{print $4}')
17445
17446         # Remove old files, some OI blocks will become idle.
17447         unlinkmany $myDIR/t- 10000
17448
17449         # stop the MDT
17450         stop $SINGLEMDS || error "Fail to stop MDT."
17451         # remount the MDT
17452         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17453
17454         df $MOUNT || error "Fail to df."
17455         # Create new files, idle OI blocks should be reused.
17456         createmany -o $myDIR/t- 2000
17457         do_facet $SINGLEMDS sync
17458         # Make sure journal flushed.
17459         sleep 6
17460         local blk2=$(do_facet $SINGLEMDS \
17461                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17462                      grep Blockcount | awk '{print $4}')
17463
17464         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17465 }
17466 run_test 228b "idle OI blocks can be reused after MDT restart"
17467
17468 #LU-1881
17469 test_228c() {
17470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17471         remote_mds_nodsh && skip "remote MDS with nodsh"
17472         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17473
17474         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17475         local myDIR=$DIR/$tdir
17476
17477         mkdir -p $myDIR
17478         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17479         $LCTL set_param fail_loc=0x80001002
17480         # 20000 files can guarantee there are index nodes in the OI file
17481         createmany -o $myDIR/t- 20000
17482         $LCTL set_param fail_loc=0
17483         # The guard is current the largest FID holder
17484         touch $myDIR/guard
17485         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17486                     tr -d '[')
17487         local IDX=$(($SEQ % 64))
17488
17489         do_facet $SINGLEMDS sync
17490         # Make sure journal flushed.
17491         sleep 6
17492         local blk1=$(do_facet $SINGLEMDS \
17493                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17494                      grep Blockcount | awk '{print $4}')
17495
17496         # Remove old files, some OI blocks will become idle.
17497         unlinkmany $myDIR/t- 20000
17498         rm -f $myDIR/guard
17499         # The OI file should become empty now
17500
17501         # Create new files, idle OI blocks should be reused.
17502         createmany -o $myDIR/t- 2000
17503         do_facet $SINGLEMDS sync
17504         # Make sure journal flushed.
17505         sleep 6
17506         local blk2=$(do_facet $SINGLEMDS \
17507                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17508                      grep Blockcount | awk '{print $4}')
17509
17510         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17511 }
17512 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17513
17514 test_229() { # LU-2482, LU-3448
17515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17516         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17517         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17518                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17519
17520         rm -f $DIR/$tfile
17521
17522         # Create a file with a released layout and stripe count 2.
17523         $MULTIOP $DIR/$tfile H2c ||
17524                 error "failed to create file with released layout"
17525
17526         $LFS getstripe -v $DIR/$tfile
17527
17528         local pattern=$($LFS getstripe -L $DIR/$tfile)
17529         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17530
17531         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17532                 error "getstripe"
17533         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17534         stat $DIR/$tfile || error "failed to stat released file"
17535
17536         chown $RUNAS_ID $DIR/$tfile ||
17537                 error "chown $RUNAS_ID $DIR/$tfile failed"
17538
17539         chgrp $RUNAS_ID $DIR/$tfile ||
17540                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17541
17542         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17543         rm $DIR/$tfile || error "failed to remove released file"
17544 }
17545 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17546
17547 test_230a() {
17548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17550         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17551                 skip "Need MDS version at least 2.11.52"
17552
17553         local MDTIDX=1
17554
17555         test_mkdir $DIR/$tdir
17556         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17557         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17558         [ $mdt_idx -ne 0 ] &&
17559                 error "create local directory on wrong MDT $mdt_idx"
17560
17561         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17562                         error "create remote directory failed"
17563         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17564         [ $mdt_idx -ne $MDTIDX ] &&
17565                 error "create remote directory on wrong MDT $mdt_idx"
17566
17567         createmany -o $DIR/$tdir/test_230/t- 10 ||
17568                 error "create files on remote directory failed"
17569         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17570         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17571         rm -r $DIR/$tdir || error "unlink remote directory failed"
17572 }
17573 run_test 230a "Create remote directory and files under the remote directory"
17574
17575 test_230b() {
17576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17578         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17579                 skip "Need MDS version at least 2.11.52"
17580
17581         local MDTIDX=1
17582         local mdt_index
17583         local i
17584         local file
17585         local pid
17586         local stripe_count
17587         local migrate_dir=$DIR/$tdir/migrate_dir
17588         local other_dir=$DIR/$tdir/other_dir
17589
17590         test_mkdir $DIR/$tdir
17591         test_mkdir -i0 -c1 $migrate_dir
17592         test_mkdir -i0 -c1 $other_dir
17593         for ((i=0; i<10; i++)); do
17594                 mkdir -p $migrate_dir/dir_${i}
17595                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17596                         error "create files under remote dir failed $i"
17597         done
17598
17599         cp /etc/passwd $migrate_dir/$tfile
17600         cp /etc/passwd $other_dir/$tfile
17601         chattr +SAD $migrate_dir
17602         chattr +SAD $migrate_dir/$tfile
17603
17604         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17605         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17606         local old_dir_mode=$(stat -c%f $migrate_dir)
17607         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17608
17609         mkdir -p $migrate_dir/dir_default_stripe2
17610         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17611         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17612
17613         mkdir -p $other_dir
17614         ln $migrate_dir/$tfile $other_dir/luna
17615         ln $migrate_dir/$tfile $migrate_dir/sofia
17616         ln $other_dir/$tfile $migrate_dir/david
17617         ln -s $migrate_dir/$tfile $other_dir/zachary
17618         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17619         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17620
17621         local len
17622         local lnktgt
17623
17624         # inline symlink
17625         for len in 58 59 60; do
17626                 lnktgt=$(str_repeat 'l' $len)
17627                 touch $migrate_dir/$lnktgt
17628                 ln -s $lnktgt $migrate_dir/${len}char_ln
17629         done
17630
17631         # PATH_MAX
17632         for len in 4094 4095; do
17633                 lnktgt=$(str_repeat 'l' $len)
17634                 ln -s $lnktgt $migrate_dir/${len}char_ln
17635         done
17636
17637         # NAME_MAX
17638         for len in 254 255; do
17639                 touch $migrate_dir/$(str_repeat 'l' $len)
17640         done
17641
17642         $LFS migrate -m $MDTIDX $migrate_dir ||
17643                 error "fails on migrating remote dir to MDT1"
17644
17645         echo "migratate to MDT1, then checking.."
17646         for ((i = 0; i < 10; i++)); do
17647                 for file in $(find $migrate_dir/dir_${i}); do
17648                         mdt_index=$($LFS getstripe -m $file)
17649                         # broken symlink getstripe will fail
17650                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17651                                 error "$file is not on MDT${MDTIDX}"
17652                 done
17653         done
17654
17655         # the multiple link file should still in MDT0
17656         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17657         [ $mdt_index == 0 ] ||
17658                 error "$file is not on MDT${MDTIDX}"
17659
17660         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17661         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17662                 error " expect $old_dir_flag get $new_dir_flag"
17663
17664         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17665         [ "$old_file_flag" = "$new_file_flag" ] ||
17666                 error " expect $old_file_flag get $new_file_flag"
17667
17668         local new_dir_mode=$(stat -c%f $migrate_dir)
17669         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17670                 error "expect mode $old_dir_mode get $new_dir_mode"
17671
17672         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17673         [ "$old_file_mode" = "$new_file_mode" ] ||
17674                 error "expect mode $old_file_mode get $new_file_mode"
17675
17676         diff /etc/passwd $migrate_dir/$tfile ||
17677                 error "$tfile different after migration"
17678
17679         diff /etc/passwd $other_dir/luna ||
17680                 error "luna different after migration"
17681
17682         diff /etc/passwd $migrate_dir/sofia ||
17683                 error "sofia different after migration"
17684
17685         diff /etc/passwd $migrate_dir/david ||
17686                 error "david different after migration"
17687
17688         diff /etc/passwd $other_dir/zachary ||
17689                 error "zachary different after migration"
17690
17691         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17692                 error "${tfile}_ln different after migration"
17693
17694         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17695                 error "${tfile}_ln_other different after migration"
17696
17697         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17698         [ $stripe_count = 2 ] ||
17699                 error "dir strpe_count $d != 2 after migration."
17700
17701         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17702         [ $stripe_count = 2 ] ||
17703                 error "file strpe_count $d != 2 after migration."
17704
17705         #migrate back to MDT0
17706         MDTIDX=0
17707
17708         $LFS migrate -m $MDTIDX $migrate_dir ||
17709                 error "fails on migrating remote dir to MDT0"
17710
17711         echo "migrate back to MDT0, checking.."
17712         for file in $(find $migrate_dir); do
17713                 mdt_index=$($LFS getstripe -m $file)
17714                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17715                         error "$file is not on MDT${MDTIDX}"
17716         done
17717
17718         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17719         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17720                 error " expect $old_dir_flag get $new_dir_flag"
17721
17722         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17723         [ "$old_file_flag" = "$new_file_flag" ] ||
17724                 error " expect $old_file_flag get $new_file_flag"
17725
17726         local new_dir_mode=$(stat -c%f $migrate_dir)
17727         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17728                 error "expect mode $old_dir_mode get $new_dir_mode"
17729
17730         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17731         [ "$old_file_mode" = "$new_file_mode" ] ||
17732                 error "expect mode $old_file_mode get $new_file_mode"
17733
17734         diff /etc/passwd ${migrate_dir}/$tfile ||
17735                 error "$tfile different after migration"
17736
17737         diff /etc/passwd ${other_dir}/luna ||
17738                 error "luna different after migration"
17739
17740         diff /etc/passwd ${migrate_dir}/sofia ||
17741                 error "sofia different after migration"
17742
17743         diff /etc/passwd ${other_dir}/zachary ||
17744                 error "zachary different after migration"
17745
17746         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17747                 error "${tfile}_ln different after migration"
17748
17749         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17750                 error "${tfile}_ln_other different after migration"
17751
17752         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17753         [ $stripe_count = 2 ] ||
17754                 error "dir strpe_count $d != 2 after migration."
17755
17756         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17757         [ $stripe_count = 2 ] ||
17758                 error "file strpe_count $d != 2 after migration."
17759
17760         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17761 }
17762 run_test 230b "migrate directory"
17763
17764 test_230c() {
17765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17766         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17767         remote_mds_nodsh && skip "remote MDS with nodsh"
17768         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17769                 skip "Need MDS version at least 2.11.52"
17770
17771         local MDTIDX=1
17772         local total=3
17773         local mdt_index
17774         local file
17775         local migrate_dir=$DIR/$tdir/migrate_dir
17776
17777         #If migrating directory fails in the middle, all entries of
17778         #the directory is still accessiable.
17779         test_mkdir $DIR/$tdir
17780         test_mkdir -i0 -c1 $migrate_dir
17781         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17782         stat $migrate_dir
17783         createmany -o $migrate_dir/f $total ||
17784                 error "create files under ${migrate_dir} failed"
17785
17786         # fail after migrating top dir, and this will fail only once, so the
17787         # first sub file migration will fail (currently f3), others succeed.
17788         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17789         do_facet mds1 lctl set_param fail_loc=0x1801
17790         local t=$(ls $migrate_dir | wc -l)
17791         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17792                 error "migrate should fail"
17793         local u=$(ls $migrate_dir | wc -l)
17794         [ "$u" == "$t" ] || error "$u != $t during migration"
17795
17796         # add new dir/file should succeed
17797         mkdir $migrate_dir/dir ||
17798                 error "mkdir failed under migrating directory"
17799         touch $migrate_dir/file ||
17800                 error "create file failed under migrating directory"
17801
17802         # add file with existing name should fail
17803         for file in $migrate_dir/f*; do
17804                 stat $file > /dev/null || error "stat $file failed"
17805                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17806                         error "open(O_CREAT|O_EXCL) $file should fail"
17807                 $MULTIOP $file m && error "create $file should fail"
17808                 touch $DIR/$tdir/remote_dir/$tfile ||
17809                         error "touch $tfile failed"
17810                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17811                         error "link $file should fail"
17812                 mdt_index=$($LFS getstripe -m $file)
17813                 if [ $mdt_index == 0 ]; then
17814                         # file failed to migrate is not allowed to rename to
17815                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17816                                 error "rename to $file should fail"
17817                 else
17818                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17819                                 error "rename to $file failed"
17820                 fi
17821                 echo hello >> $file || error "write $file failed"
17822         done
17823
17824         # resume migration with different options should fail
17825         $LFS migrate -m 0 $migrate_dir &&
17826                 error "migrate -m 0 $migrate_dir should fail"
17827
17828         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17829                 error "migrate -c 2 $migrate_dir should fail"
17830
17831         # resume migration should succeed
17832         $LFS migrate -m $MDTIDX $migrate_dir ||
17833                 error "migrate $migrate_dir failed"
17834
17835         echo "Finish migration, then checking.."
17836         for file in $(find $migrate_dir); do
17837                 mdt_index=$($LFS getstripe -m $file)
17838                 [ $mdt_index == $MDTIDX ] ||
17839                         error "$file is not on MDT${MDTIDX}"
17840         done
17841
17842         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17843 }
17844 run_test 230c "check directory accessiblity if migration failed"
17845
17846 test_230d() {
17847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17850                 skip "Need MDS version at least 2.11.52"
17851         # LU-11235
17852         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17853
17854         local migrate_dir=$DIR/$tdir/migrate_dir
17855         local old_index
17856         local new_index
17857         local old_count
17858         local new_count
17859         local new_hash
17860         local mdt_index
17861         local i
17862         local j
17863
17864         old_index=$((RANDOM % MDSCOUNT))
17865         old_count=$((MDSCOUNT - old_index))
17866         new_index=$((RANDOM % MDSCOUNT))
17867         new_count=$((MDSCOUNT - new_index))
17868         new_hash=1 # for all_char
17869
17870         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17871         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17872
17873         test_mkdir $DIR/$tdir
17874         test_mkdir -i $old_index -c $old_count $migrate_dir
17875
17876         for ((i=0; i<100; i++)); do
17877                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17878                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17879                         error "create files under remote dir failed $i"
17880         done
17881
17882         echo -n "Migrate from MDT$old_index "
17883         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17884         echo -n "to MDT$new_index"
17885         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17886         echo
17887
17888         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17889         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17890                 error "migrate remote dir error"
17891
17892         echo "Finish migration, then checking.."
17893         for file in $(find $migrate_dir); do
17894                 mdt_index=$($LFS getstripe -m $file)
17895                 if [ $mdt_index -lt $new_index ] ||
17896                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17897                         error "$file is on MDT$mdt_index"
17898                 fi
17899         done
17900
17901         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17902 }
17903 run_test 230d "check migrate big directory"
17904
17905 test_230e() {
17906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17908         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17909                 skip "Need MDS version at least 2.11.52"
17910
17911         local i
17912         local j
17913         local a_fid
17914         local b_fid
17915
17916         mkdir -p $DIR/$tdir
17917         mkdir $DIR/$tdir/migrate_dir
17918         mkdir $DIR/$tdir/other_dir
17919         touch $DIR/$tdir/migrate_dir/a
17920         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17921         ls $DIR/$tdir/other_dir
17922
17923         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17924                 error "migrate dir fails"
17925
17926         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17927         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17928
17929         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17930         [ $mdt_index == 0 ] || error "a is not on MDT0"
17931
17932         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17933                 error "migrate dir fails"
17934
17935         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17936         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17937
17938         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17939         [ $mdt_index == 1 ] || error "a is not on MDT1"
17940
17941         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17942         [ $mdt_index == 1 ] || error "b is not on MDT1"
17943
17944         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17945         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17946
17947         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17948
17949         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17950 }
17951 run_test 230e "migrate mulitple local link files"
17952
17953 test_230f() {
17954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17956         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17957                 skip "Need MDS version at least 2.11.52"
17958
17959         local a_fid
17960         local ln_fid
17961
17962         mkdir -p $DIR/$tdir
17963         mkdir $DIR/$tdir/migrate_dir
17964         $LFS mkdir -i1 $DIR/$tdir/other_dir
17965         touch $DIR/$tdir/migrate_dir/a
17966         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17967         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17968         ls $DIR/$tdir/other_dir
17969
17970         # a should be migrated to MDT1, since no other links on MDT0
17971         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17972                 error "#1 migrate dir fails"
17973         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17974         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17975         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17976         [ $mdt_index == 1 ] || error "a is not on MDT1"
17977
17978         # a should stay on MDT1, because it is a mulitple link file
17979         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17980                 error "#2 migrate dir fails"
17981         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17982         [ $mdt_index == 1 ] || error "a is not on MDT1"
17983
17984         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17985                 error "#3 migrate dir fails"
17986
17987         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17988         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17989         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17990
17991         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17992         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17993
17994         # a should be migrated to MDT0, since no other links on MDT1
17995         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17996                 error "#4 migrate dir fails"
17997         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17998         [ $mdt_index == 0 ] || error "a is not on MDT0"
17999
18000         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18001 }
18002 run_test 230f "migrate mulitple remote link files"
18003
18004 test_230g() {
18005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18007         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18008                 skip "Need MDS version at least 2.11.52"
18009
18010         mkdir -p $DIR/$tdir/migrate_dir
18011
18012         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18013                 error "migrating dir to non-exist MDT succeeds"
18014         true
18015 }
18016 run_test 230g "migrate dir to non-exist MDT"
18017
18018 test_230h() {
18019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18021         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18022                 skip "Need MDS version at least 2.11.52"
18023
18024         local mdt_index
18025
18026         mkdir -p $DIR/$tdir/migrate_dir
18027
18028         $LFS migrate -m1 $DIR &&
18029                 error "migrating mountpoint1 should fail"
18030
18031         $LFS migrate -m1 $DIR/$tdir/.. &&
18032                 error "migrating mountpoint2 should fail"
18033
18034         # same as mv
18035         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18036                 error "migrating $tdir/migrate_dir/.. should fail"
18037
18038         true
18039 }
18040 run_test 230h "migrate .. and root"
18041
18042 test_230i() {
18043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18044         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18045         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18046                 skip "Need MDS version at least 2.11.52"
18047
18048         mkdir -p $DIR/$tdir/migrate_dir
18049
18050         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18051                 error "migration fails with a tailing slash"
18052
18053         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18054                 error "migration fails with two tailing slashes"
18055 }
18056 run_test 230i "lfs migrate -m tolerates trailing slashes"
18057
18058 test_230j() {
18059         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18060         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18061                 skip "Need MDS version at least 2.11.52"
18062
18063         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18064         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18065                 error "create $tfile failed"
18066         cat /etc/passwd > $DIR/$tdir/$tfile
18067
18068         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18069
18070         cmp /etc/passwd $DIR/$tdir/$tfile ||
18071                 error "DoM file mismatch after migration"
18072 }
18073 run_test 230j "DoM file data not changed after dir migration"
18074
18075 test_230k() {
18076         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18077         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18078                 skip "Need MDS version at least 2.11.56"
18079
18080         local total=20
18081         local files_on_starting_mdt=0
18082
18083         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18084         $LFS getdirstripe $DIR/$tdir
18085         for i in $(seq $total); do
18086                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18087                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18088                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18089         done
18090
18091         echo "$files_on_starting_mdt files on MDT0"
18092
18093         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18094         $LFS getdirstripe $DIR/$tdir
18095
18096         files_on_starting_mdt=0
18097         for i in $(seq $total); do
18098                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18099                         error "file $tfile.$i mismatch after migration"
18100                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18101                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18102         done
18103
18104         echo "$files_on_starting_mdt files on MDT1 after migration"
18105         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18106
18107         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18108         $LFS getdirstripe $DIR/$tdir
18109
18110         files_on_starting_mdt=0
18111         for i in $(seq $total); do
18112                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18113                         error "file $tfile.$i mismatch after 2nd migration"
18114                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18115                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18116         done
18117
18118         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18119         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18120
18121         true
18122 }
18123 run_test 230k "file data not changed after dir migration"
18124
18125 test_230l() {
18126         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18127         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18128                 skip "Need MDS version at least 2.11.56"
18129
18130         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18131         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18132                 error "create files under remote dir failed $i"
18133         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18134 }
18135 run_test 230l "readdir between MDTs won't crash"
18136
18137 test_230m() {
18138         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18139         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18140                 skip "Need MDS version at least 2.11.56"
18141
18142         local MDTIDX=1
18143         local mig_dir=$DIR/$tdir/migrate_dir
18144         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18145         local shortstr="b"
18146         local val
18147
18148         echo "Creating files and dirs with xattrs"
18149         test_mkdir $DIR/$tdir
18150         test_mkdir -i0 -c1 $mig_dir
18151         mkdir $mig_dir/dir
18152         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18153                 error "cannot set xattr attr1 on dir"
18154         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18155                 error "cannot set xattr attr2 on dir"
18156         touch $mig_dir/dir/f0
18157         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18158                 error "cannot set xattr attr1 on file"
18159         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18160                 error "cannot set xattr attr2 on file"
18161         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18162         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18163         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18164         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18165         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18166         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18167         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18168         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18169         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18170
18171         echo "Migrating to MDT1"
18172         $LFS migrate -m $MDTIDX $mig_dir ||
18173                 error "fails on migrating dir to MDT1"
18174
18175         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18176         echo "Checking xattrs"
18177         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18178         [ "$val" = $longstr ] ||
18179                 error "expecting xattr1 $longstr on dir, found $val"
18180         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18181         [ "$val" = $shortstr ] ||
18182                 error "expecting xattr2 $shortstr on dir, found $val"
18183         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18184         [ "$val" = $longstr ] ||
18185                 error "expecting xattr1 $longstr on file, found $val"
18186         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18187         [ "$val" = $shortstr ] ||
18188                 error "expecting xattr2 $shortstr on file, found $val"
18189 }
18190 run_test 230m "xattrs not changed after dir migration"
18191
18192 test_230n() {
18193         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18194         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18195                 skip "Need MDS version at least 2.13.53"
18196
18197         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18198         cat /etc/hosts > $DIR/$tdir/$tfile
18199         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18200         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18201
18202         cmp /etc/hosts $DIR/$tdir/$tfile ||
18203                 error "File data mismatch after migration"
18204 }
18205 run_test 230n "Dir migration with mirrored file"
18206
18207 test_230o() {
18208         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18209         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18210                 skip "Need MDS version at least 2.13.52"
18211
18212         local mdts=$(comma_list $(mdts_nodes))
18213         local timeout=100
18214
18215         local restripe_status
18216         local delta
18217         local i
18218         local j
18219
18220         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18221
18222         # in case "crush" hash type is not set
18223         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18224
18225         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18226                            mdt.*MDT0000.enable_dir_restripe)
18227         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18228         stack_trap "do_nodes $mdts $LCTL set_param \
18229                     mdt.*.enable_dir_restripe=$restripe_status"
18230
18231         mkdir $DIR/$tdir
18232         createmany -m $DIR/$tdir/f 100 ||
18233                 error "create files under remote dir failed $i"
18234         createmany -d $DIR/$tdir/d 100 ||
18235                 error "create dirs under remote dir failed $i"
18236
18237         for i in $(seq 2 $MDSCOUNT); do
18238                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18239                 $LFS setdirstripe -c $i $DIR/$tdir ||
18240                         error "split -c $i $tdir failed"
18241                 wait_update $HOSTNAME \
18242                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18243                         error "dir split not finished"
18244                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18245                         awk '/migrate/ {sum += $2} END { print sum }')
18246                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18247                 # delta is around total_files/stripe_count
18248                 [ $delta -lt $((200 /(i - 1))) ] ||
18249                         error "$delta files migrated"
18250         done
18251 }
18252 run_test 230o "dir split"
18253
18254 test_230p() {
18255         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18256         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18257                 skip "Need MDS version at least 2.13.52"
18258
18259         local mdts=$(comma_list $(mdts_nodes))
18260         local timeout=100
18261
18262         local restripe_status
18263         local delta
18264         local i
18265         local j
18266
18267         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18268
18269         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18270
18271         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18272                            mdt.*MDT0000.enable_dir_restripe)
18273         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18274         stack_trap "do_nodes $mdts $LCTL set_param \
18275                     mdt.*.enable_dir_restripe=$restripe_status"
18276
18277         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18278         createmany -m $DIR/$tdir/f 100 ||
18279                 error "create files under remote dir failed $i"
18280         createmany -d $DIR/$tdir/d 100 ||
18281                 error "create dirs under remote dir failed $i"
18282
18283         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18284                 local mdt_hash="crush"
18285
18286                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18287                 $LFS setdirstripe -c $i $DIR/$tdir ||
18288                         error "split -c $i $tdir failed"
18289                 [ $i -eq 1 ] && mdt_hash="none"
18290                 wait_update $HOSTNAME \
18291                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18292                         error "dir merge not finished"
18293                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18294                         awk '/migrate/ {sum += $2} END { print sum }')
18295                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18296                 # delta is around total_files/stripe_count
18297                 [ $delta -lt $((200 / i)) ] ||
18298                         error "$delta files migrated"
18299         done
18300 }
18301 run_test 230p "dir merge"
18302
18303 test_230q() {
18304         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18305         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18306                 skip "Need MDS version at least 2.13.52"
18307
18308         local mdts=$(comma_list $(mdts_nodes))
18309         local saved_threshold=$(do_facet mds1 \
18310                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18311         local saved_delta=$(do_facet mds1 \
18312                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18313         local threshold=100
18314         local delta=2
18315         local total=0
18316         local stripe_count=0
18317         local stripe_index
18318         local nr_files
18319
18320         stack_trap "do_nodes $mdts $LCTL set_param \
18321                     mdt.*.dir_split_count=$saved_threshold"
18322         stack_trap "do_nodes $mdts $LCTL set_param \
18323                     mdt.*.dir_split_delta=$saved_delta"
18324         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18325         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18326         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18327         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18328         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18329         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18330
18331         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18332         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18333
18334         while [ $stripe_count -lt $MDSCOUNT ]; do
18335                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18336                         error "create sub files failed"
18337                 stat $DIR/$tdir > /dev/null
18338                 total=$((total + threshold * 3 / 2))
18339                 stripe_count=$((stripe_count + delta))
18340                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18341
18342                 wait_update $HOSTNAME \
18343                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18344                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18345
18346                 wait_update $HOSTNAME \
18347                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18348                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18349
18350                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18351                            grep -w $stripe_index | wc -l)
18352                 echo "$nr_files files on MDT$stripe_index after split"
18353                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18354                         error "$nr_files files on MDT$stripe_index after split"
18355
18356                 nr_files=$(ls $DIR/$tdir | wc -w)
18357                 [ $nr_files -eq $total ] ||
18358                         error "total sub files $nr_files != $total"
18359         done
18360 }
18361 run_test 230q "dir auto split"
18362
18363 test_230r() {
18364         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18365         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18366         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18367                 skip "Need MDS version at least 2.13.54"
18368
18369         # maximum amount of local locks:
18370         # parent striped dir - 2 locks
18371         # new stripe in parent to migrate to - 1 lock
18372         # source and target - 2 locks
18373         # Total 5 locks for regular file
18374         mkdir -p $DIR/$tdir
18375         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18376         touch $DIR/$tdir/dir1/eee
18377
18378         # create 4 hardlink for 4 more locks
18379         # Total: 9 locks > RS_MAX_LOCKS (8)
18380         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18381         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18382         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18383         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18384         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18385         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18386         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18387         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18388
18389         cancel_lru_locks mdc
18390
18391         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18392                 error "migrate dir fails"
18393
18394         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18395 }
18396 run_test 230r "migrate with too many local locks"
18397
18398 test_231a()
18399 {
18400         # For simplicity this test assumes that max_pages_per_rpc
18401         # is the same across all OSCs
18402         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18403         local bulk_size=$((max_pages * PAGE_SIZE))
18404         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18405                                        head -n 1)
18406
18407         mkdir -p $DIR/$tdir
18408         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18409                 error "failed to set stripe with -S ${brw_size}M option"
18410
18411         # clear the OSC stats
18412         $LCTL set_param osc.*.stats=0 &>/dev/null
18413         stop_writeback
18414
18415         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18416         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18417                 oflag=direct &>/dev/null || error "dd failed"
18418
18419         sync; sleep 1; sync # just to be safe
18420         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18421         if [ x$nrpcs != "x1" ]; then
18422                 $LCTL get_param osc.*.stats
18423                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18424         fi
18425
18426         start_writeback
18427         # Drop the OSC cache, otherwise we will read from it
18428         cancel_lru_locks osc
18429
18430         # clear the OSC stats
18431         $LCTL set_param osc.*.stats=0 &>/dev/null
18432
18433         # Client reads $bulk_size.
18434         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18435                 iflag=direct &>/dev/null || error "dd failed"
18436
18437         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18438         if [ x$nrpcs != "x1" ]; then
18439                 $LCTL get_param osc.*.stats
18440                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18441         fi
18442 }
18443 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18444
18445 test_231b() {
18446         mkdir -p $DIR/$tdir
18447         local i
18448         for i in {0..1023}; do
18449                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18450                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18451                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18452         done
18453         sync
18454 }
18455 run_test 231b "must not assert on fully utilized OST request buffer"
18456
18457 test_232a() {
18458         mkdir -p $DIR/$tdir
18459         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18460
18461         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18462         do_facet ost1 $LCTL set_param fail_loc=0x31c
18463
18464         # ignore dd failure
18465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18466
18467         do_facet ost1 $LCTL set_param fail_loc=0
18468         umount_client $MOUNT || error "umount failed"
18469         mount_client $MOUNT || error "mount failed"
18470         stop ost1 || error "cannot stop ost1"
18471         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18472 }
18473 run_test 232a "failed lock should not block umount"
18474
18475 test_232b() {
18476         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18477                 skip "Need MDS version at least 2.10.58"
18478
18479         mkdir -p $DIR/$tdir
18480         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18481         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18482         sync
18483         cancel_lru_locks osc
18484
18485         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18486         do_facet ost1 $LCTL set_param fail_loc=0x31c
18487
18488         # ignore failure
18489         $LFS data_version $DIR/$tdir/$tfile || true
18490
18491         do_facet ost1 $LCTL set_param fail_loc=0
18492         umount_client $MOUNT || error "umount failed"
18493         mount_client $MOUNT || error "mount failed"
18494         stop ost1 || error "cannot stop ost1"
18495         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18496 }
18497 run_test 232b "failed data version lock should not block umount"
18498
18499 test_233a() {
18500         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18501                 skip "Need MDS version at least 2.3.64"
18502         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18503
18504         local fid=$($LFS path2fid $MOUNT)
18505
18506         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18507                 error "cannot access $MOUNT using its FID '$fid'"
18508 }
18509 run_test 233a "checking that OBF of the FS root succeeds"
18510
18511 test_233b() {
18512         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18513                 skip "Need MDS version at least 2.5.90"
18514         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18515
18516         local fid=$($LFS path2fid $MOUNT/.lustre)
18517
18518         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18519                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18520
18521         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18522         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18523                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18524 }
18525 run_test 233b "checking that OBF of the FS .lustre succeeds"
18526
18527 test_234() {
18528         local p="$TMP/sanityN-$TESTNAME.parameters"
18529         save_lustre_params client "llite.*.xattr_cache" > $p
18530         lctl set_param llite.*.xattr_cache 1 ||
18531                 skip_env "xattr cache is not supported"
18532
18533         mkdir -p $DIR/$tdir || error "mkdir failed"
18534         touch $DIR/$tdir/$tfile || error "touch failed"
18535         # OBD_FAIL_LLITE_XATTR_ENOMEM
18536         $LCTL set_param fail_loc=0x1405
18537         getfattr -n user.attr $DIR/$tdir/$tfile &&
18538                 error "getfattr should have failed with ENOMEM"
18539         $LCTL set_param fail_loc=0x0
18540         rm -rf $DIR/$tdir
18541
18542         restore_lustre_params < $p
18543         rm -f $p
18544 }
18545 run_test 234 "xattr cache should not crash on ENOMEM"
18546
18547 test_235() {
18548         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18549                 skip "Need MDS version at least 2.4.52"
18550
18551         flock_deadlock $DIR/$tfile
18552         local RC=$?
18553         case $RC in
18554                 0)
18555                 ;;
18556                 124) error "process hangs on a deadlock"
18557                 ;;
18558                 *) error "error executing flock_deadlock $DIR/$tfile"
18559                 ;;
18560         esac
18561 }
18562 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18563
18564 #LU-2935
18565 test_236() {
18566         check_swap_layouts_support
18567
18568         local ref1=/etc/passwd
18569         local ref2=/etc/group
18570         local file1=$DIR/$tdir/f1
18571         local file2=$DIR/$tdir/f2
18572
18573         test_mkdir -c1 $DIR/$tdir
18574         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18575         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18576         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18577         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18578         local fd=$(free_fd)
18579         local cmd="exec $fd<>$file2"
18580         eval $cmd
18581         rm $file2
18582         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18583                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18584         cmd="exec $fd>&-"
18585         eval $cmd
18586         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18587
18588         #cleanup
18589         rm -rf $DIR/$tdir
18590 }
18591 run_test 236 "Layout swap on open unlinked file"
18592
18593 # LU-4659 linkea consistency
18594 test_238() {
18595         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18596                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18597                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18598                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18599
18600         touch $DIR/$tfile
18601         ln $DIR/$tfile $DIR/$tfile.lnk
18602         touch $DIR/$tfile.new
18603         mv $DIR/$tfile.new $DIR/$tfile
18604         local fid1=$($LFS path2fid $DIR/$tfile)
18605         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18606         local path1=$($LFS fid2path $FSNAME "$fid1")
18607         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18608         local path2=$($LFS fid2path $FSNAME "$fid2")
18609         [ $tfile.lnk == $path2 ] ||
18610                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18611         rm -f $DIR/$tfile*
18612 }
18613 run_test 238 "Verify linkea consistency"
18614
18615 test_239A() { # was test_239
18616         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18617                 skip "Need MDS version at least 2.5.60"
18618
18619         local list=$(comma_list $(mdts_nodes))
18620
18621         mkdir -p $DIR/$tdir
18622         createmany -o $DIR/$tdir/f- 5000
18623         unlinkmany $DIR/$tdir/f- 5000
18624         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18625                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18626         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18627                         osp.*MDT*.sync_in_flight" | calc_sum)
18628         [ "$changes" -eq 0 ] || error "$changes not synced"
18629 }
18630 run_test 239A "osp_sync test"
18631
18632 test_239a() { #LU-5297
18633         remote_mds_nodsh && skip "remote MDS with nodsh"
18634
18635         touch $DIR/$tfile
18636         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18637         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18638         chgrp $RUNAS_GID $DIR/$tfile
18639         wait_delete_completed
18640 }
18641 run_test 239a "process invalid osp sync record correctly"
18642
18643 test_239b() { #LU-5297
18644         remote_mds_nodsh && skip "remote MDS with nodsh"
18645
18646         touch $DIR/$tfile1
18647         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18648         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18649         chgrp $RUNAS_GID $DIR/$tfile1
18650         wait_delete_completed
18651         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18652         touch $DIR/$tfile2
18653         chgrp $RUNAS_GID $DIR/$tfile2
18654         wait_delete_completed
18655 }
18656 run_test 239b "process osp sync record with ENOMEM error correctly"
18657
18658 test_240() {
18659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18660         remote_mds_nodsh && skip "remote MDS with nodsh"
18661
18662         mkdir -p $DIR/$tdir
18663
18664         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18665                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18666         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18667                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18668
18669         umount_client $MOUNT || error "umount failed"
18670         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18671         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18672         mount_client $MOUNT || error "failed to mount client"
18673
18674         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18675         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18676 }
18677 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18678
18679 test_241_bio() {
18680         local count=$1
18681         local bsize=$2
18682
18683         for LOOP in $(seq $count); do
18684                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18685                 cancel_lru_locks $OSC || true
18686         done
18687 }
18688
18689 test_241_dio() {
18690         local count=$1
18691         local bsize=$2
18692
18693         for LOOP in $(seq $1); do
18694                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18695                         2>/dev/null
18696         done
18697 }
18698
18699 test_241a() { # was test_241
18700         local bsize=$PAGE_SIZE
18701
18702         (( bsize < 40960 )) && bsize=40960
18703         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18704         ls -la $DIR/$tfile
18705         cancel_lru_locks $OSC
18706         test_241_bio 1000 $bsize &
18707         PID=$!
18708         test_241_dio 1000 $bsize
18709         wait $PID
18710 }
18711 run_test 241a "bio vs dio"
18712
18713 test_241b() {
18714         local bsize=$PAGE_SIZE
18715
18716         (( bsize < 40960 )) && bsize=40960
18717         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18718         ls -la $DIR/$tfile
18719         test_241_dio 1000 $bsize &
18720         PID=$!
18721         test_241_dio 1000 $bsize
18722         wait $PID
18723 }
18724 run_test 241b "dio vs dio"
18725
18726 test_242() {
18727         remote_mds_nodsh && skip "remote MDS with nodsh"
18728
18729         mkdir -p $DIR/$tdir
18730         touch $DIR/$tdir/$tfile
18731
18732         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18733         do_facet mds1 lctl set_param fail_loc=0x105
18734         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18735
18736         do_facet mds1 lctl set_param fail_loc=0
18737         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18738 }
18739 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18740
18741 test_243()
18742 {
18743         test_mkdir $DIR/$tdir
18744         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18745 }
18746 run_test 243 "various group lock tests"
18747
18748 test_244a()
18749 {
18750         test_mkdir $DIR/$tdir
18751         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18752         sendfile_grouplock $DIR/$tdir/$tfile || \
18753                 error "sendfile+grouplock failed"
18754         rm -rf $DIR/$tdir
18755 }
18756 run_test 244a "sendfile with group lock tests"
18757
18758 test_244b()
18759 {
18760         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18761
18762         local threads=50
18763         local size=$((1024*1024))
18764
18765         test_mkdir $DIR/$tdir
18766         for i in $(seq 1 $threads); do
18767                 local file=$DIR/$tdir/file_$((i / 10))
18768                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18769                 local pids[$i]=$!
18770         done
18771         for i in $(seq 1 $threads); do
18772                 wait ${pids[$i]}
18773         done
18774 }
18775 run_test 244b "multi-threaded write with group lock"
18776
18777 test_245() {
18778         local flagname="multi_mod_rpcs"
18779         local connect_data_name="max_mod_rpcs"
18780         local out
18781
18782         # check if multiple modify RPCs flag is set
18783         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18784                 grep "connect_flags:")
18785         echo "$out"
18786
18787         echo "$out" | grep -qw $flagname
18788         if [ $? -ne 0 ]; then
18789                 echo "connect flag $flagname is not set"
18790                 return
18791         fi
18792
18793         # check if multiple modify RPCs data is set
18794         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18795         echo "$out"
18796
18797         echo "$out" | grep -qw $connect_data_name ||
18798                 error "import should have connect data $connect_data_name"
18799 }
18800 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18801
18802 cleanup_247() {
18803         local submount=$1
18804
18805         trap 0
18806         umount_client $submount
18807         rmdir $submount
18808 }
18809
18810 test_247a() {
18811         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18812                 grep -q subtree ||
18813                 skip_env "Fileset feature is not supported"
18814
18815         local submount=${MOUNT}_$tdir
18816
18817         mkdir $MOUNT/$tdir
18818         mkdir -p $submount || error "mkdir $submount failed"
18819         FILESET="$FILESET/$tdir" mount_client $submount ||
18820                 error "mount $submount failed"
18821         trap "cleanup_247 $submount" EXIT
18822         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18823         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18824                 error "read $MOUNT/$tdir/$tfile failed"
18825         cleanup_247 $submount
18826 }
18827 run_test 247a "mount subdir as fileset"
18828
18829 test_247b() {
18830         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18831                 skip_env "Fileset feature is not supported"
18832
18833         local submount=${MOUNT}_$tdir
18834
18835         rm -rf $MOUNT/$tdir
18836         mkdir -p $submount || error "mkdir $submount failed"
18837         SKIP_FILESET=1
18838         FILESET="$FILESET/$tdir" mount_client $submount &&
18839                 error "mount $submount should fail"
18840         rmdir $submount
18841 }
18842 run_test 247b "mount subdir that dose not exist"
18843
18844 test_247c() {
18845         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18846                 skip_env "Fileset feature is not supported"
18847
18848         local submount=${MOUNT}_$tdir
18849
18850         mkdir -p $MOUNT/$tdir/dir1
18851         mkdir -p $submount || error "mkdir $submount failed"
18852         trap "cleanup_247 $submount" EXIT
18853         FILESET="$FILESET/$tdir" mount_client $submount ||
18854                 error "mount $submount failed"
18855         local fid=$($LFS path2fid $MOUNT/)
18856         $LFS fid2path $submount $fid && error "fid2path should fail"
18857         cleanup_247 $submount
18858 }
18859 run_test 247c "running fid2path outside subdirectory root"
18860
18861 test_247d() {
18862         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18863                 skip "Fileset feature is not supported"
18864
18865         local submount=${MOUNT}_$tdir
18866
18867         mkdir -p $MOUNT/$tdir/dir1
18868         mkdir -p $submount || error "mkdir $submount failed"
18869         FILESET="$FILESET/$tdir" mount_client $submount ||
18870                 error "mount $submount failed"
18871         trap "cleanup_247 $submount" EXIT
18872
18873         local td=$submount/dir1
18874         local fid=$($LFS path2fid $td)
18875         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18876
18877         # check that we get the same pathname back
18878         local rootpath
18879         local found
18880         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18881                 echo "$rootpath $fid"
18882                 found=$($LFS fid2path $rootpath "$fid")
18883                 [ -n "found" ] || error "fid2path should succeed"
18884                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18885         done
18886         # check wrong root path format
18887         rootpath=$submount"_wrong"
18888         found=$($LFS fid2path $rootpath "$fid")
18889         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18890
18891         cleanup_247 $submount
18892 }
18893 run_test 247d "running fid2path inside subdirectory root"
18894
18895 # LU-8037
18896 test_247e() {
18897         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18898                 grep -q subtree ||
18899                 skip "Fileset feature is not supported"
18900
18901         local submount=${MOUNT}_$tdir
18902
18903         mkdir $MOUNT/$tdir
18904         mkdir -p $submount || error "mkdir $submount failed"
18905         FILESET="$FILESET/.." mount_client $submount &&
18906                 error "mount $submount should fail"
18907         rmdir $submount
18908 }
18909 run_test 247e "mount .. as fileset"
18910
18911 test_247f() {
18912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18913         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18914                 skip "Need at least version 2.13.52"
18915         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18916                 grep -q subtree ||
18917                 skip "Fileset feature is not supported"
18918
18919         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18920         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18921                 error "mkdir remote failed"
18922         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18923         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18924                 error "mkdir striped failed"
18925         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18926
18927         local submount=${MOUNT}_$tdir
18928
18929         mkdir -p $submount || error "mkdir $submount failed"
18930
18931         local dir
18932         local fileset=$FILESET
18933
18934         for dir in $tdir/remote $tdir/remote/subdir \
18935                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18936                 FILESET="$fileset/$dir" mount_client $submount ||
18937                         error "mount $dir failed"
18938                 umount_client $submount
18939         done
18940 }
18941 run_test 247f "mount striped or remote directory as fileset"
18942
18943 test_248a() {
18944         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18945         [ -z "$fast_read_sav" ] && skip "no fast read support"
18946
18947         # create a large file for fast read verification
18948         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18949
18950         # make sure the file is created correctly
18951         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18952                 { rm -f $DIR/$tfile; skip "file creation error"; }
18953
18954         echo "Test 1: verify that fast read is 4 times faster on cache read"
18955
18956         # small read with fast read enabled
18957         $LCTL set_param -n llite.*.fast_read=1
18958         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18959                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18960                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18961         # small read with fast read disabled
18962         $LCTL set_param -n llite.*.fast_read=0
18963         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18964                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18965                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18966
18967         # verify that fast read is 4 times faster for cache read
18968         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18969                 error_not_in_vm "fast read was not 4 times faster: " \
18970                            "$t_fast vs $t_slow"
18971
18972         echo "Test 2: verify the performance between big and small read"
18973         $LCTL set_param -n llite.*.fast_read=1
18974
18975         # 1k non-cache read
18976         cancel_lru_locks osc
18977         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18978                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18979                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18980
18981         # 1M non-cache read
18982         cancel_lru_locks osc
18983         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18984                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18985                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18986
18987         # verify that big IO is not 4 times faster than small IO
18988         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18989                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18990
18991         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18992         rm -f $DIR/$tfile
18993 }
18994 run_test 248a "fast read verification"
18995
18996 test_248b() {
18997         # Default short_io_bytes=16384, try both smaller and larger sizes.
18998         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18999         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19000         echo "bs=53248 count=113 normal buffered write"
19001         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19002                 error "dd of initial data file failed"
19003         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19004
19005         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19006         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19007                 error "dd with sync normal writes failed"
19008         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19009
19010         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19011         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19012                 error "dd with sync small writes failed"
19013         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19014
19015         cancel_lru_locks osc
19016
19017         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19018         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19019         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19020         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19021                 iflag=direct || error "dd with O_DIRECT small read failed"
19022         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19023         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19024                 error "compare $TMP/$tfile.1 failed"
19025
19026         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19027         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19028
19029         # just to see what the maximum tunable value is, and test parsing
19030         echo "test invalid parameter 2MB"
19031         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19032                 error "too-large short_io_bytes allowed"
19033         echo "test maximum parameter 512KB"
19034         # if we can set a larger short_io_bytes, run test regardless of version
19035         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19036                 # older clients may not allow setting it this large, that's OK
19037                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19038                         skip "Need at least client version 2.13.50"
19039                 error "medium short_io_bytes failed"
19040         fi
19041         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19042         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19043
19044         echo "test large parameter 64KB"
19045         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19046         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19047
19048         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19049         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19050                 error "dd with sync large writes failed"
19051         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19052
19053         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19054         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19055         num=$((113 * 4096 / PAGE_SIZE))
19056         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19057         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19058                 error "dd with O_DIRECT large writes failed"
19059         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19060                 error "compare $DIR/$tfile.3 failed"
19061
19062         cancel_lru_locks osc
19063
19064         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19065         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19066                 error "dd with O_DIRECT large read failed"
19067         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19068                 error "compare $TMP/$tfile.2 failed"
19069
19070         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19071         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19072                 error "dd with O_DIRECT large read failed"
19073         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19074                 error "compare $TMP/$tfile.3 failed"
19075 }
19076 run_test 248b "test short_io read and write for both small and large sizes"
19077
19078 test_249() { # LU-7890
19079         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19080                 skip "Need at least version 2.8.54"
19081
19082         rm -f $DIR/$tfile
19083         $LFS setstripe -c 1 $DIR/$tfile
19084         # Offset 2T == 4k * 512M
19085         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19086                 error "dd to 2T offset failed"
19087 }
19088 run_test 249 "Write above 2T file size"
19089
19090 test_250() {
19091         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19092          && skip "no 16TB file size limit on ZFS"
19093
19094         $LFS setstripe -c 1 $DIR/$tfile
19095         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19096         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19097         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19098         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19099                 conv=notrunc,fsync && error "append succeeded"
19100         return 0
19101 }
19102 run_test 250 "Write above 16T limit"
19103
19104 test_251() {
19105         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19106
19107         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19108         #Skip once - writing the first stripe will succeed
19109         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19110         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19111                 error "short write happened"
19112
19113         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19114         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19115                 error "short read happened"
19116
19117         rm -f $DIR/$tfile
19118 }
19119 run_test 251 "Handling short read and write correctly"
19120
19121 test_252() {
19122         remote_mds_nodsh && skip "remote MDS with nodsh"
19123         remote_ost_nodsh && skip "remote OST with nodsh"
19124         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19125                 skip_env "ldiskfs only test"
19126         fi
19127
19128         local tgt
19129         local dev
19130         local out
19131         local uuid
19132         local num
19133         local gen
19134
19135         # check lr_reader on OST0000
19136         tgt=ost1
19137         dev=$(facet_device $tgt)
19138         out=$(do_facet $tgt $LR_READER $dev)
19139         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19140         echo "$out"
19141         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19142         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19143                 error "Invalid uuid returned by $LR_READER on target $tgt"
19144         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19145
19146         # check lr_reader -c on MDT0000
19147         tgt=mds1
19148         dev=$(facet_device $tgt)
19149         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19150                 skip "$LR_READER does not support additional options"
19151         fi
19152         out=$(do_facet $tgt $LR_READER -c $dev)
19153         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19154         echo "$out"
19155         num=$(echo "$out" | grep -c "mdtlov")
19156         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19157                 error "Invalid number of mdtlov clients returned by $LR_READER"
19158         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19159
19160         # check lr_reader -cr on MDT0000
19161         out=$(do_facet $tgt $LR_READER -cr $dev)
19162         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19163         echo "$out"
19164         echo "$out" | grep -q "^reply_data:$" ||
19165                 error "$LR_READER should have returned 'reply_data' section"
19166         num=$(echo "$out" | grep -c "client_generation")
19167         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19168 }
19169 run_test 252 "check lr_reader tool"
19170
19171 test_253() {
19172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19173         remote_mds_nodsh && skip "remote MDS with nodsh"
19174         remote_mgs_nodsh && skip "remote MGS with nodsh"
19175
19176         local ostidx=0
19177         local rc=0
19178         local ost_name=$(ostname_from_index $ostidx)
19179
19180         # on the mdt's osc
19181         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19182         do_facet $SINGLEMDS $LCTL get_param -n \
19183                 osp.$mdtosc_proc1.reserved_mb_high ||
19184                 skip  "remote MDS does not support reserved_mb_high"
19185
19186         rm -rf $DIR/$tdir
19187         wait_mds_ost_sync
19188         wait_delete_completed
19189         mkdir $DIR/$tdir
19190
19191         pool_add $TESTNAME || error "Pool creation failed"
19192         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19193
19194         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19195                 error "Setstripe failed"
19196
19197         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19198
19199         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19200                     grep "watermarks")
19201         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19202
19203         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19204                         osp.$mdtosc_proc1.prealloc_status)
19205         echo "prealloc_status $oa_status"
19206
19207         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19208                 error "File creation should fail"
19209
19210         #object allocation was stopped, but we still able to append files
19211         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19212                 oflag=append || error "Append failed"
19213
19214         rm -f $DIR/$tdir/$tfile.0
19215
19216         # For this test, we want to delete the files we created to go out of
19217         # space but leave the watermark, so we remain nearly out of space
19218         ost_watermarks_enospc_delete_files $tfile $ostidx
19219
19220         wait_delete_completed
19221
19222         sleep_maxage
19223
19224         for i in $(seq 10 12); do
19225                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19226                         2>/dev/null || error "File creation failed after rm"
19227         done
19228
19229         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19230                         osp.$mdtosc_proc1.prealloc_status)
19231         echo "prealloc_status $oa_status"
19232
19233         if (( oa_status != 0 )); then
19234                 error "Object allocation still disable after rm"
19235         fi
19236 }
19237 run_test 253 "Check object allocation limit"
19238
19239 test_254() {
19240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19241         remote_mds_nodsh && skip "remote MDS with nodsh"
19242         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19243                 skip "MDS does not support changelog_size"
19244
19245         local cl_user
19246         local MDT0=$(facet_svc $SINGLEMDS)
19247
19248         changelog_register || error "changelog_register failed"
19249
19250         changelog_clear 0 || error "changelog_clear failed"
19251
19252         local size1=$(do_facet $SINGLEMDS \
19253                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19254         echo "Changelog size $size1"
19255
19256         rm -rf $DIR/$tdir
19257         $LFS mkdir -i 0 $DIR/$tdir
19258         # change something
19259         mkdir -p $DIR/$tdir/pics/2008/zachy
19260         touch $DIR/$tdir/pics/2008/zachy/timestamp
19261         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19262         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19263         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19264         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19265         rm $DIR/$tdir/pics/desktop.jpg
19266
19267         local size2=$(do_facet $SINGLEMDS \
19268                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19269         echo "Changelog size after work $size2"
19270
19271         (( $size2 > $size1 )) ||
19272                 error "new Changelog size=$size2 less than old size=$size1"
19273 }
19274 run_test 254 "Check changelog size"
19275
19276 ladvise_no_type()
19277 {
19278         local type=$1
19279         local file=$2
19280
19281         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19282                 awk -F: '{print $2}' | grep $type > /dev/null
19283         if [ $? -ne 0 ]; then
19284                 return 0
19285         fi
19286         return 1
19287 }
19288
19289 ladvise_no_ioctl()
19290 {
19291         local file=$1
19292
19293         lfs ladvise -a willread $file > /dev/null 2>&1
19294         if [ $? -eq 0 ]; then
19295                 return 1
19296         fi
19297
19298         lfs ladvise -a willread $file 2>&1 |
19299                 grep "Inappropriate ioctl for device" > /dev/null
19300         if [ $? -eq 0 ]; then
19301                 return 0
19302         fi
19303         return 1
19304 }
19305
19306 percent() {
19307         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19308 }
19309
19310 # run a random read IO workload
19311 # usage: random_read_iops <filename> <filesize> <iosize>
19312 random_read_iops() {
19313         local file=$1
19314         local fsize=$2
19315         local iosize=${3:-4096}
19316
19317         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19318                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19319 }
19320
19321 drop_file_oss_cache() {
19322         local file="$1"
19323         local nodes="$2"
19324
19325         $LFS ladvise -a dontneed $file 2>/dev/null ||
19326                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19327 }
19328
19329 ladvise_willread_performance()
19330 {
19331         local repeat=10
19332         local average_origin=0
19333         local average_cache=0
19334         local average_ladvise=0
19335
19336         for ((i = 1; i <= $repeat; i++)); do
19337                 echo "Iter $i/$repeat: reading without willread hint"
19338                 cancel_lru_locks osc
19339                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19340                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19341                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19342                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19343
19344                 cancel_lru_locks osc
19345                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19346                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19347                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19348
19349                 cancel_lru_locks osc
19350                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19351                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19352                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19353                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19354                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19355         done
19356         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19357         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19358         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19359
19360         speedup_cache=$(percent $average_cache $average_origin)
19361         speedup_ladvise=$(percent $average_ladvise $average_origin)
19362
19363         echo "Average uncached read: $average_origin"
19364         echo "Average speedup with OSS cached read: " \
19365                 "$average_cache = +$speedup_cache%"
19366         echo "Average speedup with ladvise willread: " \
19367                 "$average_ladvise = +$speedup_ladvise%"
19368
19369         local lowest_speedup=20
19370         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19371                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19372                         "got $average_cache%. Skipping ladvise willread check."
19373                 return 0
19374         fi
19375
19376         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19377         # it is still good to run until then to exercise 'ladvise willread'
19378         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19379                 [ "$ost1_FSTYPE" = "zfs" ] &&
19380                 echo "osd-zfs does not support dontneed or drop_caches" &&
19381                 return 0
19382
19383         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19384         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19385                 error_not_in_vm "Speedup with willread is less than " \
19386                         "$lowest_speedup%, got $average_ladvise%"
19387 }
19388
19389 test_255a() {
19390         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19391                 skip "lustre < 2.8.54 does not support ladvise "
19392         remote_ost_nodsh && skip "remote OST with nodsh"
19393
19394         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19395
19396         ladvise_no_type willread $DIR/$tfile &&
19397                 skip "willread ladvise is not supported"
19398
19399         ladvise_no_ioctl $DIR/$tfile &&
19400                 skip "ladvise ioctl is not supported"
19401
19402         local size_mb=100
19403         local size=$((size_mb * 1048576))
19404         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19405                 error "dd to $DIR/$tfile failed"
19406
19407         lfs ladvise -a willread $DIR/$tfile ||
19408                 error "Ladvise failed with no range argument"
19409
19410         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19411                 error "Ladvise failed with no -l or -e argument"
19412
19413         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19414                 error "Ladvise failed with only -e argument"
19415
19416         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19417                 error "Ladvise failed with only -l argument"
19418
19419         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19420                 error "End offset should not be smaller than start offset"
19421
19422         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19423                 error "End offset should not be equal to start offset"
19424
19425         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19426                 error "Ladvise failed with overflowing -s argument"
19427
19428         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19429                 error "Ladvise failed with overflowing -e argument"
19430
19431         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19432                 error "Ladvise failed with overflowing -l argument"
19433
19434         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19435                 error "Ladvise succeeded with conflicting -l and -e arguments"
19436
19437         echo "Synchronous ladvise should wait"
19438         local delay=4
19439 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19440         do_nodes $(comma_list $(osts_nodes)) \
19441                 $LCTL set_param fail_val=$delay fail_loc=0x237
19442
19443         local start_ts=$SECONDS
19444         lfs ladvise -a willread $DIR/$tfile ||
19445                 error "Ladvise failed with no range argument"
19446         local end_ts=$SECONDS
19447         local inteval_ts=$((end_ts - start_ts))
19448
19449         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19450                 error "Synchronous advice didn't wait reply"
19451         fi
19452
19453         echo "Asynchronous ladvise shouldn't wait"
19454         local start_ts=$SECONDS
19455         lfs ladvise -a willread -b $DIR/$tfile ||
19456                 error "Ladvise failed with no range argument"
19457         local end_ts=$SECONDS
19458         local inteval_ts=$((end_ts - start_ts))
19459
19460         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19461                 error "Asynchronous advice blocked"
19462         fi
19463
19464         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19465         ladvise_willread_performance
19466 }
19467 run_test 255a "check 'lfs ladvise -a willread'"
19468
19469 facet_meminfo() {
19470         local facet=$1
19471         local info=$2
19472
19473         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19474 }
19475
19476 test_255b() {
19477         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19478                 skip "lustre < 2.8.54 does not support ladvise "
19479         remote_ost_nodsh && skip "remote OST with nodsh"
19480
19481         lfs setstripe -c 1 -i 0 $DIR/$tfile
19482
19483         ladvise_no_type dontneed $DIR/$tfile &&
19484                 skip "dontneed ladvise is not supported"
19485
19486         ladvise_no_ioctl $DIR/$tfile &&
19487                 skip "ladvise ioctl is not supported"
19488
19489         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19490                 [ "$ost1_FSTYPE" = "zfs" ] &&
19491                 skip "zfs-osd does not support 'ladvise dontneed'"
19492
19493         local size_mb=100
19494         local size=$((size_mb * 1048576))
19495         # In order to prevent disturbance of other processes, only check 3/4
19496         # of the memory usage
19497         local kibibytes=$((size_mb * 1024 * 3 / 4))
19498
19499         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19500                 error "dd to $DIR/$tfile failed"
19501
19502         #force write to complete before dropping OST cache & checking memory
19503         sync
19504
19505         local total=$(facet_meminfo ost1 MemTotal)
19506         echo "Total memory: $total KiB"
19507
19508         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19509         local before_read=$(facet_meminfo ost1 Cached)
19510         echo "Cache used before read: $before_read KiB"
19511
19512         lfs ladvise -a willread $DIR/$tfile ||
19513                 error "Ladvise willread failed"
19514         local after_read=$(facet_meminfo ost1 Cached)
19515         echo "Cache used after read: $after_read KiB"
19516
19517         lfs ladvise -a dontneed $DIR/$tfile ||
19518                 error "Ladvise dontneed again failed"
19519         local no_read=$(facet_meminfo ost1 Cached)
19520         echo "Cache used after dontneed ladvise: $no_read KiB"
19521
19522         if [ $total -lt $((before_read + kibibytes)) ]; then
19523                 echo "Memory is too small, abort checking"
19524                 return 0
19525         fi
19526
19527         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19528                 error "Ladvise willread should use more memory" \
19529                         "than $kibibytes KiB"
19530         fi
19531
19532         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19533                 error "Ladvise dontneed should release more memory" \
19534                         "than $kibibytes KiB"
19535         fi
19536 }
19537 run_test 255b "check 'lfs ladvise -a dontneed'"
19538
19539 test_255c() {
19540         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19541                 skip "lustre < 2.10.50 does not support lockahead"
19542
19543         local count
19544         local new_count
19545         local difference
19546         local i
19547         local rc
19548
19549         test_mkdir -p $DIR/$tdir
19550         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19551
19552         #test 10 returns only success/failure
19553         i=10
19554         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19555         rc=$?
19556         if [ $rc -eq 255 ]; then
19557                 error "Ladvise test${i} failed, ${rc}"
19558         fi
19559
19560         #test 11 counts lock enqueue requests, all others count new locks
19561         i=11
19562         count=$(do_facet ost1 \
19563                 $LCTL get_param -n ost.OSS.ost.stats)
19564         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19565
19566         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19567         rc=$?
19568         if [ $rc -eq 255 ]; then
19569                 error "Ladvise test${i} failed, ${rc}"
19570         fi
19571
19572         new_count=$(do_facet ost1 \
19573                 $LCTL get_param -n ost.OSS.ost.stats)
19574         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19575                    awk '{ print $2 }')
19576
19577         difference="$((new_count - count))"
19578         if [ $difference -ne $rc ]; then
19579                 error "Ladvise test${i}, bad enqueue count, returned " \
19580                       "${rc}, actual ${difference}"
19581         fi
19582
19583         for i in $(seq 12 21); do
19584                 # If we do not do this, we run the risk of having too many
19585                 # locks and starting lock cancellation while we are checking
19586                 # lock counts.
19587                 cancel_lru_locks osc
19588
19589                 count=$($LCTL get_param -n \
19590                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19591
19592                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19593                 rc=$?
19594                 if [ $rc -eq 255 ]; then
19595                         error "Ladvise test ${i} failed, ${rc}"
19596                 fi
19597
19598                 new_count=$($LCTL get_param -n \
19599                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19600                 difference="$((new_count - count))"
19601
19602                 # Test 15 output is divided by 100 to map down to valid return
19603                 if [ $i -eq 15 ]; then
19604                         rc="$((rc * 100))"
19605                 fi
19606
19607                 if [ $difference -ne $rc ]; then
19608                         error "Ladvise test ${i}, bad lock count, returned " \
19609                               "${rc}, actual ${difference}"
19610                 fi
19611         done
19612
19613         #test 22 returns only success/failure
19614         i=22
19615         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19616         rc=$?
19617         if [ $rc -eq 255 ]; then
19618                 error "Ladvise test${i} failed, ${rc}"
19619         fi
19620 }
19621 run_test 255c "suite of ladvise lockahead tests"
19622
19623 test_256() {
19624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19625         remote_mds_nodsh && skip "remote MDS with nodsh"
19626         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19627         changelog_users $SINGLEMDS | grep "^cl" &&
19628                 skip "active changelog user"
19629
19630         local cl_user
19631         local cat_sl
19632         local mdt_dev
19633
19634         mdt_dev=$(mdsdevname 1)
19635         echo $mdt_dev
19636
19637         changelog_register || error "changelog_register failed"
19638
19639         rm -rf $DIR/$tdir
19640         mkdir -p $DIR/$tdir
19641
19642         changelog_clear 0 || error "changelog_clear failed"
19643
19644         # change something
19645         touch $DIR/$tdir/{1..10}
19646
19647         # stop the MDT
19648         stop $SINGLEMDS || error "Fail to stop MDT"
19649
19650         # remount the MDT
19651
19652         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19653
19654         #after mount new plainllog is used
19655         touch $DIR/$tdir/{11..19}
19656         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19657         stack_trap "rm -f $tmpfile"
19658         cat_sl=$(do_facet $SINGLEMDS "sync; \
19659                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19660                  llog_reader $tmpfile | grep -c type=1064553b")
19661         do_facet $SINGLEMDS llog_reader $tmpfile
19662
19663         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19664
19665         changelog_clear 0 || error "changelog_clear failed"
19666
19667         cat_sl=$(do_facet $SINGLEMDS "sync; \
19668                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19669                  llog_reader $tmpfile | grep -c type=1064553b")
19670
19671         if (( cat_sl == 2 )); then
19672                 error "Empty plain llog was not deleted from changelog catalog"
19673         elif (( cat_sl != 1 )); then
19674                 error "Active plain llog shouldn't be deleted from catalog"
19675         fi
19676 }
19677 run_test 256 "Check llog delete for empty and not full state"
19678
19679 test_257() {
19680         remote_mds_nodsh && skip "remote MDS with nodsh"
19681         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19682                 skip "Need MDS version at least 2.8.55"
19683
19684         test_mkdir $DIR/$tdir
19685
19686         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19687                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19688         stat $DIR/$tdir
19689
19690 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19691         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19692         local facet=mds$((mdtidx + 1))
19693         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19694         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19695
19696         stop $facet || error "stop MDS failed"
19697         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19698                 error "start MDS fail"
19699         wait_recovery_complete $facet
19700 }
19701 run_test 257 "xattr locks are not lost"
19702
19703 # Verify we take the i_mutex when security requires it
19704 test_258a() {
19705 #define OBD_FAIL_IMUTEX_SEC 0x141c
19706         $LCTL set_param fail_loc=0x141c
19707         touch $DIR/$tfile
19708         chmod u+s $DIR/$tfile
19709         chmod a+rwx $DIR/$tfile
19710         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19711         RC=$?
19712         if [ $RC -ne 0 ]; then
19713                 error "error, failed to take i_mutex, rc=$?"
19714         fi
19715         rm -f $DIR/$tfile
19716 }
19717 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19718
19719 # Verify we do NOT take the i_mutex in the normal case
19720 test_258b() {
19721 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19722         $LCTL set_param fail_loc=0x141d
19723         touch $DIR/$tfile
19724         chmod a+rwx $DIR
19725         chmod a+rw $DIR/$tfile
19726         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19727         RC=$?
19728         if [ $RC -ne 0 ]; then
19729                 error "error, took i_mutex unnecessarily, rc=$?"
19730         fi
19731         rm -f $DIR/$tfile
19732
19733 }
19734 run_test 258b "verify i_mutex security behavior"
19735
19736 test_259() {
19737         local file=$DIR/$tfile
19738         local before
19739         local after
19740
19741         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19742
19743         stack_trap "rm -f $file" EXIT
19744
19745         wait_delete_completed
19746         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19747         echo "before: $before"
19748
19749         $LFS setstripe -i 0 -c 1 $file
19750         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19751         sync_all_data
19752         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19753         echo "after write: $after"
19754
19755 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19756         do_facet ost1 $LCTL set_param fail_loc=0x2301
19757         $TRUNCATE $file 0
19758         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19759         echo "after truncate: $after"
19760
19761         stop ost1
19762         do_facet ost1 $LCTL set_param fail_loc=0
19763         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19764         sleep 2
19765         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19766         echo "after restart: $after"
19767         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19768                 error "missing truncate?"
19769
19770         return 0
19771 }
19772 run_test 259 "crash at delayed truncate"
19773
19774 test_260() {
19775 #define OBD_FAIL_MDC_CLOSE               0x806
19776         $LCTL set_param fail_loc=0x80000806
19777         touch $DIR/$tfile
19778
19779 }
19780 run_test 260 "Check mdc_close fail"
19781
19782 ### Data-on-MDT sanity tests ###
19783 test_270a() {
19784         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19785                 skip "Need MDS version at least 2.10.55 for DoM"
19786
19787         # create DoM file
19788         local dom=$DIR/$tdir/dom_file
19789         local tmp=$DIR/$tdir/tmp_file
19790
19791         mkdir -p $DIR/$tdir
19792
19793         # basic checks for DoM component creation
19794         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19795                 error "Can set MDT layout to non-first entry"
19796
19797         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19798                 error "Can define multiple entries as MDT layout"
19799
19800         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19801
19802         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19803         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19804         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19805
19806         local mdtidx=$($LFS getstripe -m $dom)
19807         local mdtname=MDT$(printf %04x $mdtidx)
19808         local facet=mds$((mdtidx + 1))
19809         local space_check=1
19810
19811         # Skip free space checks with ZFS
19812         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19813
19814         # write
19815         sync
19816         local size_tmp=$((65536 * 3))
19817         local mdtfree1=$(do_facet $facet \
19818                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19819
19820         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19821         # check also direct IO along write
19822         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19823         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19824         sync
19825         cmp $tmp $dom || error "file data is different"
19826         [ $(stat -c%s $dom) == $size_tmp ] ||
19827                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19828         if [ $space_check == 1 ]; then
19829                 local mdtfree2=$(do_facet $facet \
19830                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19831
19832                 # increase in usage from by $size_tmp
19833                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19834                         error "MDT free space wrong after write: " \
19835                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19836         fi
19837
19838         # truncate
19839         local size_dom=10000
19840
19841         $TRUNCATE $dom $size_dom
19842         [ $(stat -c%s $dom) == $size_dom ] ||
19843                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19844         if [ $space_check == 1 ]; then
19845                 mdtfree1=$(do_facet $facet \
19846                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19847                 # decrease in usage from $size_tmp to new $size_dom
19848                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19849                   $(((size_tmp - size_dom) / 1024)) ] ||
19850                         error "MDT free space is wrong after truncate: " \
19851                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19852         fi
19853
19854         # append
19855         cat $tmp >> $dom
19856         sync
19857         size_dom=$((size_dom + size_tmp))
19858         [ $(stat -c%s $dom) == $size_dom ] ||
19859                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19860         if [ $space_check == 1 ]; then
19861                 mdtfree2=$(do_facet $facet \
19862                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19863                 # increase in usage by $size_tmp from previous
19864                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19865                         error "MDT free space is wrong after append: " \
19866                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19867         fi
19868
19869         # delete
19870         rm $dom
19871         if [ $space_check == 1 ]; then
19872                 mdtfree1=$(do_facet $facet \
19873                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19874                 # decrease in usage by $size_dom from previous
19875                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19876                         error "MDT free space is wrong after removal: " \
19877                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19878         fi
19879
19880         # combined striping
19881         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19882                 error "Can't create DoM + OST striping"
19883
19884         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19885         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19886         # check also direct IO along write
19887         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19888         sync
19889         cmp $tmp $dom || error "file data is different"
19890         [ $(stat -c%s $dom) == $size_tmp ] ||
19891                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19892         rm $dom $tmp
19893
19894         return 0
19895 }
19896 run_test 270a "DoM: basic functionality tests"
19897
19898 test_270b() {
19899         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19900                 skip "Need MDS version at least 2.10.55"
19901
19902         local dom=$DIR/$tdir/dom_file
19903         local max_size=1048576
19904
19905         mkdir -p $DIR/$tdir
19906         $LFS setstripe -E $max_size -L mdt $dom
19907
19908         # truncate over the limit
19909         $TRUNCATE $dom $(($max_size + 1)) &&
19910                 error "successful truncate over the maximum size"
19911         # write over the limit
19912         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19913                 error "successful write over the maximum size"
19914         # append over the limit
19915         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19916         echo "12345" >> $dom && error "successful append over the maximum size"
19917         rm $dom
19918
19919         return 0
19920 }
19921 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19922
19923 test_270c() {
19924         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19925                 skip "Need MDS version at least 2.10.55"
19926
19927         mkdir -p $DIR/$tdir
19928         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19929
19930         # check files inherit DoM EA
19931         touch $DIR/$tdir/first
19932         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19933                 error "bad pattern"
19934         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19935                 error "bad stripe count"
19936         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19937                 error "bad stripe size"
19938
19939         # check directory inherits DoM EA and uses it as default
19940         mkdir $DIR/$tdir/subdir
19941         touch $DIR/$tdir/subdir/second
19942         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19943                 error "bad pattern in sub-directory"
19944         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19945                 error "bad stripe count in sub-directory"
19946         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19947                 error "bad stripe size in sub-directory"
19948         return 0
19949 }
19950 run_test 270c "DoM: DoM EA inheritance tests"
19951
19952 test_270d() {
19953         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19954                 skip "Need MDS version at least 2.10.55"
19955
19956         mkdir -p $DIR/$tdir
19957         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19958
19959         # inherit default DoM striping
19960         mkdir $DIR/$tdir/subdir
19961         touch $DIR/$tdir/subdir/f1
19962
19963         # change default directory striping
19964         $LFS setstripe -c 1 $DIR/$tdir/subdir
19965         touch $DIR/$tdir/subdir/f2
19966         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19967                 error "wrong default striping in file 2"
19968         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19969                 error "bad pattern in file 2"
19970         return 0
19971 }
19972 run_test 270d "DoM: change striping from DoM to RAID0"
19973
19974 test_270e() {
19975         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19976                 skip "Need MDS version at least 2.10.55"
19977
19978         mkdir -p $DIR/$tdir/dom
19979         mkdir -p $DIR/$tdir/norm
19980         DOMFILES=20
19981         NORMFILES=10
19982         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19983         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19984
19985         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19986         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19987
19988         # find DoM files by layout
19989         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19990         [ $NUM -eq  $DOMFILES ] ||
19991                 error "lfs find -L: found $NUM, expected $DOMFILES"
19992         echo "Test 1: lfs find 20 DOM files by layout: OK"
19993
19994         # there should be 1 dir with default DOM striping
19995         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19996         [ $NUM -eq  1 ] ||
19997                 error "lfs find -L: found $NUM, expected 1 dir"
19998         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19999
20000         # find DoM files by stripe size
20001         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20002         [ $NUM -eq  $DOMFILES ] ||
20003                 error "lfs find -S: found $NUM, expected $DOMFILES"
20004         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20005
20006         # find files by stripe offset except DoM files
20007         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20008         [ $NUM -eq  $NORMFILES ] ||
20009                 error "lfs find -i: found $NUM, expected $NORMFILES"
20010         echo "Test 5: lfs find no DOM files by stripe index: OK"
20011         return 0
20012 }
20013 run_test 270e "DoM: lfs find with DoM files test"
20014
20015 test_270f() {
20016         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20017                 skip "Need MDS version at least 2.10.55"
20018
20019         local mdtname=${FSNAME}-MDT0000-mdtlov
20020         local dom=$DIR/$tdir/dom_file
20021         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20022                                                 lod.$mdtname.dom_stripesize)
20023         local dom_limit=131072
20024
20025         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20026         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20027                                                 lod.$mdtname.dom_stripesize)
20028         [ ${dom_limit} -eq ${dom_current} ] ||
20029                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20030
20031         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20032         $LFS setstripe -d $DIR/$tdir
20033         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20034                 error "Can't set directory default striping"
20035
20036         # exceed maximum stripe size
20037         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20038                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20039         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20040                 error "Able to create DoM component size more than LOD limit"
20041
20042         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20043         dom_current=$(do_facet mds1 $LCTL get_param -n \
20044                                                 lod.$mdtname.dom_stripesize)
20045         [ 0 -eq ${dom_current} ] ||
20046                 error "Can't set zero DoM stripe limit"
20047         rm $dom
20048
20049         # attempt to create DoM file on server with disabled DoM should
20050         # remove DoM entry from layout and be succeed
20051         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20052                 error "Can't create DoM file (DoM is disabled)"
20053         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20054                 error "File has DoM component while DoM is disabled"
20055         rm $dom
20056
20057         # attempt to create DoM file with only DoM stripe should return error
20058         $LFS setstripe -E $dom_limit -L mdt $dom &&
20059                 error "Able to create DoM-only file while DoM is disabled"
20060
20061         # too low values to be aligned with smallest stripe size 64K
20062         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20063         dom_current=$(do_facet mds1 $LCTL get_param -n \
20064                                                 lod.$mdtname.dom_stripesize)
20065         [ 30000 -eq ${dom_current} ] &&
20066                 error "Can set too small DoM stripe limit"
20067
20068         # 64K is a minimal stripe size in Lustre, expect limit of that size
20069         [ 65536 -eq ${dom_current} ] ||
20070                 error "Limit is not set to 64K but ${dom_current}"
20071
20072         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20073         dom_current=$(do_facet mds1 $LCTL get_param -n \
20074                                                 lod.$mdtname.dom_stripesize)
20075         echo $dom_current
20076         [ 2147483648 -eq ${dom_current} ] &&
20077                 error "Can set too large DoM stripe limit"
20078
20079         do_facet mds1 $LCTL set_param -n \
20080                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20081         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20082                 error "Can't create DoM component size after limit change"
20083         do_facet mds1 $LCTL set_param -n \
20084                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20085         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20086                 error "Can't create DoM file after limit decrease"
20087         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20088                 error "Can create big DoM component after limit decrease"
20089         touch ${dom}_def ||
20090                 error "Can't create file with old default layout"
20091
20092         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20093         return 0
20094 }
20095 run_test 270f "DoM: maximum DoM stripe size checks"
20096
20097 test_270g() {
20098         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20099                 skip "Need MDS version at least 2.13.52"
20100         local dom=$DIR/$tdir/$tfile
20101
20102         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20103         local lodname=${FSNAME}-MDT0000-mdtlov
20104
20105         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20106         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20107         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20108         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20109
20110         local dom_limit=1024
20111         local dom_threshold="50%"
20112
20113         $LFS setstripe -d $DIR/$tdir
20114         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20115                 error "Can't set directory default striping"
20116
20117         do_facet mds1 $LCTL set_param -n \
20118                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20119         # set 0 threshold and create DOM file to change tunable stripesize
20120         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20121         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20122                 error "Failed to create $dom file"
20123         # now tunable dom_cur_stripesize should reach maximum
20124         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20125                                         lod.${lodname}.dom_stripesize_cur_kb)
20126         [[ $dom_current == $dom_limit ]] ||
20127                 error "Current DOM stripesize is not maximum"
20128         rm $dom
20129
20130         # set threshold for further tests
20131         do_facet mds1 $LCTL set_param -n \
20132                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20133         echo "DOM threshold is $dom_threshold free space"
20134         local dom_def
20135         local dom_set
20136         # Spoof bfree to exceed threshold
20137         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20138         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20139         for spfree in 40 20 0 15 30 55; do
20140                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20141                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20142                         error "Failed to create $dom file"
20143                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20144                                         lod.${lodname}.dom_stripesize_cur_kb)
20145                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20146                 [[ $dom_def != $dom_current ]] ||
20147                         error "Default stripe size was not changed"
20148                 if [[ $spfree > 0 ]] ; then
20149                         dom_set=$($LFS getstripe -S $dom)
20150                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20151                                 error "DOM component size is still old"
20152                 else
20153                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20154                                 error "DoM component is set with no free space"
20155                 fi
20156                 rm $dom
20157                 dom_current=$dom_def
20158         done
20159 }
20160 run_test 270g "DoM: default DoM stripe size depends on free space"
20161
20162 test_270h() {
20163         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20164                 skip "Need MDS version at least 2.13.53"
20165
20166         local mdtname=${FSNAME}-MDT0000-mdtlov
20167         local dom=$DIR/$tdir/$tfile
20168         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20169
20170         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20171         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20172
20173         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20174         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20175                 error "can't create OST file"
20176         # mirrored file with DOM entry in the second mirror
20177         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20178                 error "can't create mirror with DoM component"
20179
20180         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20181
20182         # DOM component in the middle and has other enries in the same mirror,
20183         # should succeed but lost DoM component
20184         $LFS setstripe --copy=${dom}_1 $dom ||
20185                 error "Can't create file from OST|DOM mirror layout"
20186         # check new file has no DoM layout after all
20187         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20188                 error "File has DoM component while DoM is disabled"
20189 }
20190 run_test 270h "DoM: DoM stripe removal when disabled on server"
20191
20192 test_271a() {
20193         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20194                 skip "Need MDS version at least 2.10.55"
20195
20196         local dom=$DIR/$tdir/dom
20197
20198         mkdir -p $DIR/$tdir
20199
20200         $LFS setstripe -E 1024K -L mdt $dom
20201
20202         lctl set_param -n mdc.*.stats=clear
20203         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20204         cat $dom > /dev/null
20205         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20206         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20207         ls $dom
20208         rm -f $dom
20209 }
20210 run_test 271a "DoM: data is cached for read after write"
20211
20212 test_271b() {
20213         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20214                 skip "Need MDS version at least 2.10.55"
20215
20216         local dom=$DIR/$tdir/dom
20217
20218         mkdir -p $DIR/$tdir
20219
20220         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20221
20222         lctl set_param -n mdc.*.stats=clear
20223         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20224         cancel_lru_locks mdc
20225         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20226         # second stat to check size is cached on client
20227         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20228         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20229         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20230         rm -f $dom
20231 }
20232 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20233
20234 test_271ba() {
20235         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20236                 skip "Need MDS version at least 2.10.55"
20237
20238         local dom=$DIR/$tdir/dom
20239
20240         mkdir -p $DIR/$tdir
20241
20242         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20243
20244         lctl set_param -n mdc.*.stats=clear
20245         lctl set_param -n osc.*.stats=clear
20246         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20247         cancel_lru_locks mdc
20248         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20249         # second stat to check size is cached on client
20250         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20251         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20252         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20253         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20254         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20255         rm -f $dom
20256 }
20257 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20258
20259
20260 get_mdc_stats() {
20261         local mdtidx=$1
20262         local param=$2
20263         local mdt=MDT$(printf %04x $mdtidx)
20264
20265         if [ -z $param ]; then
20266                 lctl get_param -n mdc.*$mdt*.stats
20267         else
20268                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20269         fi
20270 }
20271
20272 test_271c() {
20273         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20274                 skip "Need MDS version at least 2.10.55"
20275
20276         local dom=$DIR/$tdir/dom
20277
20278         mkdir -p $DIR/$tdir
20279
20280         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20281
20282         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20283         local facet=mds$((mdtidx + 1))
20284
20285         cancel_lru_locks mdc
20286         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20287         createmany -o $dom 1000
20288         lctl set_param -n mdc.*.stats=clear
20289         smalliomany -w $dom 1000 200
20290         get_mdc_stats $mdtidx
20291         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20292         # Each file has 1 open, 1 IO enqueues, total 2000
20293         # but now we have also +1 getxattr for security.capability, total 3000
20294         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20295         unlinkmany $dom 1000
20296
20297         cancel_lru_locks mdc
20298         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20299         createmany -o $dom 1000
20300         lctl set_param -n mdc.*.stats=clear
20301         smalliomany -w $dom 1000 200
20302         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20303         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20304         # for OPEN and IO lock.
20305         [ $((enq - enq_2)) -ge 1000 ] ||
20306                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20307         unlinkmany $dom 1000
20308         return 0
20309 }
20310 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20311
20312 cleanup_271def_tests() {
20313         trap 0
20314         rm -f $1
20315 }
20316
20317 test_271d() {
20318         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20319                 skip "Need MDS version at least 2.10.57"
20320
20321         local dom=$DIR/$tdir/dom
20322         local tmp=$TMP/$tfile
20323         trap "cleanup_271def_tests $tmp" EXIT
20324
20325         mkdir -p $DIR/$tdir
20326
20327         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20328
20329         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20330
20331         cancel_lru_locks mdc
20332         dd if=/dev/urandom of=$tmp bs=1000 count=1
20333         dd if=$tmp of=$dom bs=1000 count=1
20334         cancel_lru_locks mdc
20335
20336         cat /etc/hosts >> $tmp
20337         lctl set_param -n mdc.*.stats=clear
20338
20339         # append data to the same file it should update local page
20340         echo "Append to the same page"
20341         cat /etc/hosts >> $dom
20342         local num=$(get_mdc_stats $mdtidx ost_read)
20343         local ra=$(get_mdc_stats $mdtidx req_active)
20344         local rw=$(get_mdc_stats $mdtidx req_waittime)
20345
20346         [ -z $num ] || error "$num READ RPC occured"
20347         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20348         echo "... DONE"
20349
20350         # compare content
20351         cmp $tmp $dom || error "file miscompare"
20352
20353         cancel_lru_locks mdc
20354         lctl set_param -n mdc.*.stats=clear
20355
20356         echo "Open and read file"
20357         cat $dom > /dev/null
20358         local num=$(get_mdc_stats $mdtidx ost_read)
20359         local ra=$(get_mdc_stats $mdtidx req_active)
20360         local rw=$(get_mdc_stats $mdtidx req_waittime)
20361
20362         [ -z $num ] || error "$num READ RPC occured"
20363         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20364         echo "... DONE"
20365
20366         # compare content
20367         cmp $tmp $dom || error "file miscompare"
20368
20369         return 0
20370 }
20371 run_test 271d "DoM: read on open (1K file in reply buffer)"
20372
20373 test_271f() {
20374         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20375                 skip "Need MDS version at least 2.10.57"
20376
20377         local dom=$DIR/$tdir/dom
20378         local tmp=$TMP/$tfile
20379         trap "cleanup_271def_tests $tmp" EXIT
20380
20381         mkdir -p $DIR/$tdir
20382
20383         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20384
20385         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20386
20387         cancel_lru_locks mdc
20388         dd if=/dev/urandom of=$tmp bs=265000 count=1
20389         dd if=$tmp of=$dom bs=265000 count=1
20390         cancel_lru_locks mdc
20391         cat /etc/hosts >> $tmp
20392         lctl set_param -n mdc.*.stats=clear
20393
20394         echo "Append to the same page"
20395         cat /etc/hosts >> $dom
20396         local num=$(get_mdc_stats $mdtidx ost_read)
20397         local ra=$(get_mdc_stats $mdtidx req_active)
20398         local rw=$(get_mdc_stats $mdtidx req_waittime)
20399
20400         [ -z $num ] || error "$num READ RPC occured"
20401         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20402         echo "... DONE"
20403
20404         # compare content
20405         cmp $tmp $dom || error "file miscompare"
20406
20407         cancel_lru_locks mdc
20408         lctl set_param -n mdc.*.stats=clear
20409
20410         echo "Open and read file"
20411         cat $dom > /dev/null
20412         local num=$(get_mdc_stats $mdtidx ost_read)
20413         local ra=$(get_mdc_stats $mdtidx req_active)
20414         local rw=$(get_mdc_stats $mdtidx req_waittime)
20415
20416         [ -z $num ] && num=0
20417         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20418         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20419         echo "... DONE"
20420
20421         # compare content
20422         cmp $tmp $dom || error "file miscompare"
20423
20424         return 0
20425 }
20426 run_test 271f "DoM: read on open (200K file and read tail)"
20427
20428 test_271g() {
20429         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20430                 skip "Skipping due to old client or server version"
20431
20432         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20433         # to get layout
20434         $CHECKSTAT -t file $DIR1/$tfile
20435
20436         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20437         MULTIOP_PID=$!
20438         sleep 1
20439         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20440         $LCTL set_param fail_loc=0x80000314
20441         rm $DIR1/$tfile || error "Unlink fails"
20442         RC=$?
20443         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20444         [ $RC -eq 0 ] || error "Failed write to stale object"
20445 }
20446 run_test 271g "Discard DoM data vs client flush race"
20447
20448 test_272a() {
20449         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20450                 skip "Need MDS version at least 2.11.50"
20451
20452         local dom=$DIR/$tdir/dom
20453         mkdir -p $DIR/$tdir
20454
20455         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20456         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20457                 error "failed to write data into $dom"
20458         local old_md5=$(md5sum $dom)
20459
20460         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20461                 error "failed to migrate to the same DoM component"
20462
20463         local new_md5=$(md5sum $dom)
20464
20465         [ "$old_md5" == "$new_md5" ] ||
20466                 error "md5sum differ: $old_md5, $new_md5"
20467
20468         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20469                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20470 }
20471 run_test 272a "DoM migration: new layout with the same DOM component"
20472
20473 test_272b() {
20474         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20475                 skip "Need MDS version at least 2.11.50"
20476
20477         local dom=$DIR/$tdir/dom
20478         mkdir -p $DIR/$tdir
20479         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20480
20481         local mdtidx=$($LFS getstripe -m $dom)
20482         local mdtname=MDT$(printf %04x $mdtidx)
20483         local facet=mds$((mdtidx + 1))
20484
20485         local mdtfree1=$(do_facet $facet \
20486                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20487         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20488                 error "failed to write data into $dom"
20489         local old_md5=$(md5sum $dom)
20490         cancel_lru_locks mdc
20491         local mdtfree1=$(do_facet $facet \
20492                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20493
20494         $LFS migrate -c2 $dom ||
20495                 error "failed to migrate to the new composite layout"
20496         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20497                 error "MDT stripe was not removed"
20498
20499         cancel_lru_locks mdc
20500         local new_md5=$(md5sum $dom)
20501         [ "$old_md5" == "$new_md5" ] ||
20502                 error "$old_md5 != $new_md5"
20503
20504         # Skip free space checks with ZFS
20505         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20506                 local mdtfree2=$(do_facet $facet \
20507                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20508                 [ $mdtfree2 -gt $mdtfree1 ] ||
20509                         error "MDT space is not freed after migration"
20510         fi
20511         return 0
20512 }
20513 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20514
20515 test_272c() {
20516         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20517                 skip "Need MDS version at least 2.11.50"
20518
20519         local dom=$DIR/$tdir/$tfile
20520         mkdir -p $DIR/$tdir
20521         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20522
20523         local mdtidx=$($LFS getstripe -m $dom)
20524         local mdtname=MDT$(printf %04x $mdtidx)
20525         local facet=mds$((mdtidx + 1))
20526
20527         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20528                 error "failed to write data into $dom"
20529         local old_md5=$(md5sum $dom)
20530         cancel_lru_locks mdc
20531         local mdtfree1=$(do_facet $facet \
20532                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20533
20534         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20535                 error "failed to migrate to the new composite layout"
20536         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20537                 error "MDT stripe was not removed"
20538
20539         cancel_lru_locks mdc
20540         local new_md5=$(md5sum $dom)
20541         [ "$old_md5" == "$new_md5" ] ||
20542                 error "$old_md5 != $new_md5"
20543
20544         # Skip free space checks with ZFS
20545         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20546                 local mdtfree2=$(do_facet $facet \
20547                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20548                 [ $mdtfree2 -gt $mdtfree1 ] ||
20549                         error "MDS space is not freed after migration"
20550         fi
20551         return 0
20552 }
20553 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20554
20555 test_272d() {
20556         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20557                 skip "Need MDS version at least 2.12.55"
20558
20559         local dom=$DIR/$tdir/$tfile
20560         mkdir -p $DIR/$tdir
20561         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20562
20563         local mdtidx=$($LFS getstripe -m $dom)
20564         local mdtname=MDT$(printf %04x $mdtidx)
20565         local facet=mds$((mdtidx + 1))
20566
20567         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20568                 error "failed to write data into $dom"
20569         local old_md5=$(md5sum $dom)
20570         cancel_lru_locks mdc
20571         local mdtfree1=$(do_facet $facet \
20572                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20573
20574         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20575                 error "failed mirroring to the new composite layout"
20576         $LFS mirror resync $dom ||
20577                 error "failed mirror resync"
20578         $LFS mirror split --mirror-id 1 -d $dom ||
20579                 error "failed mirror split"
20580
20581         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20582                 error "MDT stripe was not removed"
20583
20584         cancel_lru_locks mdc
20585         local new_md5=$(md5sum $dom)
20586         [ "$old_md5" == "$new_md5" ] ||
20587                 error "$old_md5 != $new_md5"
20588
20589         # Skip free space checks with ZFS
20590         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20591                 local mdtfree2=$(do_facet $facet \
20592                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20593                 [ $mdtfree2 -gt $mdtfree1 ] ||
20594                         error "MDS space is not freed after DOM mirror deletion"
20595         fi
20596         return 0
20597 }
20598 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20599
20600 test_272e() {
20601         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20602                 skip "Need MDS version at least 2.12.55"
20603
20604         local dom=$DIR/$tdir/$tfile
20605         mkdir -p $DIR/$tdir
20606         $LFS setstripe -c 2 $dom
20607
20608         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20609                 error "failed to write data into $dom"
20610         local old_md5=$(md5sum $dom)
20611         cancel_lru_locks mdc
20612
20613         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20614                 error "failed mirroring to the DOM layout"
20615         $LFS mirror resync $dom ||
20616                 error "failed mirror resync"
20617         $LFS mirror split --mirror-id 1 -d $dom ||
20618                 error "failed mirror split"
20619
20620         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20621                 error "MDT stripe was not removed"
20622
20623         cancel_lru_locks mdc
20624         local new_md5=$(md5sum $dom)
20625         [ "$old_md5" == "$new_md5" ] ||
20626                 error "$old_md5 != $new_md5"
20627
20628         return 0
20629 }
20630 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20631
20632 test_272f() {
20633         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20634                 skip "Need MDS version at least 2.12.55"
20635
20636         local dom=$DIR/$tdir/$tfile
20637         mkdir -p $DIR/$tdir
20638         $LFS setstripe -c 2 $dom
20639
20640         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20641                 error "failed to write data into $dom"
20642         local old_md5=$(md5sum $dom)
20643         cancel_lru_locks mdc
20644
20645         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20646                 error "failed migrating to the DOM file"
20647
20648         cancel_lru_locks mdc
20649         local new_md5=$(md5sum $dom)
20650         [ "$old_md5" != "$new_md5" ] &&
20651                 error "$old_md5 != $new_md5"
20652
20653         return 0
20654 }
20655 run_test 272f "DoM migration: OST-striped file to DOM file"
20656
20657 test_273a() {
20658         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20659                 skip "Need MDS version at least 2.11.50"
20660
20661         # Layout swap cannot be done if either file has DOM component,
20662         # this will never be supported, migration should be used instead
20663
20664         local dom=$DIR/$tdir/$tfile
20665         mkdir -p $DIR/$tdir
20666
20667         $LFS setstripe -c2 ${dom}_plain
20668         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20669         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20670                 error "can swap layout with DoM component"
20671         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20672                 error "can swap layout with DoM component"
20673
20674         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20675         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20676                 error "can swap layout with DoM component"
20677         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20678                 error "can swap layout with DoM component"
20679         return 0
20680 }
20681 run_test 273a "DoM: layout swapping should fail with DOM"
20682
20683 test_275() {
20684         remote_ost_nodsh && skip "remote OST with nodsh"
20685         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20686                 skip "Need OST version >= 2.10.57"
20687
20688         local file=$DIR/$tfile
20689         local oss
20690
20691         oss=$(comma_list $(osts_nodes))
20692
20693         dd if=/dev/urandom of=$file bs=1M count=2 ||
20694                 error "failed to create a file"
20695         cancel_lru_locks osc
20696
20697         #lock 1
20698         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20699                 error "failed to read a file"
20700
20701 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20702         $LCTL set_param fail_loc=0x8000031f
20703
20704         cancel_lru_locks osc &
20705         sleep 1
20706
20707 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20708         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20709         #IO takes another lock, but matches the PENDING one
20710         #and places it to the IO RPC
20711         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20712                 error "failed to read a file with PENDING lock"
20713 }
20714 run_test 275 "Read on a canceled duplicate lock"
20715
20716 test_276() {
20717         remote_ost_nodsh && skip "remote OST with nodsh"
20718         local pid
20719
20720         do_facet ost1 "(while true; do \
20721                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20722                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20723         pid=$!
20724
20725         for LOOP in $(seq 20); do
20726                 stop ost1
20727                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20728         done
20729         kill -9 $pid
20730         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20731                 rm $TMP/sanity_276_pid"
20732 }
20733 run_test 276 "Race between mount and obd_statfs"
20734
20735 test_277() {
20736         $LCTL set_param ldlm.namespaces.*.lru_size=0
20737         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20738         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20739                         grep ^used_mb | awk '{print $2}')
20740         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20741         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20742                 oflag=direct conv=notrunc
20743         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20744                         grep ^used_mb | awk '{print $2}')
20745         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20746 }
20747 run_test 277 "Direct IO shall drop page cache"
20748
20749 test_278() {
20750         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20751         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20752         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20753                 skip "needs the same host for mdt1 mdt2" && return
20754
20755         local pid1
20756         local pid2
20757
20758 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20759         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20760         stop mds2 &
20761         pid2=$!
20762
20763         stop mds1
20764
20765         echo "Starting MDTs"
20766         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20767         wait $pid2
20768 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20769 #will return NULL
20770         do_facet mds2 $LCTL set_param fail_loc=0
20771
20772         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20773         wait_recovery_complete mds2
20774 }
20775 run_test 278 "Race starting MDS between MDTs stop/start"
20776
20777 test_280() {
20778         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20779                 skip "Need MGS version at least 2.13.52"
20780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20781         combined_mgs_mds || skip "needs combined MGS/MDT"
20782
20783         umount_client $MOUNT
20784 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20785         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20786
20787         mount_client $MOUNT &
20788         sleep 1
20789         stop mgs || error "stop mgs failed"
20790         #for a race mgs would crash
20791         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20792         mount_client $MOUNT || error "mount client failed"
20793 }
20794 run_test 280 "Race between MGS umount and client llog processing"
20795
20796 cleanup_test_300() {
20797         trap 0
20798         umask $SAVE_UMASK
20799 }
20800 test_striped_dir() {
20801         local mdt_index=$1
20802         local stripe_count
20803         local stripe_index
20804
20805         mkdir -p $DIR/$tdir
20806
20807         SAVE_UMASK=$(umask)
20808         trap cleanup_test_300 RETURN EXIT
20809
20810         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20811                                                 $DIR/$tdir/striped_dir ||
20812                 error "set striped dir error"
20813
20814         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20815         [ "$mode" = "755" ] || error "expect 755 got $mode"
20816
20817         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20818                 error "getdirstripe failed"
20819         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20820         if [ "$stripe_count" != "2" ]; then
20821                 error "1:stripe_count is $stripe_count, expect 2"
20822         fi
20823         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20824         if [ "$stripe_count" != "2" ]; then
20825                 error "2:stripe_count is $stripe_count, expect 2"
20826         fi
20827
20828         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20829         if [ "$stripe_index" != "$mdt_index" ]; then
20830                 error "stripe_index is $stripe_index, expect $mdt_index"
20831         fi
20832
20833         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20834                 error "nlink error after create striped dir"
20835
20836         mkdir $DIR/$tdir/striped_dir/a
20837         mkdir $DIR/$tdir/striped_dir/b
20838
20839         stat $DIR/$tdir/striped_dir/a ||
20840                 error "create dir under striped dir failed"
20841         stat $DIR/$tdir/striped_dir/b ||
20842                 error "create dir under striped dir failed"
20843
20844         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20845                 error "nlink error after mkdir"
20846
20847         rmdir $DIR/$tdir/striped_dir/a
20848         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20849                 error "nlink error after rmdir"
20850
20851         rmdir $DIR/$tdir/striped_dir/b
20852         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20853                 error "nlink error after rmdir"
20854
20855         chattr +i $DIR/$tdir/striped_dir
20856         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20857                 error "immutable flags not working under striped dir!"
20858         chattr -i $DIR/$tdir/striped_dir
20859
20860         rmdir $DIR/$tdir/striped_dir ||
20861                 error "rmdir striped dir error"
20862
20863         cleanup_test_300
20864
20865         true
20866 }
20867
20868 test_300a() {
20869         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20870                 skip "skipped for lustre < 2.7.0"
20871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20872         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20873
20874         test_striped_dir 0 || error "failed on striped dir on MDT0"
20875         test_striped_dir 1 || error "failed on striped dir on MDT0"
20876 }
20877 run_test 300a "basic striped dir sanity test"
20878
20879 test_300b() {
20880         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20881                 skip "skipped for lustre < 2.7.0"
20882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20884
20885         local i
20886         local mtime1
20887         local mtime2
20888         local mtime3
20889
20890         test_mkdir $DIR/$tdir || error "mkdir fail"
20891         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20892                 error "set striped dir error"
20893         for i in {0..9}; do
20894                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20895                 sleep 1
20896                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20897                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20898                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20899                 sleep 1
20900                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20901                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20902                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20903         done
20904         true
20905 }
20906 run_test 300b "check ctime/mtime for striped dir"
20907
20908 test_300c() {
20909         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20910                 skip "skipped for lustre < 2.7.0"
20911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20913
20914         local file_count
20915
20916         mkdir -p $DIR/$tdir
20917         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20918                 error "set striped dir error"
20919
20920         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20921                 error "chown striped dir failed"
20922
20923         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20924                 error "create 5k files failed"
20925
20926         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20927
20928         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20929
20930         rm -rf $DIR/$tdir
20931 }
20932 run_test 300c "chown && check ls under striped directory"
20933
20934 test_300d() {
20935         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20936                 skip "skipped for lustre < 2.7.0"
20937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20939
20940         local stripe_count
20941         local file
20942
20943         mkdir -p $DIR/$tdir
20944         $LFS setstripe -c 2 $DIR/$tdir
20945
20946         #local striped directory
20947         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20948                 error "set striped dir error"
20949         #look at the directories for debug purposes
20950         ls -l $DIR/$tdir
20951         $LFS getdirstripe $DIR/$tdir
20952         ls -l $DIR/$tdir/striped_dir
20953         $LFS getdirstripe $DIR/$tdir/striped_dir
20954         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20955                 error "create 10 files failed"
20956
20957         #remote striped directory
20958         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20959                 error "set striped dir error"
20960         #look at the directories for debug purposes
20961         ls -l $DIR/$tdir
20962         $LFS getdirstripe $DIR/$tdir
20963         ls -l $DIR/$tdir/remote_striped_dir
20964         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20965         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20966                 error "create 10 files failed"
20967
20968         for file in $(find $DIR/$tdir); do
20969                 stripe_count=$($LFS getstripe -c $file)
20970                 [ $stripe_count -eq 2 ] ||
20971                         error "wrong stripe $stripe_count for $file"
20972         done
20973
20974         rm -rf $DIR/$tdir
20975 }
20976 run_test 300d "check default stripe under striped directory"
20977
20978 test_300e() {
20979         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20980                 skip "Need MDS version at least 2.7.55"
20981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20982         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20983
20984         local stripe_count
20985         local file
20986
20987         mkdir -p $DIR/$tdir
20988
20989         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20990                 error "set striped dir error"
20991
20992         touch $DIR/$tdir/striped_dir/a
20993         touch $DIR/$tdir/striped_dir/b
20994         touch $DIR/$tdir/striped_dir/c
20995
20996         mkdir $DIR/$tdir/striped_dir/dir_a
20997         mkdir $DIR/$tdir/striped_dir/dir_b
20998         mkdir $DIR/$tdir/striped_dir/dir_c
20999
21000         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21001                 error "set striped adir under striped dir error"
21002
21003         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21004                 error "set striped bdir under striped dir error"
21005
21006         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21007                 error "set striped cdir under striped dir error"
21008
21009         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21010                 error "rename dir under striped dir fails"
21011
21012         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21013                 error "rename dir under different stripes fails"
21014
21015         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21016                 error "rename file under striped dir should succeed"
21017
21018         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21019                 error "rename dir under striped dir should succeed"
21020
21021         rm -rf $DIR/$tdir
21022 }
21023 run_test 300e "check rename under striped directory"
21024
21025 test_300f() {
21026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21028         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21029                 skip "Need MDS version at least 2.7.55"
21030
21031         local stripe_count
21032         local file
21033
21034         rm -rf $DIR/$tdir
21035         mkdir -p $DIR/$tdir
21036
21037         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21038                 error "set striped dir error"
21039
21040         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21041                 error "set striped dir error"
21042
21043         touch $DIR/$tdir/striped_dir/a
21044         mkdir $DIR/$tdir/striped_dir/dir_a
21045         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21046                 error "create striped dir under striped dir fails"
21047
21048         touch $DIR/$tdir/striped_dir1/b
21049         mkdir $DIR/$tdir/striped_dir1/dir_b
21050         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21051                 error "create striped dir under striped dir fails"
21052
21053         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21054                 error "rename dir under different striped dir should fail"
21055
21056         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21057                 error "rename striped dir under diff striped dir should fail"
21058
21059         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21060                 error "rename file under diff striped dirs fails"
21061
21062         rm -rf $DIR/$tdir
21063 }
21064 run_test 300f "check rename cross striped directory"
21065
21066 test_300_check_default_striped_dir()
21067 {
21068         local dirname=$1
21069         local default_count=$2
21070         local default_index=$3
21071         local stripe_count
21072         local stripe_index
21073         local dir_stripe_index
21074         local dir
21075
21076         echo "checking $dirname $default_count $default_index"
21077         $LFS setdirstripe -D -c $default_count -i $default_index \
21078                                 -t all_char $DIR/$tdir/$dirname ||
21079                 error "set default stripe on striped dir error"
21080         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21081         [ $stripe_count -eq $default_count ] ||
21082                 error "expect $default_count get $stripe_count for $dirname"
21083
21084         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21085         [ $stripe_index -eq $default_index ] ||
21086                 error "expect $default_index get $stripe_index for $dirname"
21087
21088         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21089                                                 error "create dirs failed"
21090
21091         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21092         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21093         for dir in $(find $DIR/$tdir/$dirname/*); do
21094                 stripe_count=$($LFS getdirstripe -c $dir)
21095                 [ $stripe_count -eq $default_count ] ||
21096                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21097                 error "stripe count $default_count != $stripe_count for $dir"
21098
21099                 stripe_index=$($LFS getdirstripe -i $dir)
21100                 [ $default_index -eq -1 ] ||
21101                         [ $stripe_index -eq $default_index ] ||
21102                         error "$stripe_index != $default_index for $dir"
21103
21104                 #check default stripe
21105                 stripe_count=$($LFS getdirstripe -D -c $dir)
21106                 [ $stripe_count -eq $default_count ] ||
21107                 error "default count $default_count != $stripe_count for $dir"
21108
21109                 stripe_index=$($LFS getdirstripe -D -i $dir)
21110                 [ $stripe_index -eq $default_index ] ||
21111                 error "default index $default_index != $stripe_index for $dir"
21112         done
21113         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21114 }
21115
21116 test_300g() {
21117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21118         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21119                 skip "Need MDS version at least 2.7.55"
21120
21121         local dir
21122         local stripe_count
21123         local stripe_index
21124
21125         mkdir $DIR/$tdir
21126         mkdir $DIR/$tdir/normal_dir
21127
21128         #Checking when client cache stripe index
21129         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21130         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21131                 error "create striped_dir failed"
21132
21133         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21134                 error "create dir0 fails"
21135         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21136         [ $stripe_index -eq 0 ] ||
21137                 error "dir0 expect index 0 got $stripe_index"
21138
21139         mkdir $DIR/$tdir/striped_dir/dir1 ||
21140                 error "create dir1 fails"
21141         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21142         [ $stripe_index -eq 1 ] ||
21143                 error "dir1 expect index 1 got $stripe_index"
21144
21145         #check default stripe count/stripe index
21146         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21147         test_300_check_default_striped_dir normal_dir 1 0
21148         test_300_check_default_striped_dir normal_dir 2 1
21149         test_300_check_default_striped_dir normal_dir 2 -1
21150
21151         #delete default stripe information
21152         echo "delete default stripeEA"
21153         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21154                 error "set default stripe on striped dir error"
21155
21156         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21157         for dir in $(find $DIR/$tdir/normal_dir/*); do
21158                 stripe_count=$($LFS getdirstripe -c $dir)
21159                 [ $stripe_count -eq 0 ] ||
21160                         error "expect 1 get $stripe_count for $dir"
21161                 stripe_index=$($LFS getdirstripe -i $dir)
21162                 [ $stripe_index -eq 0 ] ||
21163                         error "expect 0 get $stripe_index for $dir"
21164         done
21165 }
21166 run_test 300g "check default striped directory for normal directory"
21167
21168 test_300h() {
21169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21170         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21171                 skip "Need MDS version at least 2.7.55"
21172
21173         local dir
21174         local stripe_count
21175
21176         mkdir $DIR/$tdir
21177         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21178                 error "set striped dir error"
21179
21180         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21181         test_300_check_default_striped_dir striped_dir 1 0
21182         test_300_check_default_striped_dir striped_dir 2 1
21183         test_300_check_default_striped_dir striped_dir 2 -1
21184
21185         #delete default stripe information
21186         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21187                 error "set default stripe on striped dir error"
21188
21189         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21190         for dir in $(find $DIR/$tdir/striped_dir/*); do
21191                 stripe_count=$($LFS getdirstripe -c $dir)
21192                 [ $stripe_count -eq 0 ] ||
21193                         error "expect 1 get $stripe_count for $dir"
21194         done
21195 }
21196 run_test 300h "check default striped directory for striped directory"
21197
21198 test_300i() {
21199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21201         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21202                 skip "Need MDS version at least 2.7.55"
21203
21204         local stripe_count
21205         local file
21206
21207         mkdir $DIR/$tdir
21208
21209         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21210                 error "set striped dir error"
21211
21212         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21213                 error "create files under striped dir failed"
21214
21215         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21216                 error "set striped hashdir error"
21217
21218         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21219                 error "create dir0 under hash dir failed"
21220         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21221                 error "create dir1 under hash dir failed"
21222
21223         # unfortunately, we need to umount to clear dir layout cache for now
21224         # once we fully implement dir layout, we can drop this
21225         umount_client $MOUNT || error "umount failed"
21226         mount_client $MOUNT || error "mount failed"
21227
21228         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21229         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21230         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21231
21232         #set the stripe to be unknown hash type
21233         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21234         $LCTL set_param fail_loc=0x1901
21235         for ((i = 0; i < 10; i++)); do
21236                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21237                         error "stat f-$i failed"
21238                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21239         done
21240
21241         touch $DIR/$tdir/striped_dir/f0 &&
21242                 error "create under striped dir with unknown hash should fail"
21243
21244         $LCTL set_param fail_loc=0
21245
21246         umount_client $MOUNT || error "umount failed"
21247         mount_client $MOUNT || error "mount failed"
21248
21249         return 0
21250 }
21251 run_test 300i "client handle unknown hash type striped directory"
21252
21253 test_300j() {
21254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21256         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21257                 skip "Need MDS version at least 2.7.55"
21258
21259         local stripe_count
21260         local file
21261
21262         mkdir $DIR/$tdir
21263
21264         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21265         $LCTL set_param fail_loc=0x1702
21266         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21267                 error "set striped dir error"
21268
21269         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21270                 error "create files under striped dir failed"
21271
21272         $LCTL set_param fail_loc=0
21273
21274         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21275
21276         return 0
21277 }
21278 run_test 300j "test large update record"
21279
21280 test_300k() {
21281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21283         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21284                 skip "Need MDS version at least 2.7.55"
21285
21286         # this test needs a huge transaction
21287         local kb
21288         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21289              osd*.$FSNAME-MDT0000.kbytestotal")
21290         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21291
21292         local stripe_count
21293         local file
21294
21295         mkdir $DIR/$tdir
21296
21297         #define OBD_FAIL_LARGE_STRIPE   0x1703
21298         $LCTL set_param fail_loc=0x1703
21299         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21300                 error "set striped dir error"
21301         $LCTL set_param fail_loc=0
21302
21303         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21304                 error "getstripeddir fails"
21305         rm -rf $DIR/$tdir/striped_dir ||
21306                 error "unlink striped dir fails"
21307
21308         return 0
21309 }
21310 run_test 300k "test large striped directory"
21311
21312 test_300l() {
21313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21315         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21316                 skip "Need MDS version at least 2.7.55"
21317
21318         local stripe_index
21319
21320         test_mkdir -p $DIR/$tdir/striped_dir
21321         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21322                         error "chown $RUNAS_ID failed"
21323         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21324                 error "set default striped dir failed"
21325
21326         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21327         $LCTL set_param fail_loc=0x80000158
21328         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21329
21330         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21331         [ $stripe_index -eq 1 ] ||
21332                 error "expect 1 get $stripe_index for $dir"
21333 }
21334 run_test 300l "non-root user to create dir under striped dir with stale layout"
21335
21336 test_300m() {
21337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21338         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21339         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21340                 skip "Need MDS version at least 2.7.55"
21341
21342         mkdir -p $DIR/$tdir/striped_dir
21343         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21344                 error "set default stripes dir error"
21345
21346         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21347
21348         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21349         [ $stripe_count -eq 0 ] ||
21350                         error "expect 0 get $stripe_count for a"
21351
21352         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21353                 error "set default stripes dir error"
21354
21355         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21356
21357         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21358         [ $stripe_count -eq 0 ] ||
21359                         error "expect 0 get $stripe_count for b"
21360
21361         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21362                 error "set default stripes dir error"
21363
21364         mkdir $DIR/$tdir/striped_dir/c &&
21365                 error "default stripe_index is invalid, mkdir c should fails"
21366
21367         rm -rf $DIR/$tdir || error "rmdir fails"
21368 }
21369 run_test 300m "setstriped directory on single MDT FS"
21370
21371 cleanup_300n() {
21372         local list=$(comma_list $(mdts_nodes))
21373
21374         trap 0
21375         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21376 }
21377
21378 test_300n() {
21379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21381         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21382                 skip "Need MDS version at least 2.7.55"
21383         remote_mds_nodsh && skip "remote MDS with nodsh"
21384
21385         local stripe_index
21386         local list=$(comma_list $(mdts_nodes))
21387
21388         trap cleanup_300n RETURN EXIT
21389         mkdir -p $DIR/$tdir
21390         chmod 777 $DIR/$tdir
21391         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21392                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21393                 error "create striped dir succeeds with gid=0"
21394
21395         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21396         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21397                 error "create striped dir fails with gid=-1"
21398
21399         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21400         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21401                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21402                 error "set default striped dir succeeds with gid=0"
21403
21404
21405         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21406         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21407                 error "set default striped dir fails with gid=-1"
21408
21409
21410         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21411         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21412                                         error "create test_dir fails"
21413         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21414                                         error "create test_dir1 fails"
21415         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21416                                         error "create test_dir2 fails"
21417         cleanup_300n
21418 }
21419 run_test 300n "non-root user to create dir under striped dir with default EA"
21420
21421 test_300o() {
21422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21423         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21424         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21425                 skip "Need MDS version at least 2.7.55"
21426
21427         local numfree1
21428         local numfree2
21429
21430         mkdir -p $DIR/$tdir
21431
21432         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21433         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21434         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21435                 skip "not enough free inodes $numfree1 $numfree2"
21436         fi
21437
21438         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21439         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21440         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21441                 skip "not enough free space $numfree1 $numfree2"
21442         fi
21443
21444         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21445                 error "setdirstripe fails"
21446
21447         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21448                 error "create dirs fails"
21449
21450         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21451         ls $DIR/$tdir/striped_dir > /dev/null ||
21452                 error "ls striped dir fails"
21453         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21454                 error "unlink big striped dir fails"
21455 }
21456 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21457
21458 test_300p() {
21459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21461         remote_mds_nodsh && skip "remote MDS with nodsh"
21462
21463         mkdir -p $DIR/$tdir
21464
21465         #define OBD_FAIL_OUT_ENOSPC     0x1704
21466         do_facet mds2 lctl set_param fail_loc=0x80001704
21467         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21468                  && error "create striped directory should fail"
21469
21470         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21471
21472         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21473         true
21474 }
21475 run_test 300p "create striped directory without space"
21476
21477 test_300q() {
21478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21479         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21480
21481         local fd=$(free_fd)
21482         local cmd="exec $fd<$tdir"
21483         cd $DIR
21484         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21485         eval $cmd
21486         cmd="exec $fd<&-"
21487         trap "eval $cmd" EXIT
21488         cd $tdir || error "cd $tdir fails"
21489         rmdir  ../$tdir || error "rmdir $tdir fails"
21490         mkdir local_dir && error "create dir succeeds"
21491         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21492         eval $cmd
21493         return 0
21494 }
21495 run_test 300q "create remote directory under orphan directory"
21496
21497 test_300r() {
21498         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21499                 skip "Need MDS version at least 2.7.55" && return
21500         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21501
21502         mkdir $DIR/$tdir
21503
21504         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21505                 error "set striped dir error"
21506
21507         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21508                 error "getstripeddir fails"
21509
21510         local stripe_count
21511         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21512                       awk '/lmv_stripe_count:/ { print $2 }')
21513
21514         [ $MDSCOUNT -ne $stripe_count ] &&
21515                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21516
21517         rm -rf $DIR/$tdir/striped_dir ||
21518                 error "unlink striped dir fails"
21519 }
21520 run_test 300r "test -1 striped directory"
21521
21522 prepare_remote_file() {
21523         mkdir $DIR/$tdir/src_dir ||
21524                 error "create remote source failed"
21525
21526         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21527                  error "cp to remote source failed"
21528         touch $DIR/$tdir/src_dir/a
21529
21530         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21531                 error "create remote target dir failed"
21532
21533         touch $DIR/$tdir/tgt_dir/b
21534
21535         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21536                 error "rename dir cross MDT failed!"
21537
21538         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21539                 error "src_child still exists after rename"
21540
21541         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21542                 error "missing file(a) after rename"
21543
21544         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21545                 error "diff after rename"
21546 }
21547
21548 test_310a() {
21549         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21551
21552         local remote_file=$DIR/$tdir/tgt_dir/b
21553
21554         mkdir -p $DIR/$tdir
21555
21556         prepare_remote_file || error "prepare remote file failed"
21557
21558         #open-unlink file
21559         $OPENUNLINK $remote_file $remote_file ||
21560                 error "openunlink $remote_file failed"
21561         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21562 }
21563 run_test 310a "open unlink remote file"
21564
21565 test_310b() {
21566         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21568
21569         local remote_file=$DIR/$tdir/tgt_dir/b
21570
21571         mkdir -p $DIR/$tdir
21572
21573         prepare_remote_file || error "prepare remote file failed"
21574
21575         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21576         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21577         $CHECKSTAT -t file $remote_file || error "check file failed"
21578 }
21579 run_test 310b "unlink remote file with multiple links while open"
21580
21581 test_310c() {
21582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21583         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21584
21585         local remote_file=$DIR/$tdir/tgt_dir/b
21586
21587         mkdir -p $DIR/$tdir
21588
21589         prepare_remote_file || error "prepare remote file failed"
21590
21591         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21592         multiop_bg_pause $remote_file O_uc ||
21593                         error "mulitop failed for remote file"
21594         MULTIPID=$!
21595         $MULTIOP $DIR/$tfile Ouc
21596         kill -USR1 $MULTIPID
21597         wait $MULTIPID
21598 }
21599 run_test 310c "open-unlink remote file with multiple links"
21600
21601 #LU-4825
21602 test_311() {
21603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21604         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21605         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21606                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21607         remote_mds_nodsh && skip "remote MDS with nodsh"
21608
21609         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21610         local mdts=$(comma_list $(mdts_nodes))
21611
21612         mkdir -p $DIR/$tdir
21613         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21614         createmany -o $DIR/$tdir/$tfile. 1000
21615
21616         # statfs data is not real time, let's just calculate it
21617         old_iused=$((old_iused + 1000))
21618
21619         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21620                         osp.*OST0000*MDT0000.create_count")
21621         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21622                                 osp.*OST0000*MDT0000.max_create_count")
21623         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21624
21625         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21626         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21627         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21628
21629         unlinkmany $DIR/$tdir/$tfile. 1000
21630
21631         do_nodes $mdts "$LCTL set_param -n \
21632                         osp.*OST0000*.max_create_count=$max_count"
21633         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21634                 do_nodes $mdts "$LCTL set_param -n \
21635                                 osp.*OST0000*.create_count=$count"
21636         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21637                         grep "=0" && error "create_count is zero"
21638
21639         local new_iused
21640         for i in $(seq 120); do
21641                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21642                 # system may be too busy to destroy all objs in time, use
21643                 # a somewhat small value to not fail autotest
21644                 [ $((old_iused - new_iused)) -gt 400 ] && break
21645                 sleep 1
21646         done
21647
21648         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21649         [ $((old_iused - new_iused)) -gt 400 ] ||
21650                 error "objs not destroyed after unlink"
21651 }
21652 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21653
21654 zfs_oid_to_objid()
21655 {
21656         local ost=$1
21657         local objid=$2
21658
21659         local vdevdir=$(dirname $(facet_vdevice $ost))
21660         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21661         local zfs_zapid=$(do_facet $ost $cmd |
21662                           grep -w "/O/0/d$((objid%32))" -C 5 |
21663                           awk '/Object/{getline; print $1}')
21664         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21665                           awk "/$objid = /"'{printf $3}')
21666
21667         echo $zfs_objid
21668 }
21669
21670 zfs_object_blksz() {
21671         local ost=$1
21672         local objid=$2
21673
21674         local vdevdir=$(dirname $(facet_vdevice $ost))
21675         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21676         local blksz=$(do_facet $ost $cmd $objid |
21677                       awk '/dblk/{getline; printf $4}')
21678
21679         case "${blksz: -1}" in
21680                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21681                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21682                 *) ;;
21683         esac
21684
21685         echo $blksz
21686 }
21687
21688 test_312() { # LU-4856
21689         remote_ost_nodsh && skip "remote OST with nodsh"
21690         [ "$ost1_FSTYPE" = "zfs" ] ||
21691                 skip_env "the test only applies to zfs"
21692
21693         local max_blksz=$(do_facet ost1 \
21694                           $ZFS get -p recordsize $(facet_device ost1) |
21695                           awk '!/VALUE/{print $3}')
21696
21697         # to make life a little bit easier
21698         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21699         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21700
21701         local tf=$DIR/$tdir/$tfile
21702         touch $tf
21703         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21704
21705         # Get ZFS object id
21706         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21707         # block size change by sequential overwrite
21708         local bs
21709
21710         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21711                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21712
21713                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21714                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21715         done
21716         rm -f $tf
21717
21718         # block size change by sequential append write
21719         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21720         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21721         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21722         local count
21723
21724         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21725                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21726                         oflag=sync conv=notrunc
21727
21728                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21729                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21730                         error "blksz error, actual $blksz, " \
21731                                 "expected: 2 * $count * $PAGE_SIZE"
21732         done
21733         rm -f $tf
21734
21735         # random write
21736         touch $tf
21737         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21738         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21739
21740         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21741         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21742         [ $blksz -eq $PAGE_SIZE ] ||
21743                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21744
21745         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21746         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21747         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21748
21749         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21750         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21751         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21752 }
21753 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21754
21755 test_313() {
21756         remote_ost_nodsh && skip "remote OST with nodsh"
21757
21758         local file=$DIR/$tfile
21759
21760         rm -f $file
21761         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21762
21763         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21764         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21765         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21766                 error "write should failed"
21767         do_facet ost1 "$LCTL set_param fail_loc=0"
21768         rm -f $file
21769 }
21770 run_test 313 "io should fail after last_rcvd update fail"
21771
21772 test_314() {
21773         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21774
21775         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21776         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21777         rm -f $DIR/$tfile
21778         wait_delete_completed
21779         do_facet ost1 "$LCTL set_param fail_loc=0"
21780 }
21781 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21782
21783 test_315() { # LU-618
21784         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21785
21786         local file=$DIR/$tfile
21787         rm -f $file
21788
21789         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21790                 error "multiop file write failed"
21791         $MULTIOP $file oO_RDONLY:r4063232_c &
21792         PID=$!
21793
21794         sleep 2
21795
21796         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21797         kill -USR1 $PID
21798
21799         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21800         rm -f $file
21801 }
21802 run_test 315 "read should be accounted"
21803
21804 test_316() {
21805         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21806         large_xattr_enabled || skip_env "ea_inode feature disabled"
21807
21808         rm -rf $DIR/$tdir/d
21809         mkdir -p $DIR/$tdir/d
21810         chown nobody $DIR/$tdir/d
21811         touch $DIR/$tdir/d/file
21812
21813         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21814 }
21815 run_test 316 "lfs mv"
21816
21817 test_317() {
21818         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21819                 skip "Need MDS version at least 2.11.53"
21820         if [ "$ost1_FSTYPE" == "zfs" ]; then
21821                 skip "LU-10370: no implementation for ZFS"
21822         fi
21823
21824         local trunc_sz
21825         local grant_blk_size
21826
21827         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21828                         awk '/grant_block_size:/ { print $2; exit; }')
21829         #
21830         # Create File of size 5M. Truncate it to below size's and verify
21831         # blocks count.
21832         #
21833         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21834                 error "Create file $DIR/$tfile failed"
21835         stack_trap "rm -f $DIR/$tfile" EXIT
21836
21837         for trunc_sz in 2097152 4097 4000 509 0; do
21838                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21839                         error "truncate $tfile to $trunc_sz failed"
21840                 local sz=$(stat --format=%s $DIR/$tfile)
21841                 local blk=$(stat --format=%b $DIR/$tfile)
21842                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21843                                      grant_blk_size) * 8))
21844
21845                 if [[ $blk -ne $trunc_blk ]]; then
21846                         $(which stat) $DIR/$tfile
21847                         error "Expected Block $trunc_blk got $blk for $tfile"
21848                 fi
21849
21850                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21851                         error "Expected Size $trunc_sz got $sz for $tfile"
21852         done
21853
21854         #
21855         # sparse file test
21856         # Create file with a hole and write actual two blocks. Block count
21857         # must be 16.
21858         #
21859         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21860                 conv=fsync || error "Create file : $DIR/$tfile"
21861
21862         # Calculate the final truncate size.
21863         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21864
21865         #
21866         # truncate to size $trunc_sz bytes. Strip the last block
21867         # The block count must drop to 8
21868         #
21869         $TRUNCATE $DIR/$tfile $trunc_sz ||
21870                 error "truncate $tfile to $trunc_sz failed"
21871
21872         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21873         sz=$(stat --format=%s $DIR/$tfile)
21874         blk=$(stat --format=%b $DIR/$tfile)
21875
21876         if [[ $blk -ne $trunc_bsz ]]; then
21877                 $(which stat) $DIR/$tfile
21878                 error "Expected Block $trunc_bsz got $blk for $tfile"
21879         fi
21880
21881         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21882                 error "Expected Size $trunc_sz got $sz for $tfile"
21883 }
21884 run_test 317 "Verify blocks get correctly update after truncate"
21885
21886 test_318() {
21887         local old_max_active=$($LCTL get_param -n \
21888                             llite.*.max_read_ahead_async_active 2>/dev/null)
21889
21890         $LCTL set_param llite.*.max_read_ahead_async_active=256
21891         local max_active=$($LCTL get_param -n \
21892                            llite.*.max_read_ahead_async_active 2>/dev/null)
21893         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21894
21895         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21896                 error "set max_read_ahead_async_active should succeed"
21897
21898         $LCTL set_param llite.*.max_read_ahead_async_active=512
21899         max_active=$($LCTL get_param -n \
21900                      llite.*.max_read_ahead_async_active 2>/dev/null)
21901         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21902
21903         # restore @max_active
21904         [ $old_max_active -ne 0 ] && $LCTL set_param \
21905                 llite.*.max_read_ahead_async_active=$old_max_active
21906
21907         local old_threshold=$($LCTL get_param -n \
21908                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21909         local max_per_file_mb=$($LCTL get_param -n \
21910                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21911
21912         local invalid=$(($max_per_file_mb + 1))
21913         $LCTL set_param \
21914                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21915                         && error "set $invalid should fail"
21916
21917         local valid=$(($invalid - 1))
21918         $LCTL set_param \
21919                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21920                         error "set $valid should succeed"
21921         local threshold=$($LCTL get_param -n \
21922                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21923         [ $threshold -eq $valid ] || error \
21924                 "expect threshold $valid got $threshold"
21925         $LCTL set_param \
21926                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21927 }
21928 run_test 318 "Verify async readahead tunables"
21929
21930 test_319() {
21931         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21932
21933         local before=$(date +%s)
21934         local evict
21935         local mdir=$DIR/$tdir
21936         local file=$mdir/xxx
21937
21938         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21939         touch $file
21940
21941 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21942         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21943         $LFS mv -m1 $file &
21944
21945         sleep 1
21946         dd if=$file of=/dev/null
21947         wait
21948         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21949           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21950
21951         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21952 }
21953 run_test 319 "lost lease lock on migrate error"
21954
21955 test_398a() { # LU-4198
21956         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21957         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21958
21959         # request a new lock on client
21960         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21961
21962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21963         local lock_count=$($LCTL get_param -n \
21964                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21965         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21966
21967         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21968
21969         # no lock cached, should use lockless IO and not enqueue new lock
21970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21971         lock_count=$($LCTL get_param -n \
21972                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21973         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21974 }
21975 run_test 398a "direct IO should cancel lock otherwise lockless"
21976
21977 test_398b() { # LU-4198
21978         which fio || skip_env "no fio installed"
21979         $LFS setstripe -c -1 $DIR/$tfile
21980
21981         local size=12
21982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21983
21984         local njobs=4
21985         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21986         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21987                 --numjobs=$njobs --fallocate=none \
21988                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21989                 --filename=$DIR/$tfile &
21990         bg_pid=$!
21991
21992         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21993         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21994                 --numjobs=$njobs --fallocate=none \
21995                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21996                 --filename=$DIR/$tfile || true
21997         wait $bg_pid
21998
21999         rm -rf $DIR/$tfile
22000 }
22001 run_test 398b "DIO and buffer IO race"
22002
22003 test_398c() { # LU-4198
22004         which fio || skip_env "no fio installed"
22005
22006         saved_debug=$($LCTL get_param -n debug)
22007         $LCTL set_param debug=0
22008
22009         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22010         ((size /= 1024)) # by megabytes
22011         ((size /= 2)) # write half of the OST at most
22012         [ $size -gt 40 ] && size=40 #reduce test time anyway
22013
22014         $LFS setstripe -c 1 $DIR/$tfile
22015
22016         # it seems like ldiskfs reserves more space than necessary if the
22017         # writing blocks are not mapped, so it extends the file firstly
22018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22019         cancel_lru_locks osc
22020
22021         # clear and verify rpc_stats later
22022         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22023
22024         local njobs=4
22025         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22026         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22027                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22028                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22029                 --filename=$DIR/$tfile
22030         [ $? -eq 0 ] || error "fio write error"
22031
22032         [ $($LCTL get_param -n \
22033          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22034                 error "Locks were requested while doing AIO"
22035
22036         # get the percentage of 1-page I/O
22037         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22038                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22039                 awk '{print $7}')
22040         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22041
22042         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22043         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22044                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22045                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22046                 --filename=$DIR/$tfile
22047         [ $? -eq 0 ] || error "fio mixed read write error"
22048
22049         echo "AIO with large block size ${size}M"
22050         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22051                 --numjobs=1 --fallocate=none --ioengine=libaio \
22052                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22053                 --filename=$DIR/$tfile
22054         [ $? -eq 0 ] || error "fio large block size failed"
22055
22056         rm -rf $DIR/$tfile
22057         $LCTL set_param debug="$saved_debug"
22058 }
22059 run_test 398c "run fio to test AIO"
22060
22061 test_398d() { #  LU-13846
22062         test -f aiocp || skip_env "no aiocp installed"
22063         local aio_file=$DIR/aio_file
22064
22065         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22066
22067         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22068         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22069
22070         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22071
22072         # make sure we don't crash and fail properly
22073         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22074                 error "aio not aligned with PAGE SIZE should fail"
22075
22076         rm -rf $DIR/$tfile $aio_file
22077 }
22078 run_test 398d "run aiocp to verify block size > stripe size"
22079
22080 test_fake_rw() {
22081         local read_write=$1
22082         if [ "$read_write" = "write" ]; then
22083                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22084         elif [ "$read_write" = "read" ]; then
22085                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22086         else
22087                 error "argument error"
22088         fi
22089
22090         # turn off debug for performance testing
22091         local saved_debug=$($LCTL get_param -n debug)
22092         $LCTL set_param debug=0
22093
22094         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22095
22096         # get ost1 size - $FSNAME-OST0000
22097         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22098         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22099         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22100
22101         if [ "$read_write" = "read" ]; then
22102                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22103         fi
22104
22105         local start_time=$(date +%s.%N)
22106         $dd_cmd bs=1M count=$blocks oflag=sync ||
22107                 error "real dd $read_write error"
22108         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22109
22110         if [ "$read_write" = "write" ]; then
22111                 rm -f $DIR/$tfile
22112         fi
22113
22114         # define OBD_FAIL_OST_FAKE_RW           0x238
22115         do_facet ost1 $LCTL set_param fail_loc=0x238
22116
22117         local start_time=$(date +%s.%N)
22118         $dd_cmd bs=1M count=$blocks oflag=sync ||
22119                 error "fake dd $read_write error"
22120         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22121
22122         if [ "$read_write" = "write" ]; then
22123                 # verify file size
22124                 cancel_lru_locks osc
22125                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22126                         error "$tfile size not $blocks MB"
22127         fi
22128         do_facet ost1 $LCTL set_param fail_loc=0
22129
22130         echo "fake $read_write $duration_fake vs. normal $read_write" \
22131                 "$duration in seconds"
22132         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22133                 error_not_in_vm "fake write is slower"
22134
22135         $LCTL set_param -n debug="$saved_debug"
22136         rm -f $DIR/$tfile
22137 }
22138 test_399a() { # LU-7655 for OST fake write
22139         remote_ost_nodsh && skip "remote OST with nodsh"
22140
22141         test_fake_rw write
22142 }
22143 run_test 399a "fake write should not be slower than normal write"
22144
22145 test_399b() { # LU-8726 for OST fake read
22146         remote_ost_nodsh && skip "remote OST with nodsh"
22147         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22148                 skip_env "ldiskfs only test"
22149         fi
22150
22151         test_fake_rw read
22152 }
22153 run_test 399b "fake read should not be slower than normal read"
22154
22155 test_400a() { # LU-1606, was conf-sanity test_74
22156         if ! which $CC > /dev/null 2>&1; then
22157                 skip_env "$CC is not installed"
22158         fi
22159
22160         local extra_flags=''
22161         local out=$TMP/$tfile
22162         local prefix=/usr/include/lustre
22163         local prog
22164
22165         # Oleg removes c files in his test rig so test if any c files exist
22166         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22167                 skip_env "Needed c test files are missing"
22168
22169         if ! [[ -d $prefix ]]; then
22170                 # Assume we're running in tree and fixup the include path.
22171                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22172                 extra_flags+=" -L$LUSTRE/utils/.lib"
22173         fi
22174
22175         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22176                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22177                         error "client api broken"
22178         done
22179         rm -f $out
22180 }
22181 run_test 400a "Lustre client api program can compile and link"
22182
22183 test_400b() { # LU-1606, LU-5011
22184         local header
22185         local out=$TMP/$tfile
22186         local prefix=/usr/include/linux/lustre
22187
22188         # We use a hard coded prefix so that this test will not fail
22189         # when run in tree. There are headers in lustre/include/lustre/
22190         # that are not packaged (like lustre_idl.h) and have more
22191         # complicated include dependencies (like config.h and lnet/types.h).
22192         # Since this test about correct packaging we just skip them when
22193         # they don't exist (see below) rather than try to fixup cppflags.
22194
22195         if ! which $CC > /dev/null 2>&1; then
22196                 skip_env "$CC is not installed"
22197         fi
22198
22199         for header in $prefix/*.h; do
22200                 if ! [[ -f "$header" ]]; then
22201                         continue
22202                 fi
22203
22204                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22205                         continue # lustre_ioctl.h is internal header
22206                 fi
22207
22208                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22209                         error "cannot compile '$header'"
22210         done
22211         rm -f $out
22212 }
22213 run_test 400b "packaged headers can be compiled"
22214
22215 test_401a() { #LU-7437
22216         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22217         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22218
22219         #count the number of parameters by "list_param -R"
22220         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22221         #count the number of parameters by listing proc files
22222         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22223         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22224         echo "proc_dirs='$proc_dirs'"
22225         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22226         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22227                       sort -u | wc -l)
22228
22229         [ $params -eq $procs ] ||
22230                 error "found $params parameters vs. $procs proc files"
22231
22232         # test the list_param -D option only returns directories
22233         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22234         #count the number of parameters by listing proc directories
22235         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22236                 sort -u | wc -l)
22237
22238         [ $params -eq $procs ] ||
22239                 error "found $params parameters vs. $procs proc files"
22240 }
22241 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22242
22243 test_401b() {
22244         # jobid_var may not allow arbitrary values, so use jobid_name
22245         # if available
22246         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22247                 local testname=jobid_name tmp='testing%p'
22248         else
22249                 local testname=jobid_var tmp=testing
22250         fi
22251
22252         local save=$($LCTL get_param -n $testname)
22253
22254         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22255                 error "no error returned when setting bad parameters"
22256
22257         local jobid_new=$($LCTL get_param -n foe $testname baz)
22258         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22259
22260         $LCTL set_param -n fog=bam $testname=$save bat=fog
22261         local jobid_old=$($LCTL get_param -n foe $testname bag)
22262         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22263 }
22264 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22265
22266 test_401c() {
22267         # jobid_var may not allow arbitrary values, so use jobid_name
22268         # if available
22269         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22270                 local testname=jobid_name
22271         else
22272                 local testname=jobid_var
22273         fi
22274
22275         local jobid_var_old=$($LCTL get_param -n $testname)
22276         local jobid_var_new
22277
22278         $LCTL set_param $testname= &&
22279                 error "no error returned for 'set_param a='"
22280
22281         jobid_var_new=$($LCTL get_param -n $testname)
22282         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22283                 error "$testname was changed by setting without value"
22284
22285         $LCTL set_param $testname &&
22286                 error "no error returned for 'set_param a'"
22287
22288         jobid_var_new=$($LCTL get_param -n $testname)
22289         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22290                 error "$testname was changed by setting without value"
22291 }
22292 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22293
22294 test_401d() {
22295         # jobid_var may not allow arbitrary values, so use jobid_name
22296         # if available
22297         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22298                 local testname=jobid_name new_value='foo=bar%p'
22299         else
22300                 local testname=jobid_var new_valuie=foo=bar
22301         fi
22302
22303         local jobid_var_old=$($LCTL get_param -n $testname)
22304         local jobid_var_new
22305
22306         $LCTL set_param $testname=$new_value ||
22307                 error "'set_param a=b' did not accept a value containing '='"
22308
22309         jobid_var_new=$($LCTL get_param -n $testname)
22310         [[ "$jobid_var_new" == "$new_value" ]] ||
22311                 error "'set_param a=b' failed on a value containing '='"
22312
22313         # Reset the $testname to test the other format
22314         $LCTL set_param $testname=$jobid_var_old
22315         jobid_var_new=$($LCTL get_param -n $testname)
22316         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22317                 error "failed to reset $testname"
22318
22319         $LCTL set_param $testname $new_value ||
22320                 error "'set_param a b' did not accept a value containing '='"
22321
22322         jobid_var_new=$($LCTL get_param -n $testname)
22323         [[ "$jobid_var_new" == "$new_value" ]] ||
22324                 error "'set_param a b' failed on a value containing '='"
22325
22326         $LCTL set_param $testname $jobid_var_old
22327         jobid_var_new=$($LCTL get_param -n $testname)
22328         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22329                 error "failed to reset $testname"
22330 }
22331 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22332
22333 test_402() {
22334         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22335         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22336                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22337         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22338                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22339                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22340         remote_mds_nodsh && skip "remote MDS with nodsh"
22341
22342         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22343 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22344         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22345         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22346                 echo "Touch failed - OK"
22347 }
22348 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22349
22350 test_403() {
22351         local file1=$DIR/$tfile.1
22352         local file2=$DIR/$tfile.2
22353         local tfile=$TMP/$tfile
22354
22355         rm -f $file1 $file2 $tfile
22356
22357         touch $file1
22358         ln $file1 $file2
22359
22360         # 30 sec OBD_TIMEOUT in ll_getattr()
22361         # right before populating st_nlink
22362         $LCTL set_param fail_loc=0x80001409
22363         stat -c %h $file1 > $tfile &
22364
22365         # create an alias, drop all locks and reclaim the dentry
22366         < $file2
22367         cancel_lru_locks mdc
22368         cancel_lru_locks osc
22369         sysctl -w vm.drop_caches=2
22370
22371         wait
22372
22373         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22374
22375         rm -f $tfile $file1 $file2
22376 }
22377 run_test 403 "i_nlink should not drop to zero due to aliasing"
22378
22379 test_404() { # LU-6601
22380         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22381                 skip "Need server version newer than 2.8.52"
22382         remote_mds_nodsh && skip "remote MDS with nodsh"
22383
22384         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22385                 awk '/osp .*-osc-MDT/ { print $4}')
22386
22387         local osp
22388         for osp in $mosps; do
22389                 echo "Deactivate: " $osp
22390                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22391                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22392                         awk -vp=$osp '$4 == p { print $2 }')
22393                 [ $stat = IN ] || {
22394                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22395                         error "deactivate error"
22396                 }
22397                 echo "Activate: " $osp
22398                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22399                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22400                         awk -vp=$osp '$4 == p { print $2 }')
22401                 [ $stat = UP ] || {
22402                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22403                         error "activate error"
22404                 }
22405         done
22406 }
22407 run_test 404 "validate manual {de}activated works properly for OSPs"
22408
22409 test_405() {
22410         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22411         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22412                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22413                         skip "Layout swap lock is not supported"
22414
22415         check_swap_layouts_support
22416         check_swap_layout_no_dom $DIR
22417
22418         test_mkdir $DIR/$tdir
22419         swap_lock_test -d $DIR/$tdir ||
22420                 error "One layout swap locked test failed"
22421 }
22422 run_test 405 "Various layout swap lock tests"
22423
22424 test_406() {
22425         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22426         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22427         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22429         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22430                 skip "Need MDS version at least 2.8.50"
22431
22432         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22433         local test_pool=$TESTNAME
22434
22435         pool_add $test_pool || error "pool_add failed"
22436         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22437                 error "pool_add_targets failed"
22438
22439         save_layout_restore_at_exit $MOUNT
22440
22441         # parent set default stripe count only, child will stripe from both
22442         # parent and fs default
22443         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22444                 error "setstripe $MOUNT failed"
22445         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22446         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22447         for i in $(seq 10); do
22448                 local f=$DIR/$tdir/$tfile.$i
22449                 touch $f || error "touch failed"
22450                 local count=$($LFS getstripe -c $f)
22451                 [ $count -eq $OSTCOUNT ] ||
22452                         error "$f stripe count $count != $OSTCOUNT"
22453                 local offset=$($LFS getstripe -i $f)
22454                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22455                 local size=$($LFS getstripe -S $f)
22456                 [ $size -eq $((def_stripe_size * 2)) ] ||
22457                         error "$f stripe size $size != $((def_stripe_size * 2))"
22458                 local pool=$($LFS getstripe -p $f)
22459                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22460         done
22461
22462         # change fs default striping, delete parent default striping, now child
22463         # will stripe from new fs default striping only
22464         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22465                 error "change $MOUNT default stripe failed"
22466         $LFS setstripe -c 0 $DIR/$tdir ||
22467                 error "delete $tdir default stripe failed"
22468         for i in $(seq 11 20); do
22469                 local f=$DIR/$tdir/$tfile.$i
22470                 touch $f || error "touch $f failed"
22471                 local count=$($LFS getstripe -c $f)
22472                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22473                 local offset=$($LFS getstripe -i $f)
22474                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22475                 local size=$($LFS getstripe -S $f)
22476                 [ $size -eq $def_stripe_size ] ||
22477                         error "$f stripe size $size != $def_stripe_size"
22478                 local pool=$($LFS getstripe -p $f)
22479                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22480         done
22481
22482         unlinkmany $DIR/$tdir/$tfile. 1 20
22483
22484         local f=$DIR/$tdir/$tfile
22485         pool_remove_all_targets $test_pool $f
22486         pool_remove $test_pool $f
22487 }
22488 run_test 406 "DNE support fs default striping"
22489
22490 test_407() {
22491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22492         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22493                 skip "Need MDS version at least 2.8.55"
22494         remote_mds_nodsh && skip "remote MDS with nodsh"
22495
22496         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22497                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22498         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22499                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22500         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22501
22502         #define OBD_FAIL_DT_TXN_STOP    0x2019
22503         for idx in $(seq $MDSCOUNT); do
22504                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22505         done
22506         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22507         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22508                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22509         true
22510 }
22511 run_test 407 "transaction fail should cause operation fail"
22512
22513 test_408() {
22514         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22515
22516         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22517         lctl set_param fail_loc=0x8000040a
22518         # let ll_prepare_partial_page() fail
22519         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22520
22521         rm -f $DIR/$tfile
22522
22523         # create at least 100 unused inodes so that
22524         # shrink_icache_memory(0) should not return 0
22525         touch $DIR/$tfile-{0..100}
22526         rm -f $DIR/$tfile-{0..100}
22527         sync
22528
22529         echo 2 > /proc/sys/vm/drop_caches
22530 }
22531 run_test 408 "drop_caches should not hang due to page leaks"
22532
22533 test_409()
22534 {
22535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22536
22537         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22538         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22539         touch $DIR/$tdir/guard || error "(2) Fail to create"
22540
22541         local PREFIX=$(str_repeat 'A' 128)
22542         echo "Create 1K hard links start at $(date)"
22543         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22544                 error "(3) Fail to hard link"
22545
22546         echo "Links count should be right although linkEA overflow"
22547         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22548         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22549         [ $linkcount -eq 1001 ] ||
22550                 error "(5) Unexpected hard links count: $linkcount"
22551
22552         echo "List all links start at $(date)"
22553         ls -l $DIR/$tdir/foo > /dev/null ||
22554                 error "(6) Fail to list $DIR/$tdir/foo"
22555
22556         echo "Unlink hard links start at $(date)"
22557         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22558                 error "(7) Fail to unlink"
22559         echo "Unlink hard links finished at $(date)"
22560 }
22561 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22562
22563 test_410()
22564 {
22565         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22566                 skip "Need client version at least 2.9.59"
22567         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22568                 skip "Need MODULES build"
22569
22570         # Create a file, and stat it from the kernel
22571         local testfile=$DIR/$tfile
22572         touch $testfile
22573
22574         local run_id=$RANDOM
22575         local my_ino=$(stat --format "%i" $testfile)
22576
22577         # Try to insert the module. This will always fail as the
22578         # module is designed to not be inserted.
22579         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22580             &> /dev/null
22581
22582         # Anything but success is a test failure
22583         dmesg | grep -q \
22584             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22585             error "no inode match"
22586 }
22587 run_test 410 "Test inode number returned from kernel thread"
22588
22589 cleanup_test411_cgroup() {
22590         trap 0
22591         rmdir "$1"
22592 }
22593
22594 test_411() {
22595         local cg_basedir=/sys/fs/cgroup/memory
22596         # LU-9966
22597         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22598                 skip "no setup for cgroup"
22599
22600         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22601                 error "test file creation failed"
22602         cancel_lru_locks osc
22603
22604         # Create a very small memory cgroup to force a slab allocation error
22605         local cgdir=$cg_basedir/osc_slab_alloc
22606         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22607         trap "cleanup_test411_cgroup $cgdir" EXIT
22608         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22609         echo 1M > $cgdir/memory.limit_in_bytes
22610
22611         # Should not LBUG, just be killed by oom-killer
22612         # dd will return 0 even allocation failure in some environment.
22613         # So don't check return value
22614         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22615         cleanup_test411_cgroup $cgdir
22616
22617         return 0
22618 }
22619 run_test 411 "Slab allocation error with cgroup does not LBUG"
22620
22621 test_412() {
22622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22623         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22624                 skip "Need server version at least 2.10.55"
22625         fi
22626
22627         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22628                 error "mkdir failed"
22629         $LFS getdirstripe $DIR/$tdir
22630         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22631         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22632                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22633         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22634         [ $stripe_count -eq 2 ] ||
22635                 error "expect 2 get $stripe_count"
22636 }
22637 run_test 412 "mkdir on specific MDTs"
22638
22639 test_qos_mkdir() {
22640         local mkdir_cmd=$1
22641         local stripe_count=$2
22642         local mdts=$(comma_list $(mdts_nodes))
22643
22644         local testdir
22645         local lmv_qos_prio_free
22646         local lmv_qos_threshold_rr
22647         local lmv_qos_maxage
22648         local lod_qos_prio_free
22649         local lod_qos_threshold_rr
22650         local lod_qos_maxage
22651         local count
22652         local i
22653
22654         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22655         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22656         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22657                 head -n1)
22658         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22659         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22660         stack_trap "$LCTL set_param \
22661                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22662         stack_trap "$LCTL set_param \
22663                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22664         stack_trap "$LCTL set_param \
22665                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22666
22667         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22668                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22669         lod_qos_prio_free=${lod_qos_prio_free%%%}
22670         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22671                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22672         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22673         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22674                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22675         stack_trap "do_nodes $mdts $LCTL set_param \
22676                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22677         stack_trap "do_nodes $mdts $LCTL set_param \
22678                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22679                 EXIT
22680         stack_trap "do_nodes $mdts $LCTL set_param \
22681                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22682
22683         echo
22684         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22685
22686         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22687         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22688
22689         testdir=$DIR/$tdir-s$stripe_count/rr
22690
22691         for i in $(seq $((100 * MDSCOUNT))); do
22692                 eval $mkdir_cmd $testdir/subdir$i ||
22693                         error "$mkdir_cmd subdir$i failed"
22694         done
22695
22696         for i in $(seq $MDSCOUNT); do
22697                 count=$($LFS getdirstripe -i $testdir/* |
22698                                 grep ^$((i - 1))$ | wc -l)
22699                 echo "$count directories created on MDT$((i - 1))"
22700                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22701
22702                 if [ $stripe_count -gt 1 ]; then
22703                         count=$($LFS getdirstripe $testdir/* |
22704                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22705                         echo "$count stripes created on MDT$((i - 1))"
22706                         # deviation should < 5% of average
22707                         [ $count -lt $((95 * stripe_count)) ] ||
22708                         [ $count -gt $((105 * stripe_count)) ] &&
22709                                 error "stripes are not evenly distributed"
22710                 fi
22711         done
22712
22713         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22714         do_nodes $mdts $LCTL set_param \
22715                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22716
22717         echo
22718         echo "Check for uneven MDTs: "
22719
22720         local ffree
22721         local bavail
22722         local max
22723         local min
22724         local max_index
22725         local min_index
22726         local tmp
22727
22728         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22729         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22730         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22731
22732         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22733         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22734         max_index=0
22735         min_index=0
22736         for ((i = 1; i < ${#ffree[@]}; i++)); do
22737                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22738                 if [ $tmp -gt $max ]; then
22739                         max=$tmp
22740                         max_index=$i
22741                 fi
22742                 if [ $tmp -lt $min ]; then
22743                         min=$tmp
22744                         min_index=$i
22745                 fi
22746         done
22747
22748         [ ${ffree[min_index]} -eq 0 ] &&
22749                 skip "no free files in MDT$min_index"
22750         [ ${ffree[min_index]} -gt 100000000 ] &&
22751                 skip "too much free files in MDT$min_index"
22752
22753         # Check if we need to generate uneven MDTs
22754         local threshold=50
22755         local diff=$(((max - min) * 100 / min))
22756         local value="$(generate_string 1024)"
22757
22758         while [ $diff -lt $threshold ]; do
22759                 # generate uneven MDTs, create till $threshold% diff
22760                 echo -n "weight diff=$diff% must be > $threshold% ..."
22761                 count=$((${ffree[min_index]} / 10))
22762                 # 50 sec per 10000 files in vm
22763                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22764                         skip "$count files to create"
22765                 echo "Fill MDT$min_index with $count files"
22766                 [ -d $DIR/$tdir-MDT$min_index ] ||
22767                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22768                         error "mkdir $tdir-MDT$min_index failed"
22769                 for i in $(seq $count); do
22770                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22771                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22772                                 error "create f$j_$i failed"
22773                         setfattr -n user.413b -v $value \
22774                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22775                                 error "setfattr f$j_$i failed"
22776                 done
22777
22778                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22779                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22780                 max=$(((${ffree[max_index]} >> 8) * \
22781                         (${bavail[max_index]} * bsize >> 16)))
22782                 min=$(((${ffree[min_index]} >> 8) * \
22783                         (${bavail[min_index]} * bsize >> 16)))
22784                 diff=$(((max - min) * 100 / min))
22785         done
22786
22787         echo "MDT filesfree available: ${ffree[@]}"
22788         echo "MDT blocks available: ${bavail[@]}"
22789         echo "weight diff=$diff%"
22790
22791         echo
22792         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22793
22794         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22795         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22796         # decrease statfs age, so that it can be updated in time
22797         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22798         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22799
22800         sleep 1
22801
22802         testdir=$DIR/$tdir-s$stripe_count/qos
22803
22804         for i in $(seq $((100 * MDSCOUNT))); do
22805                 eval $mkdir_cmd $testdir/subdir$i ||
22806                         error "$mkdir_cmd subdir$i failed"
22807         done
22808
22809         for i in $(seq $MDSCOUNT); do
22810                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22811                         wc -l)
22812                 echo "$count directories created on MDT$((i - 1))"
22813
22814                 if [ $stripe_count -gt 1 ]; then
22815                         count=$($LFS getdirstripe $testdir/* |
22816                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22817                         echo "$count stripes created on MDT$((i - 1))"
22818                 fi
22819         done
22820
22821         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22822         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22823
22824         # D-value should > 10% of averge
22825         [ $((max - min)) -lt 10 ] &&
22826                 error "subdirs shouldn't be evenly distributed"
22827
22828         # ditto
22829         if [ $stripe_count -gt 1 ]; then
22830                 max=$($LFS getdirstripe $testdir/* |
22831                         grep -P "^\s+$max_index\t" | wc -l)
22832                 min=$($LFS getdirstripe $testdir/* |
22833                         grep -P "^\s+$min_index\t" | wc -l)
22834                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22835                         error "stripes shouldn't be evenly distributed"|| true
22836         fi
22837 }
22838
22839 test_413a() {
22840         [ $MDSCOUNT -lt 2 ] &&
22841                 skip "We need at least 2 MDTs for this test"
22842
22843         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22844                 skip "Need server version at least 2.12.52"
22845
22846         local stripe_count
22847
22848         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22849                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22850                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22851                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22852                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22853         done
22854 }
22855 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22856
22857 test_413b() {
22858         [ $MDSCOUNT -lt 2 ] &&
22859                 skip "We need at least 2 MDTs for this test"
22860
22861         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22862                 skip "Need server version at least 2.12.52"
22863
22864         local stripe_count
22865
22866         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22867                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22868                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22869                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22870                 $LFS setdirstripe -D -c $stripe_count \
22871                         $DIR/$tdir-s$stripe_count/rr ||
22872                         error "setdirstripe failed"
22873                 $LFS setdirstripe -D -c $stripe_count \
22874                         $DIR/$tdir-s$stripe_count/qos ||
22875                         error "setdirstripe failed"
22876                 test_qos_mkdir "mkdir" $stripe_count
22877         done
22878 }
22879 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22880
22881 test_414() {
22882 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22883         $LCTL set_param fail_loc=0x80000521
22884         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22885         rm -f $DIR/$tfile
22886 }
22887 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22888
22889 test_415() {
22890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22891         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22892                 skip "Need server version at least 2.11.52"
22893
22894         # LU-11102
22895         local total
22896         local setattr_pid
22897         local start_time
22898         local end_time
22899         local duration
22900
22901         total=500
22902         # this test may be slow on ZFS
22903         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22904
22905         # though this test is designed for striped directory, let's test normal
22906         # directory too since lock is always saved as CoS lock.
22907         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22908         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22909
22910         (
22911                 while true; do
22912                         touch $DIR/$tdir
22913                 done
22914         ) &
22915         setattr_pid=$!
22916
22917         start_time=$(date +%s)
22918         for i in $(seq $total); do
22919                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22920                         > /dev/null
22921         done
22922         end_time=$(date +%s)
22923         duration=$((end_time - start_time))
22924
22925         kill -9 $setattr_pid
22926
22927         echo "rename $total files took $duration sec"
22928         [ $duration -lt 100 ] || error "rename took $duration sec"
22929 }
22930 run_test 415 "lock revoke is not missing"
22931
22932 test_416() {
22933         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22934                 skip "Need server version at least 2.11.55"
22935
22936         # define OBD_FAIL_OSD_TXN_START    0x19a
22937         do_facet mds1 lctl set_param fail_loc=0x19a
22938
22939         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22940
22941         true
22942 }
22943 run_test 416 "transaction start failure won't cause system hung"
22944
22945 cleanup_417() {
22946         trap 0
22947         do_nodes $(comma_list $(mdts_nodes)) \
22948                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22949         do_nodes $(comma_list $(mdts_nodes)) \
22950                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22951         do_nodes $(comma_list $(mdts_nodes)) \
22952                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22953 }
22954
22955 test_417() {
22956         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22957         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22958                 skip "Need MDS version at least 2.11.56"
22959
22960         trap cleanup_417 RETURN EXIT
22961
22962         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22963         do_nodes $(comma_list $(mdts_nodes)) \
22964                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22965         $LFS migrate -m 0 $DIR/$tdir.1 &&
22966                 error "migrate dir $tdir.1 should fail"
22967
22968         do_nodes $(comma_list $(mdts_nodes)) \
22969                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22970         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22971                 error "create remote dir $tdir.2 should fail"
22972
22973         do_nodes $(comma_list $(mdts_nodes)) \
22974                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22975         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22976                 error "create striped dir $tdir.3 should fail"
22977         true
22978 }
22979 run_test 417 "disable remote dir, striped dir and dir migration"
22980
22981 # Checks that the outputs of df [-i] and lfs df [-i] match
22982 #
22983 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22984 check_lfs_df() {
22985         local dir=$2
22986         local inodes
22987         local df_out
22988         local lfs_df_out
22989         local count
22990         local passed=false
22991
22992         # blocks or inodes
22993         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22994
22995         for count in {1..100}; do
22996                 cancel_lru_locks
22997                 sync; sleep 0.2
22998
22999                 # read the lines of interest
23000                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23001                         error "df $inodes $dir | tail -n +2 failed"
23002                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23003                         error "lfs df $inodes $dir | grep summary: failed"
23004
23005                 # skip first substrings of each output as they are different
23006                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23007                 # compare the two outputs
23008                 passed=true
23009                 for i in {1..5}; do
23010                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23011                 done
23012                 $passed && break
23013         done
23014
23015         if ! $passed; then
23016                 df -P $inodes $dir
23017                 echo
23018                 lfs df $inodes $dir
23019                 error "df and lfs df $1 output mismatch: "      \
23020                       "df ${inodes}: ${df_out[*]}, "            \
23021                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23022         fi
23023 }
23024
23025 test_418() {
23026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23027
23028         local dir=$DIR/$tdir
23029         local numfiles=$((RANDOM % 4096 + 2))
23030         local numblocks=$((RANDOM % 256 + 1))
23031
23032         wait_delete_completed
23033         test_mkdir $dir
23034
23035         # check block output
23036         check_lfs_df blocks $dir
23037         # check inode output
23038         check_lfs_df inodes $dir
23039
23040         # create a single file and retest
23041         echo "Creating a single file and testing"
23042         createmany -o $dir/$tfile- 1 &>/dev/null ||
23043                 error "creating 1 file in $dir failed"
23044         check_lfs_df blocks $dir
23045         check_lfs_df inodes $dir
23046
23047         # create a random number of files
23048         echo "Creating $((numfiles - 1)) files and testing"
23049         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23050                 error "creating $((numfiles - 1)) files in $dir failed"
23051
23052         # write a random number of blocks to the first test file
23053         echo "Writing $numblocks 4K blocks and testing"
23054         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23055                 count=$numblocks &>/dev/null ||
23056                 error "dd to $dir/${tfile}-0 failed"
23057
23058         # retest
23059         check_lfs_df blocks $dir
23060         check_lfs_df inodes $dir
23061
23062         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23063                 error "unlinking $numfiles files in $dir failed"
23064 }
23065 run_test 418 "df and lfs df outputs match"
23066
23067 test_419()
23068 {
23069         local dir=$DIR/$tdir
23070
23071         mkdir -p $dir
23072         touch $dir/file
23073
23074         cancel_lru_locks mdc
23075
23076         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23077         $LCTL set_param fail_loc=0x1410
23078         cat $dir/file
23079         $LCTL set_param fail_loc=0
23080         rm -rf $dir
23081 }
23082 run_test 419 "Verify open file by name doesn't crash kernel"
23083
23084 test_420()
23085 {
23086         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23087                 skip "Need MDS version at least 2.12.53"
23088
23089         local SAVE_UMASK=$(umask)
23090         local dir=$DIR/$tdir
23091         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23092
23093         mkdir -p $dir
23094         umask 0000
23095         mkdir -m03777 $dir/testdir
23096         ls -dn $dir/testdir
23097         # Need to remove trailing '.' when SELinux is enabled
23098         local dirperms=$(ls -dn $dir/testdir |
23099                          awk '{ sub(/\.$/, "", $1); print $1}')
23100         [ $dirperms == "drwxrwsrwt" ] ||
23101                 error "incorrect perms on $dir/testdir"
23102
23103         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23104                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23105         ls -n $dir/testdir/testfile
23106         local fileperms=$(ls -n $dir/testdir/testfile |
23107                           awk '{ sub(/\.$/, "", $1); print $1}')
23108         [ $fileperms == "-rwxr-xr-x" ] ||
23109                 error "incorrect perms on $dir/testdir/testfile"
23110
23111         umask $SAVE_UMASK
23112 }
23113 run_test 420 "clear SGID bit on non-directories for non-members"
23114
23115 test_421a() {
23116         local cnt
23117         local fid1
23118         local fid2
23119
23120         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23121                 skip "Need MDS version at least 2.12.54"
23122
23123         test_mkdir $DIR/$tdir
23124         createmany -o $DIR/$tdir/f 3
23125         cnt=$(ls -1 $DIR/$tdir | wc -l)
23126         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23127
23128         fid1=$(lfs path2fid $DIR/$tdir/f1)
23129         fid2=$(lfs path2fid $DIR/$tdir/f2)
23130         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23131
23132         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23133         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23134
23135         cnt=$(ls -1 $DIR/$tdir | wc -l)
23136         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23137
23138         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23139         createmany -o $DIR/$tdir/f 3
23140         cnt=$(ls -1 $DIR/$tdir | wc -l)
23141         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23142
23143         fid1=$(lfs path2fid $DIR/$tdir/f1)
23144         fid2=$(lfs path2fid $DIR/$tdir/f2)
23145         echo "remove using fsname $FSNAME"
23146         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23147
23148         cnt=$(ls -1 $DIR/$tdir | wc -l)
23149         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23150 }
23151 run_test 421a "simple rm by fid"
23152
23153 test_421b() {
23154         local cnt
23155         local FID1
23156         local FID2
23157
23158         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23159                 skip "Need MDS version at least 2.12.54"
23160
23161         test_mkdir $DIR/$tdir
23162         createmany -o $DIR/$tdir/f 3
23163         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23164         MULTIPID=$!
23165
23166         FID1=$(lfs path2fid $DIR/$tdir/f1)
23167         FID2=$(lfs path2fid $DIR/$tdir/f2)
23168         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23169
23170         kill -USR1 $MULTIPID
23171         wait
23172
23173         cnt=$(ls $DIR/$tdir | wc -l)
23174         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23175 }
23176 run_test 421b "rm by fid on open file"
23177
23178 test_421c() {
23179         local cnt
23180         local FIDS
23181
23182         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23183                 skip "Need MDS version at least 2.12.54"
23184
23185         test_mkdir $DIR/$tdir
23186         createmany -o $DIR/$tdir/f 3
23187         touch $DIR/$tdir/$tfile
23188         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23189         cnt=$(ls -1 $DIR/$tdir | wc -l)
23190         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23191
23192         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23193         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23194
23195         cnt=$(ls $DIR/$tdir | wc -l)
23196         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23197 }
23198 run_test 421c "rm by fid against hardlinked files"
23199
23200 test_421d() {
23201         local cnt
23202         local FIDS
23203
23204         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23205                 skip "Need MDS version at least 2.12.54"
23206
23207         test_mkdir $DIR/$tdir
23208         createmany -o $DIR/$tdir/f 4097
23209         cnt=$(ls -1 $DIR/$tdir | wc -l)
23210         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23211
23212         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23213         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23214
23215         cnt=$(ls $DIR/$tdir | wc -l)
23216         rm -rf $DIR/$tdir
23217         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23218 }
23219 run_test 421d "rmfid en masse"
23220
23221 test_421e() {
23222         local cnt
23223         local FID
23224
23225         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23226         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23227                 skip "Need MDS version at least 2.12.54"
23228
23229         mkdir -p $DIR/$tdir
23230         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23231         createmany -o $DIR/$tdir/striped_dir/f 512
23232         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23233         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23234
23235         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23236                 sed "s/[/][^:]*://g")
23237         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23238
23239         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23240         rm -rf $DIR/$tdir
23241         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23242 }
23243 run_test 421e "rmfid in DNE"
23244
23245 test_421f() {
23246         local cnt
23247         local FID
23248
23249         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23250                 skip "Need MDS version at least 2.12.54"
23251
23252         test_mkdir $DIR/$tdir
23253         touch $DIR/$tdir/f
23254         cnt=$(ls -1 $DIR/$tdir | wc -l)
23255         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23256
23257         FID=$(lfs path2fid $DIR/$tdir/f)
23258         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23259         # rmfid should fail
23260         cnt=$(ls -1 $DIR/$tdir | wc -l)
23261         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23262
23263         chmod a+rw $DIR/$tdir
23264         ls -la $DIR/$tdir
23265         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23266         # rmfid should fail
23267         cnt=$(ls -1 $DIR/$tdir | wc -l)
23268         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23269
23270         rm -f $DIR/$tdir/f
23271         $RUNAS touch $DIR/$tdir/f
23272         FID=$(lfs path2fid $DIR/$tdir/f)
23273         echo "rmfid as root"
23274         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23275         cnt=$(ls -1 $DIR/$tdir | wc -l)
23276         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23277
23278         rm -f $DIR/$tdir/f
23279         $RUNAS touch $DIR/$tdir/f
23280         cnt=$(ls -1 $DIR/$tdir | wc -l)
23281         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23282         FID=$(lfs path2fid $DIR/$tdir/f)
23283         # rmfid w/o user_fid2path mount option should fail
23284         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23285         cnt=$(ls -1 $DIR/$tdir | wc -l)
23286         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23287
23288         umount_client $MOUNT || error "failed to umount client"
23289         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23290                 error "failed to mount client'"
23291
23292         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23293         # rmfid should succeed
23294         cnt=$(ls -1 $DIR/$tdir | wc -l)
23295         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23296
23297         # rmfid shouldn't allow to remove files due to dir's permission
23298         chmod a+rwx $DIR/$tdir
23299         touch $DIR/$tdir/f
23300         ls -la $DIR/$tdir
23301         FID=$(lfs path2fid $DIR/$tdir/f)
23302         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23303
23304         umount_client $MOUNT || error "failed to umount client"
23305         mount_client $MOUNT "$MOUNT_OPTS" ||
23306                 error "failed to mount client'"
23307
23308 }
23309 run_test 421f "rmfid checks permissions"
23310
23311 test_421g() {
23312         local cnt
23313         local FIDS
23314
23315         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23316         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23317                 skip "Need MDS version at least 2.12.54"
23318
23319         mkdir -p $DIR/$tdir
23320         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23321         createmany -o $DIR/$tdir/striped_dir/f 512
23322         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23323         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23324
23325         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23326                 sed "s/[/][^:]*://g")
23327
23328         rm -f $DIR/$tdir/striped_dir/f1*
23329         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23330         removed=$((512 - cnt))
23331
23332         # few files have been just removed, so we expect
23333         # rmfid to fail on their fids
23334         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23335         [ $removed != $errors ] && error "$errors != $removed"
23336
23337         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23338         rm -rf $DIR/$tdir
23339         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23340 }
23341 run_test 421g "rmfid to return errors properly"
23342
23343 test_422() {
23344         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23345         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23346         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23347         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23348         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23349
23350         local amc=$(at_max_get client)
23351         local amo=$(at_max_get mds1)
23352         local timeout=`lctl get_param -n timeout`
23353
23354         at_max_set 0 client
23355         at_max_set 0 mds1
23356
23357 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23358         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23359                         fail_val=$(((2*timeout + 10)*1000))
23360         touch $DIR/$tdir/d3/file &
23361         sleep 2
23362 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23363         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23364                         fail_val=$((2*timeout + 5))
23365         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23366         local pid=$!
23367         sleep 1
23368         kill -9 $pid
23369         sleep $((2 * timeout))
23370         echo kill $pid
23371         kill -9 $pid
23372         lctl mark touch
23373         touch $DIR/$tdir/d2/file3
23374         touch $DIR/$tdir/d2/file4
23375         touch $DIR/$tdir/d2/file5
23376
23377         wait
23378         at_max_set $amc client
23379         at_max_set $amo mds1
23380
23381         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23382         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23383                 error "Watchdog is always throttled"
23384 }
23385 run_test 422 "kill a process with RPC in progress"
23386
23387 stat_test() {
23388     df -h $MOUNT &
23389     df -h $MOUNT &
23390     df -h $MOUNT &
23391     df -h $MOUNT &
23392     df -h $MOUNT &
23393     df -h $MOUNT &
23394 }
23395
23396 test_423() {
23397     local _stats
23398     # ensure statfs cache is expired
23399     sleep 2;
23400
23401     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23402     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23403
23404     return 0
23405 }
23406 run_test 423 "statfs should return a right data"
23407
23408 test_424() {
23409 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23410         $LCTL set_param fail_loc=0x80000522
23411         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23412         rm -f $DIR/$tfile
23413 }
23414 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23415
23416 test_425() {
23417         test_mkdir -c -1 $DIR/$tdir
23418         $LFS setstripe -c -1 $DIR/$tdir
23419
23420         lru_resize_disable "" 100
23421         stack_trap "lru_resize_enable" EXIT
23422
23423         sleep 5
23424
23425         for i in $(seq $((MDSCOUNT * 125))); do
23426                 local t=$DIR/$tdir/$tfile_$i
23427
23428                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23429                         error_noexit "Create file $t"
23430         done
23431         stack_trap "rm -rf $DIR/$tdir" EXIT
23432
23433         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23434                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23435                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23436
23437                 [ $lock_count -le $lru_size ] ||
23438                         error "osc lock count $lock_count > lru size $lru_size"
23439         done
23440
23441         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23442                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23443                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23444
23445                 [ $lock_count -le $lru_size ] ||
23446                         error "mdc lock count $lock_count > lru size $lru_size"
23447         done
23448 }
23449 run_test 425 "lock count should not exceed lru size"
23450
23451 prep_801() {
23452         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23453         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23454                 skip "Need server version at least 2.9.55"
23455
23456         start_full_debug_logging
23457 }
23458
23459 post_801() {
23460         stop_full_debug_logging
23461 }
23462
23463 barrier_stat() {
23464         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23465                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23466                            awk '/The barrier for/ { print $7 }')
23467                 echo $st
23468         else
23469                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23470                 echo \'$st\'
23471         fi
23472 }
23473
23474 barrier_expired() {
23475         local expired
23476
23477         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23478                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23479                           awk '/will be expired/ { print $7 }')
23480         else
23481                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23482         fi
23483
23484         echo $expired
23485 }
23486
23487 test_801a() {
23488         prep_801
23489
23490         echo "Start barrier_freeze at: $(date)"
23491         #define OBD_FAIL_BARRIER_DELAY          0x2202
23492         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23493         # Do not reduce barrier time - See LU-11873
23494         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23495
23496         sleep 2
23497         local b_status=$(barrier_stat)
23498         echo "Got barrier status at: $(date)"
23499         [ "$b_status" = "'freezing_p1'" ] ||
23500                 error "(1) unexpected barrier status $b_status"
23501
23502         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23503         wait
23504         b_status=$(barrier_stat)
23505         [ "$b_status" = "'frozen'" ] ||
23506                 error "(2) unexpected barrier status $b_status"
23507
23508         local expired=$(barrier_expired)
23509         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23510         sleep $((expired + 3))
23511
23512         b_status=$(barrier_stat)
23513         [ "$b_status" = "'expired'" ] ||
23514                 error "(3) unexpected barrier status $b_status"
23515
23516         # Do not reduce barrier time - See LU-11873
23517         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23518                 error "(4) fail to freeze barrier"
23519
23520         b_status=$(barrier_stat)
23521         [ "$b_status" = "'frozen'" ] ||
23522                 error "(5) unexpected barrier status $b_status"
23523
23524         echo "Start barrier_thaw at: $(date)"
23525         #define OBD_FAIL_BARRIER_DELAY          0x2202
23526         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23527         do_facet mgs $LCTL barrier_thaw $FSNAME &
23528
23529         sleep 2
23530         b_status=$(barrier_stat)
23531         echo "Got barrier status at: $(date)"
23532         [ "$b_status" = "'thawing'" ] ||
23533                 error "(6) unexpected barrier status $b_status"
23534
23535         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23536         wait
23537         b_status=$(barrier_stat)
23538         [ "$b_status" = "'thawed'" ] ||
23539                 error "(7) unexpected barrier status $b_status"
23540
23541         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23542         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23543         do_facet mgs $LCTL barrier_freeze $FSNAME
23544
23545         b_status=$(barrier_stat)
23546         [ "$b_status" = "'failed'" ] ||
23547                 error "(8) unexpected barrier status $b_status"
23548
23549         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23550         do_facet mgs $LCTL barrier_thaw $FSNAME
23551
23552         post_801
23553 }
23554 run_test 801a "write barrier user interfaces and stat machine"
23555
23556 test_801b() {
23557         prep_801
23558
23559         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23560         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23561         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23562         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23563         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23564
23565         cancel_lru_locks mdc
23566
23567         # 180 seconds should be long enough
23568         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23569
23570         local b_status=$(barrier_stat)
23571         [ "$b_status" = "'frozen'" ] ||
23572                 error "(6) unexpected barrier status $b_status"
23573
23574         mkdir $DIR/$tdir/d0/d10 &
23575         mkdir_pid=$!
23576
23577         touch $DIR/$tdir/d1/f13 &
23578         touch_pid=$!
23579
23580         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23581         ln_pid=$!
23582
23583         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23584         mv_pid=$!
23585
23586         rm -f $DIR/$tdir/d4/f12 &
23587         rm_pid=$!
23588
23589         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23590
23591         # To guarantee taht the 'stat' is not blocked
23592         b_status=$(barrier_stat)
23593         [ "$b_status" = "'frozen'" ] ||
23594                 error "(8) unexpected barrier status $b_status"
23595
23596         # let above commands to run at background
23597         sleep 5
23598
23599         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23600         ps -p $touch_pid || error "(10) touch should be blocked"
23601         ps -p $ln_pid || error "(11) link should be blocked"
23602         ps -p $mv_pid || error "(12) rename should be blocked"
23603         ps -p $rm_pid || error "(13) unlink should be blocked"
23604
23605         b_status=$(barrier_stat)
23606         [ "$b_status" = "'frozen'" ] ||
23607                 error "(14) unexpected barrier status $b_status"
23608
23609         do_facet mgs $LCTL barrier_thaw $FSNAME
23610         b_status=$(barrier_stat)
23611         [ "$b_status" = "'thawed'" ] ||
23612                 error "(15) unexpected barrier status $b_status"
23613
23614         wait $mkdir_pid || error "(16) mkdir should succeed"
23615         wait $touch_pid || error "(17) touch should succeed"
23616         wait $ln_pid || error "(18) link should succeed"
23617         wait $mv_pid || error "(19) rename should succeed"
23618         wait $rm_pid || error "(20) unlink should succeed"
23619
23620         post_801
23621 }
23622 run_test 801b "modification will be blocked by write barrier"
23623
23624 test_801c() {
23625         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23626
23627         prep_801
23628
23629         stop mds2 || error "(1) Fail to stop mds2"
23630
23631         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23632
23633         local b_status=$(barrier_stat)
23634         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23635                 do_facet mgs $LCTL barrier_thaw $FSNAME
23636                 error "(2) unexpected barrier status $b_status"
23637         }
23638
23639         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23640                 error "(3) Fail to rescan barrier bitmap"
23641
23642         # Do not reduce barrier time - See LU-11873
23643         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23644
23645         b_status=$(barrier_stat)
23646         [ "$b_status" = "'frozen'" ] ||
23647                 error "(4) unexpected barrier status $b_status"
23648
23649         do_facet mgs $LCTL barrier_thaw $FSNAME
23650         b_status=$(barrier_stat)
23651         [ "$b_status" = "'thawed'" ] ||
23652                 error "(5) unexpected barrier status $b_status"
23653
23654         local devname=$(mdsdevname 2)
23655
23656         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23657
23658         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23659                 error "(7) Fail to rescan barrier bitmap"
23660
23661         post_801
23662 }
23663 run_test 801c "rescan barrier bitmap"
23664
23665 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23666 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23667 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23668 saved_MOUNT_OPTS=$MOUNT_OPTS
23669
23670 cleanup_802a() {
23671         trap 0
23672
23673         stopall
23674         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23675         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23676         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23677         MOUNT_OPTS=$saved_MOUNT_OPTS
23678         setupall
23679 }
23680
23681 test_802a() {
23682         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23683         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23684         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23685                 skip "Need server version at least 2.9.55"
23686
23687         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23688
23689         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23690
23691         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23692                 error "(2) Fail to copy"
23693
23694         trap cleanup_802a EXIT
23695
23696         # sync by force before remount as readonly
23697         sync; sync_all_data; sleep 3; sync_all_data
23698
23699         stopall
23700
23701         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23702         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23703         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23704
23705         echo "Mount the server as read only"
23706         setupall server_only || error "(3) Fail to start servers"
23707
23708         echo "Mount client without ro should fail"
23709         mount_client $MOUNT &&
23710                 error "(4) Mount client without 'ro' should fail"
23711
23712         echo "Mount client with ro should succeed"
23713         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23714         mount_client $MOUNT ||
23715                 error "(5) Mount client with 'ro' should succeed"
23716
23717         echo "Modify should be refused"
23718         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23719
23720         echo "Read should be allowed"
23721         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23722                 error "(7) Read should succeed under ro mode"
23723
23724         cleanup_802a
23725 }
23726 run_test 802a "simulate readonly device"
23727
23728 test_802b() {
23729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23730         remote_mds_nodsh && skip "remote MDS with nodsh"
23731
23732         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23733                 skip "readonly option not available"
23734
23735         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23736
23737         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23738                 error "(2) Fail to copy"
23739
23740         # write back all cached data before setting MDT to readonly
23741         cancel_lru_locks
23742         sync_all_data
23743
23744         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23745         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23746
23747         echo "Modify should be refused"
23748         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23749
23750         echo "Read should be allowed"
23751         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23752                 error "(7) Read should succeed under ro mode"
23753
23754         # disable readonly
23755         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23756 }
23757 run_test 802b "be able to set MDTs to readonly"
23758
23759 test_803() {
23760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23761         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23762                 skip "MDS needs to be newer than 2.10.54"
23763
23764         mkdir -p $DIR/$tdir
23765         # Create some objects on all MDTs to trigger related logs objects
23766         for idx in $(seq $MDSCOUNT); do
23767                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23768                         $DIR/$tdir/dir${idx} ||
23769                         error "Fail to create $DIR/$tdir/dir${idx}"
23770         done
23771
23772         sync; sleep 3
23773         wait_delete_completed # ensure old test cleanups are finished
23774         echo "before create:"
23775         $LFS df -i $MOUNT
23776         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23777
23778         for i in {1..10}; do
23779                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23780                         error "Fail to create $DIR/$tdir/foo$i"
23781         done
23782
23783         sync; sleep 3
23784         echo "after create:"
23785         $LFS df -i $MOUNT
23786         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23787
23788         # allow for an llog to be cleaned up during the test
23789         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23790                 error "before ($before_used) + 10 > after ($after_used)"
23791
23792         for i in {1..10}; do
23793                 rm -rf $DIR/$tdir/foo$i ||
23794                         error "Fail to remove $DIR/$tdir/foo$i"
23795         done
23796
23797         sleep 3 # avoid MDT return cached statfs
23798         wait_delete_completed
23799         echo "after unlink:"
23800         $LFS df -i $MOUNT
23801         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23802
23803         # allow for an llog to be created during the test
23804         [ $after_used -le $((before_used + 1)) ] ||
23805                 error "after ($after_used) > before ($before_used) + 1"
23806 }
23807 run_test 803 "verify agent object for remote object"
23808
23809 test_804() {
23810         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23811         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23812                 skip "MDS needs to be newer than 2.10.54"
23813         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23814
23815         mkdir -p $DIR/$tdir
23816         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23817                 error "Fail to create $DIR/$tdir/dir0"
23818
23819         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23820         local dev=$(mdsdevname 2)
23821
23822         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23823                 grep ${fid} || error "NOT found agent entry for dir0"
23824
23825         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23826                 error "Fail to create $DIR/$tdir/dir1"
23827
23828         touch $DIR/$tdir/dir1/foo0 ||
23829                 error "Fail to create $DIR/$tdir/dir1/foo0"
23830         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23831         local rc=0
23832
23833         for idx in $(seq $MDSCOUNT); do
23834                 dev=$(mdsdevname $idx)
23835                 do_facet mds${idx} \
23836                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23837                         grep ${fid} && rc=$idx
23838         done
23839
23840         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23841                 error "Fail to rename foo0 to foo1"
23842         if [ $rc -eq 0 ]; then
23843                 for idx in $(seq $MDSCOUNT); do
23844                         dev=$(mdsdevname $idx)
23845                         do_facet mds${idx} \
23846                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23847                         grep ${fid} && rc=$idx
23848                 done
23849         fi
23850
23851         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23852                 error "Fail to rename foo1 to foo2"
23853         if [ $rc -eq 0 ]; then
23854                 for idx in $(seq $MDSCOUNT); do
23855                         dev=$(mdsdevname $idx)
23856                         do_facet mds${idx} \
23857                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23858                         grep ${fid} && rc=$idx
23859                 done
23860         fi
23861
23862         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23863
23864         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23865                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23866         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23867                 error "Fail to rename foo2 to foo0"
23868         unlink $DIR/$tdir/dir1/foo0 ||
23869                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23870         rm -rf $DIR/$tdir/dir0 ||
23871                 error "Fail to rm $DIR/$tdir/dir0"
23872
23873         for idx in $(seq $MDSCOUNT); do
23874                 dev=$(mdsdevname $idx)
23875                 rc=0
23876
23877                 stop mds${idx}
23878                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23879                         rc=$?
23880                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23881                         error "mount mds$idx failed"
23882                 df $MOUNT > /dev/null 2>&1
23883
23884                 # e2fsck should not return error
23885                 [ $rc -eq 0 ] ||
23886                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23887         done
23888 }
23889 run_test 804 "verify agent entry for remote entry"
23890
23891 cleanup_805() {
23892         do_facet $SINGLEMDS zfs set quota=$old $fsset
23893         unlinkmany $DIR/$tdir/f- 1000000
23894         trap 0
23895 }
23896
23897 test_805() {
23898         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23899         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23900         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23901                 skip "netfree not implemented before 0.7"
23902         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23903                 skip "Need MDS version at least 2.10.57"
23904
23905         local fsset
23906         local freekb
23907         local usedkb
23908         local old
23909         local quota
23910         local pref="osd-zfs.$FSNAME-MDT0000."
23911
23912         # limit available space on MDS dataset to meet nospace issue
23913         # quickly. then ZFS 0.7.2 can use reserved space if asked
23914         # properly (using netfree flag in osd_declare_destroy()
23915         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23916         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23917                 gawk '{print $3}')
23918         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23919         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23920         let "usedkb=usedkb-freekb"
23921         let "freekb=freekb/2"
23922         if let "freekb > 5000"; then
23923                 let "freekb=5000"
23924         fi
23925         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23926         trap cleanup_805 EXIT
23927         mkdir $DIR/$tdir
23928         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23929                 error "Can't set PFL layout"
23930         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23931         rm -rf $DIR/$tdir || error "not able to remove"
23932         do_facet $SINGLEMDS zfs set quota=$old $fsset
23933         trap 0
23934 }
23935 run_test 805 "ZFS can remove from full fs"
23936
23937 # Size-on-MDS test
23938 check_lsom_data()
23939 {
23940         local file=$1
23941         local size=$($LFS getsom -s $file)
23942         local expect=$(stat -c %s $file)
23943
23944         [[ $size == $expect ]] ||
23945                 error "$file expected size: $expect, got: $size"
23946
23947         local blocks=$($LFS getsom -b $file)
23948         expect=$(stat -c %b $file)
23949         [[ $blocks == $expect ]] ||
23950                 error "$file expected blocks: $expect, got: $blocks"
23951 }
23952
23953 check_lsom_size()
23954 {
23955         local size=$($LFS getsom -s $1)
23956         local expect=$2
23957
23958         [[ $size == $expect ]] ||
23959                 error "$file expected size: $expect, got: $size"
23960 }
23961
23962 test_806() {
23963         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23964                 skip "Need MDS version at least 2.11.52"
23965
23966         local bs=1048576
23967
23968         touch $DIR/$tfile || error "touch $tfile failed"
23969
23970         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23971         save_lustre_params client "llite.*.xattr_cache" > $save
23972         lctl set_param llite.*.xattr_cache=0
23973         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23974
23975         # single-threaded write
23976         echo "Test SOM for single-threaded write"
23977         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23978                 error "write $tfile failed"
23979         check_lsom_size $DIR/$tfile $bs
23980
23981         local num=32
23982         local size=$(($num * $bs))
23983         local offset=0
23984         local i
23985
23986         echo "Test SOM for single client multi-threaded($num) write"
23987         $TRUNCATE $DIR/$tfile 0
23988         for ((i = 0; i < $num; i++)); do
23989                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23990                 local pids[$i]=$!
23991                 offset=$((offset + $bs))
23992         done
23993         for (( i=0; i < $num; i++ )); do
23994                 wait ${pids[$i]}
23995         done
23996         check_lsom_size $DIR/$tfile $size
23997
23998         $TRUNCATE $DIR/$tfile 0
23999         for ((i = 0; i < $num; i++)); do
24000                 offset=$((offset - $bs))
24001                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24002                 local pids[$i]=$!
24003         done
24004         for (( i=0; i < $num; i++ )); do
24005                 wait ${pids[$i]}
24006         done
24007         check_lsom_size $DIR/$tfile $size
24008
24009         # multi-client writes
24010         num=$(get_node_count ${CLIENTS//,/ })
24011         size=$(($num * $bs))
24012         offset=0
24013         i=0
24014
24015         echo "Test SOM for multi-client ($num) writes"
24016         $TRUNCATE $DIR/$tfile 0
24017         for client in ${CLIENTS//,/ }; do
24018                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24019                 local pids[$i]=$!
24020                 i=$((i + 1))
24021                 offset=$((offset + $bs))
24022         done
24023         for (( i=0; i < $num; i++ )); do
24024                 wait ${pids[$i]}
24025         done
24026         check_lsom_size $DIR/$tfile $offset
24027
24028         i=0
24029         $TRUNCATE $DIR/$tfile 0
24030         for client in ${CLIENTS//,/ }; do
24031                 offset=$((offset - $bs))
24032                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24033                 local pids[$i]=$!
24034                 i=$((i + 1))
24035         done
24036         for (( i=0; i < $num; i++ )); do
24037                 wait ${pids[$i]}
24038         done
24039         check_lsom_size $DIR/$tfile $size
24040
24041         # verify truncate
24042         echo "Test SOM for truncate"
24043         $TRUNCATE $DIR/$tfile 1048576
24044         check_lsom_size $DIR/$tfile 1048576
24045         $TRUNCATE $DIR/$tfile 1234
24046         check_lsom_size $DIR/$tfile 1234
24047
24048         # verify SOM blocks count
24049         echo "Verify SOM block count"
24050         $TRUNCATE $DIR/$tfile 0
24051         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24052                 error "failed to write file $tfile"
24053         check_lsom_data $DIR/$tfile
24054 }
24055 run_test 806 "Verify Lazy Size on MDS"
24056
24057 test_807() {
24058         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24059         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24060                 skip "Need MDS version at least 2.11.52"
24061
24062         # Registration step
24063         changelog_register || error "changelog_register failed"
24064         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24065         changelog_users $SINGLEMDS | grep -q $cl_user ||
24066                 error "User $cl_user not found in changelog_users"
24067
24068         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24069         save_lustre_params client "llite.*.xattr_cache" > $save
24070         lctl set_param llite.*.xattr_cache=0
24071         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24072
24073         rm -rf $DIR/$tdir || error "rm $tdir failed"
24074         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24075         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24076         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24077         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24078                 error "truncate $tdir/trunc failed"
24079
24080         local bs=1048576
24081         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24082                 error "write $tfile failed"
24083
24084         # multi-client wirtes
24085         local num=$(get_node_count ${CLIENTS//,/ })
24086         local offset=0
24087         local i=0
24088
24089         echo "Test SOM for multi-client ($num) writes"
24090         touch $DIR/$tfile || error "touch $tfile failed"
24091         $TRUNCATE $DIR/$tfile 0
24092         for client in ${CLIENTS//,/ }; do
24093                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24094                 local pids[$i]=$!
24095                 i=$((i + 1))
24096                 offset=$((offset + $bs))
24097         done
24098         for (( i=0; i < $num; i++ )); do
24099                 wait ${pids[$i]}
24100         done
24101
24102         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24103         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24104         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24105         check_lsom_data $DIR/$tdir/trunc
24106         check_lsom_data $DIR/$tdir/single_dd
24107         check_lsom_data $DIR/$tfile
24108
24109         rm -rf $DIR/$tdir
24110         # Deregistration step
24111         changelog_deregister || error "changelog_deregister failed"
24112 }
24113 run_test 807 "verify LSOM syncing tool"
24114
24115 check_som_nologged()
24116 {
24117         local lines=$($LFS changelog $FSNAME-MDT0000 |
24118                 grep 'x=trusted.som' | wc -l)
24119         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24120 }
24121
24122 test_808() {
24123         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24124                 skip "Need MDS version at least 2.11.55"
24125
24126         # Registration step
24127         changelog_register || error "changelog_register failed"
24128
24129         touch $DIR/$tfile || error "touch $tfile failed"
24130         check_som_nologged
24131
24132         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24133                 error "write $tfile failed"
24134         check_som_nologged
24135
24136         $TRUNCATE $DIR/$tfile 1234
24137         check_som_nologged
24138
24139         $TRUNCATE $DIR/$tfile 1048576
24140         check_som_nologged
24141
24142         # Deregistration step
24143         changelog_deregister || error "changelog_deregister failed"
24144 }
24145 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24146
24147 check_som_nodata()
24148 {
24149         $LFS getsom $1
24150         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24151 }
24152
24153 test_809() {
24154         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24155                 skip "Need MDS version at least 2.11.56"
24156
24157         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24158                 error "failed to create DoM-only file $DIR/$tfile"
24159         touch $DIR/$tfile || error "touch $tfile failed"
24160         check_som_nodata $DIR/$tfile
24161
24162         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24163                 error "write $tfile failed"
24164         check_som_nodata $DIR/$tfile
24165
24166         $TRUNCATE $DIR/$tfile 1234
24167         check_som_nodata $DIR/$tfile
24168
24169         $TRUNCATE $DIR/$tfile 4097
24170         check_som_nodata $DIR/$file
24171 }
24172 run_test 809 "Verify no SOM xattr store for DoM-only files"
24173
24174 test_810() {
24175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24176         $GSS && skip_env "could not run with gss"
24177         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24178                 skip "OST < 2.12.58 doesn't align checksum"
24179
24180         set_checksums 1
24181         stack_trap "set_checksums $ORIG_CSUM" EXIT
24182         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24183
24184         local csum
24185         local before
24186         local after
24187         for csum in $CKSUM_TYPES; do
24188                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24189                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24190                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24191                         eval set -- $i
24192                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24193                         before=$(md5sum $DIR/$tfile)
24194                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24195                         after=$(md5sum $DIR/$tfile)
24196                         [ "$before" == "$after" ] ||
24197                                 error "$csum: $before != $after bs=$1 seek=$2"
24198                 done
24199         done
24200 }
24201 run_test 810 "partial page writes on ZFS (LU-11663)"
24202
24203 test_812a() {
24204         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24205                 skip "OST < 2.12.51 doesn't support this fail_loc"
24206         [ "$SHARED_KEY" = true ] &&
24207                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24208
24209         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24210         # ensure ost1 is connected
24211         stat $DIR/$tfile >/dev/null || error "can't stat"
24212         wait_osc_import_state client ost1 FULL
24213         # no locks, no reqs to let the connection idle
24214         cancel_lru_locks osc
24215
24216         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24217 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24218         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24219         wait_osc_import_state client ost1 CONNECTING
24220         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24221
24222         stat $DIR/$tfile >/dev/null || error "can't stat file"
24223 }
24224 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24225
24226 test_812b() { # LU-12378
24227         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24228                 skip "OST < 2.12.51 doesn't support this fail_loc"
24229         [ "$SHARED_KEY" = true ] &&
24230                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24231
24232         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24233         # ensure ost1 is connected
24234         stat $DIR/$tfile >/dev/null || error "can't stat"
24235         wait_osc_import_state client ost1 FULL
24236         # no locks, no reqs to let the connection idle
24237         cancel_lru_locks osc
24238
24239         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24240 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24241         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24242         wait_osc_import_state client ost1 CONNECTING
24243         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24244
24245         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24246         wait_osc_import_state client ost1 IDLE
24247 }
24248 run_test 812b "do not drop no resend request for idle connect"
24249
24250 test_813() {
24251         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24252         [ -z "$file_heat_sav" ] && skip "no file heat support"
24253
24254         local readsample
24255         local writesample
24256         local readbyte
24257         local writebyte
24258         local readsample1
24259         local writesample1
24260         local readbyte1
24261         local writebyte1
24262
24263         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24264         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24265
24266         $LCTL set_param -n llite.*.file_heat=1
24267         echo "Turn on file heat"
24268         echo "Period second: $period_second, Decay percentage: $decay_pct"
24269
24270         echo "QQQQ" > $DIR/$tfile
24271         echo "QQQQ" > $DIR/$tfile
24272         echo "QQQQ" > $DIR/$tfile
24273         cat $DIR/$tfile > /dev/null
24274         cat $DIR/$tfile > /dev/null
24275         cat $DIR/$tfile > /dev/null
24276         cat $DIR/$tfile > /dev/null
24277
24278         local out=$($LFS heat_get $DIR/$tfile)
24279
24280         $LFS heat_get $DIR/$tfile
24281         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24282         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24283         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24284         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24285
24286         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24287         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24288         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24289         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24290
24291         sleep $((period_second + 3))
24292         echo "Sleep $((period_second + 3)) seconds..."
24293         # The recursion formula to calculate the heat of the file f is as
24294         # follow:
24295         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24296         # Where Hi is the heat value in the period between time points i*I and
24297         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24298         # to the weight of Ci.
24299         out=$($LFS heat_get $DIR/$tfile)
24300         $LFS heat_get $DIR/$tfile
24301         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24302         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24303         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24304         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24305
24306         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24307                 error "read sample ($readsample) is wrong"
24308         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24309                 error "write sample ($writesample) is wrong"
24310         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24311                 error "read bytes ($readbyte) is wrong"
24312         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24313                 error "write bytes ($writebyte) is wrong"
24314
24315         echo "QQQQ" > $DIR/$tfile
24316         echo "QQQQ" > $DIR/$tfile
24317         echo "QQQQ" > $DIR/$tfile
24318         cat $DIR/$tfile > /dev/null
24319         cat $DIR/$tfile > /dev/null
24320         cat $DIR/$tfile > /dev/null
24321         cat $DIR/$tfile > /dev/null
24322
24323         sleep $((period_second + 3))
24324         echo "Sleep $((period_second + 3)) seconds..."
24325
24326         out=$($LFS heat_get $DIR/$tfile)
24327         $LFS heat_get $DIR/$tfile
24328         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24329         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24330         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24331         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24332
24333         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24334                 4 * $decay_pct) / 100") -eq 1 ] ||
24335                 error "read sample ($readsample1) is wrong"
24336         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24337                 3 * $decay_pct) / 100") -eq 1 ] ||
24338                 error "write sample ($writesample1) is wrong"
24339         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24340                 20 * $decay_pct) / 100") -eq 1 ] ||
24341                 error "read bytes ($readbyte1) is wrong"
24342         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24343                 15 * $decay_pct) / 100") -eq 1 ] ||
24344                 error "write bytes ($writebyte1) is wrong"
24345
24346         echo "Turn off file heat for the file $DIR/$tfile"
24347         $LFS heat_set -o $DIR/$tfile
24348
24349         echo "QQQQ" > $DIR/$tfile
24350         echo "QQQQ" > $DIR/$tfile
24351         echo "QQQQ" > $DIR/$tfile
24352         cat $DIR/$tfile > /dev/null
24353         cat $DIR/$tfile > /dev/null
24354         cat $DIR/$tfile > /dev/null
24355         cat $DIR/$tfile > /dev/null
24356
24357         out=$($LFS heat_get $DIR/$tfile)
24358         $LFS heat_get $DIR/$tfile
24359         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24360         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24361         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24362         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24363
24364         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24365         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24366         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24367         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24368
24369         echo "Trun on file heat for the file $DIR/$tfile"
24370         $LFS heat_set -O $DIR/$tfile
24371
24372         echo "QQQQ" > $DIR/$tfile
24373         echo "QQQQ" > $DIR/$tfile
24374         echo "QQQQ" > $DIR/$tfile
24375         cat $DIR/$tfile > /dev/null
24376         cat $DIR/$tfile > /dev/null
24377         cat $DIR/$tfile > /dev/null
24378         cat $DIR/$tfile > /dev/null
24379
24380         out=$($LFS heat_get $DIR/$tfile)
24381         $LFS heat_get $DIR/$tfile
24382         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24383         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24384         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24385         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24386
24387         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24388         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24389         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24390         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24391
24392         $LFS heat_set -c $DIR/$tfile
24393         $LCTL set_param -n llite.*.file_heat=0
24394         echo "Turn off file heat support for the Lustre filesystem"
24395
24396         echo "QQQQ" > $DIR/$tfile
24397         echo "QQQQ" > $DIR/$tfile
24398         echo "QQQQ" > $DIR/$tfile
24399         cat $DIR/$tfile > /dev/null
24400         cat $DIR/$tfile > /dev/null
24401         cat $DIR/$tfile > /dev/null
24402         cat $DIR/$tfile > /dev/null
24403
24404         out=$($LFS heat_get $DIR/$tfile)
24405         $LFS heat_get $DIR/$tfile
24406         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24407         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24408         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24409         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24410
24411         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24412         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24413         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24414         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24415
24416         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24417         rm -f $DIR/$tfile
24418 }
24419 run_test 813 "File heat verfication"
24420
24421 test_814()
24422 {
24423         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24424         echo -n y >> $DIR/$tfile
24425         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24426         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24427 }
24428 run_test 814 "sparse cp works as expected (LU-12361)"
24429
24430 test_815()
24431 {
24432         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24433         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24434 }
24435 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24436
24437 test_816() {
24438         [ "$SHARED_KEY" = true ] &&
24439                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24440
24441         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24442         # ensure ost1 is connected
24443         stat $DIR/$tfile >/dev/null || error "can't stat"
24444         wait_osc_import_state client ost1 FULL
24445         # no locks, no reqs to let the connection idle
24446         cancel_lru_locks osc
24447         lru_resize_disable osc
24448         local before
24449         local now
24450         before=$($LCTL get_param -n \
24451                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24452
24453         wait_osc_import_state client ost1 IDLE
24454         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24455         now=$($LCTL get_param -n \
24456               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24457         [ $before == $now ] || error "lru_size changed $before != $now"
24458 }
24459 run_test 816 "do not reset lru_resize on idle reconnect"
24460
24461 cleanup_817() {
24462         umount $tmpdir
24463         exportfs -u localhost:$DIR/nfsexp
24464         rm -rf $DIR/nfsexp
24465 }
24466
24467 test_817() {
24468         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24469
24470         mkdir -p $DIR/nfsexp
24471         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24472                 error "failed to export nfs"
24473
24474         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24475         stack_trap cleanup_817 EXIT
24476
24477         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24478                 error "failed to mount nfs to $tmpdir"
24479
24480         cp /bin/true $tmpdir
24481         $DIR/nfsexp/true || error "failed to execute 'true' command"
24482 }
24483 run_test 817 "nfsd won't cache write lock for exec file"
24484
24485 test_818() {
24486         mkdir $DIR/$tdir
24487         $LFS setstripe -c1 -i0 $DIR/$tfile
24488         $LFS setstripe -c1 -i1 $DIR/$tfile
24489         stop $SINGLEMDS
24490         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24491         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24492         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24493                 error "start $SINGLEMDS failed"
24494         rm -rf $DIR/$tdir
24495 }
24496 run_test 818 "unlink with failed llog"
24497
24498 test_819a() {
24499         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24500         cancel_lru_locks osc
24501         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24502         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24503         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24504         rm -f $TDIR/$tfile
24505 }
24506 run_test 819a "too big niobuf in read"
24507
24508 test_819b() {
24509         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24510         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24511         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24512         cancel_lru_locks osc
24513         sleep 1
24514         rm -f $TDIR/$tfile
24515 }
24516 run_test 819b "too big niobuf in write"
24517
24518
24519 function test_820_start_ost() {
24520         sleep 5
24521
24522         for num in $(seq $OSTCOUNT); do
24523                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24524         done
24525 }
24526
24527 test_820() {
24528         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24529
24530         mkdir $DIR/$tdir
24531         umount_client $MOUNT || error "umount failed"
24532         for num in $(seq $OSTCOUNT); do
24533                 stop ost$num
24534         done
24535
24536         # mount client with no active OSTs
24537         # so that the client can't initialize max LOV EA size
24538         # from OSC notifications
24539         mount_client $MOUNT || error "mount failed"
24540         # delay OST starting to keep this 0 max EA size for a while
24541         test_820_start_ost &
24542
24543         # create a directory on MDS2
24544         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24545                 error "Failed to create directory"
24546         # open intent should update default EA size
24547         # see mdc_update_max_ea_from_body()
24548         # notice this is the very first RPC to MDS2
24549         cp /etc/services $DIR/$tdir/mds2 ||
24550                 error "Failed to copy files to mds$n"
24551 }
24552 run_test 820 "update max EA from open intent"
24553
24554 #
24555 # tests that do cleanup/setup should be run at the end
24556 #
24557
24558 test_900() {
24559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24560         local ls
24561
24562         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24563         $LCTL set_param fail_loc=0x903
24564
24565         cancel_lru_locks MGC
24566
24567         FAIL_ON_ERROR=true cleanup
24568         FAIL_ON_ERROR=true setup
24569 }
24570 run_test 900 "umount should not race with any mgc requeue thread"
24571
24572 # LUS-6253/LU-11185
24573 test_901() {
24574         local oldc
24575         local newc
24576         local olds
24577         local news
24578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24579
24580         # some get_param have a bug to handle dot in param name
24581         cancel_lru_locks MGC
24582         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24583         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24584         umount_client $MOUNT || error "umount failed"
24585         mount_client $MOUNT || error "mount failed"
24586         cancel_lru_locks MGC
24587         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24588         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24589
24590         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24591         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24592
24593         return 0
24594 }
24595 run_test 901 "don't leak a mgc lock on client umount"
24596
24597 # LU-13377
24598 test_902() {
24599         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24600                 skip "client does not have LU-13377 fix"
24601         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24602         $LCTL set_param fail_loc=0x1415
24603         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24604         cancel_lru_locks osc
24605         rm -f $DIR/$tfile
24606 }
24607 run_test 902 "test short write doesn't hang lustre"
24608
24609 complete $SECONDS
24610 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24611 check_and_cleanup_lustre
24612 if [ "$I_MOUNTED" != "yes" ]; then
24613         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24614 fi
24615 exit_status