Whamcloud - gitweb
LU-13498 tests: remove tests from ALWAYS_EXCEPT with SSK
[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 selinux_status=$(getenforce)
48 if [ "$selinux_status" != "Disabled" ]; then
49         # bug number:
50         ALWAYS_EXCEPT+=""
51 fi
52
53 # skip the grant tests for ARM until they are fixed
54 if [[ $(uname -m) = aarch64 ]]; then
55         # bug number:    LU-11596
56         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
57         # bug number:    LU-11671 LU-11667
58         ALWAYS_EXCEPT+=" 45       317"
59         # bug number:    LU-14067 LU-14067
60         ALWAYS_EXCEPT+=" 400a     400b"
61 fi
62
63 # skip splice tests on kernels >= 4.15.0 until they are fixed
64 if [ $LINUX_VERSION_CODE -ge $(version_code 4.15.0) ]; then
65         # bug number:   LU-14045
66         ALWAYS_EXCEPT+=" 426"
67 fi
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 # Get the SLES distro version
91 #
92 # Returns a version string that should only be used in comparing
93 # strings returned by version_code()
94 sles_version_code()
95 {
96         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
97
98         # All SuSE Linux versions have one decimal. version_code expects two
99         local sles_version=$version.0
100         version_code $sles_version
101 }
102
103 # Check if we are running on Ubuntu or SLES so we can make decisions on
104 # what tests to run
105 if [ -r /etc/SuSE-release ]; then
106         sles_version=$(sles_version_code)
107         [ $sles_version -lt $(version_code 11.4.0) ] &&
108                 # bug number for skipped test: LU-4341
109                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
110         [ $sles_version -lt $(version_code 12.0.0) ] &&
111                 # bug number for skipped test: LU-3703
112                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
113 elif [ -r /etc/os-release ]; then
114         if grep -qi ubuntu /etc/os-release; then
115                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
116                                                 -e 's/^VERSION=//p' \
117                                                 /etc/os-release |
118                                                 awk '{ print $1 }'))
119
120                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
121                         # bug number for skipped test:
122                         #                LU-10334 LU-10366
123                         ALWAYS_EXCEPT+=" 103a     410"
124                 fi
125         fi
126 fi
127
128 build_test_filter
129 FAIL_ON_ERROR=false
130
131 cleanup() {
132         echo -n "cln.."
133         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
134         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
135 }
136 setup() {
137         echo -n "mnt.."
138         load_modules
139         setupall || exit 10
140         echo "done"
141 }
142
143 check_swap_layouts_support()
144 {
145         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
146                 skip "Does not support layout lock."
147 }
148
149 check_swap_layout_no_dom()
150 {
151         local FOLDER=$1
152         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
153         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
154 }
155
156 check_and_setup_lustre
157 DIR=${DIR:-$MOUNT}
158 assert_DIR
159
160 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
161
162 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
163 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
164 rm -rf $DIR/[Rdfs][0-9]*
165
166 # $RUNAS_ID may get set incorrectly somewhere else
167 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
168         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
169
170 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
171
172 if [ "${ONLY}" = "MOUNT" ] ; then
173         echo "Lustre is up, please go on"
174         exit
175 fi
176
177 echo "preparing for tests involving mounts"
178 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
179 touch $EXT2_DEV
180 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
181 echo # add a newline after mke2fs.
182
183 umask 077
184
185 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
186 lctl set_param debug=-1 2> /dev/null || true
187 test_0a() {
188         touch $DIR/$tfile
189         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
190         rm $DIR/$tfile
191         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
192 }
193 run_test 0a "touch; rm ====================="
194
195 test_0b() {
196         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
197         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
198 }
199 run_test 0b "chmod 0755 $DIR ============================="
200
201 test_0c() {
202         $LCTL get_param mdc.*.import | grep "state: FULL" ||
203                 error "import not FULL"
204         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
205                 error "bad target"
206 }
207 run_test 0c "check import proc"
208
209 test_0d() { # LU-3397
210         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
211                 skip "proc exports not supported before 2.10.57"
212
213         local mgs_exp="mgs.MGS.exports"
214         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
215         local exp_client_nid
216         local exp_client_version
217         local exp_val
218         local imp_val
219         local temp_imp=$DIR/$tfile.import
220         local temp_exp=$DIR/$tfile.export
221
222         # save mgc import file to $temp_imp
223         $LCTL get_param mgc.*.import | tee $temp_imp
224         # Check if client uuid is found in MGS export
225         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
226                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
227                         $client_uuid ] &&
228                         break;
229         done
230         # save mgs export file to $temp_exp
231         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
232
233         # Compare the value of field "connect_flags"
234         imp_val=$(grep "connect_flags" $temp_imp)
235         exp_val=$(grep "connect_flags" $temp_exp)
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "export flags '$exp_val' != import flags '$imp_val'"
238
239         # Compare the value of client version
240         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
241         exp_val=$(version_code $exp_client_version)
242         imp_val=$CLIENT_VERSION
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export client version '$exp_val' != '$imp_val'"
245 }
246 run_test 0d "check export proc ============================="
247
248 test_1() {
249         test_mkdir $DIR/$tdir
250         test_mkdir $DIR/$tdir/d2
251         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
252         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
253         rmdir $DIR/$tdir/d2
254         rmdir $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
256 }
257 run_test 1 "mkdir; remkdir; rmdir"
258
259 test_2() {
260         test_mkdir $DIR/$tdir
261         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
265 }
266 run_test 2 "mkdir; touch; rmdir; check file"
267
268 test_3() {
269         test_mkdir $DIR/$tdir
270         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
271         touch $DIR/$tdir/$tfile
272         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
273         rm -r $DIR/$tdir
274         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
275 }
276 run_test 3 "mkdir; touch; rmdir; check dir"
277
278 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
279 test_4() {
280         test_mkdir -i 1 $DIR/$tdir
281
282         touch $DIR/$tdir/$tfile ||
283                 error "Create file under remote directory failed"
284
285         rmdir $DIR/$tdir &&
286                 error "Expect error removing in-use dir $DIR/$tdir"
287
288         test -d $DIR/$tdir || error "Remote directory disappeared"
289
290         rm -rf $DIR/$tdir || error "remove remote dir error"
291 }
292 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
293
294 test_5() {
295         test_mkdir $DIR/$tdir
296         test_mkdir $DIR/$tdir/d2
297         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
298         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
299         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
300 }
301 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
302
303 test_6a() {
304         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
305         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
306         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
307                 error "$tfile does not have perm 0666 or UID $UID"
308         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
309         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
310                 error "$tfile should be 0666 and owned by UID $UID"
311 }
312 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
313
314 test_6c() {
315         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
316
317         touch $DIR/$tfile
318         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
319         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
320                 error "$tfile should be owned by UID $RUNAS_ID"
321         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
322         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by UID $RUNAS_ID"
324 }
325 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
326
327 test_6e() {
328         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
329
330         touch $DIR/$tfile
331         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
332         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
333                 error "$tfile should be owned by GID $UID"
334         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
335         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
336                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
337 }
338 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
339
340 test_6g() {
341         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
342
343         test_mkdir $DIR/$tdir
344         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
345         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
346         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
347         test_mkdir $DIR/$tdir/d/subdir
348         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
349                 error "$tdir/d/subdir should be GID $RUNAS_GID"
350         if [[ $MDSCOUNT -gt 1 ]]; then
351                 # check remote dir sgid inherite
352                 $LFS mkdir -i 0 $DIR/$tdir.local ||
353                         error "mkdir $tdir.local failed"
354                 chmod g+s $DIR/$tdir.local ||
355                         error "chmod $tdir.local failed"
356                 chgrp $RUNAS_GID $DIR/$tdir.local ||
357                         error "chgrp $tdir.local failed"
358                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
359                         error "mkdir $tdir.remote failed"
360                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
362                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
363                         error "$tdir.remote should be mode 02755"
364         fi
365 }
366 run_test 6g "verify new dir in sgid dir inherits group"
367
368 test_6h() { # bug 7331
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile || error "touch failed"
372         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
373         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
374                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
375         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
376                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
377 }
378 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
379
380 test_7a() {
381         test_mkdir $DIR/$tdir
382         $MCREATE $DIR/$tdir/$tfile
383         chmod 0666 $DIR/$tdir/$tfile
384         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
385                 error "$tdir/$tfile should be mode 0666"
386 }
387 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
388
389 test_7b() {
390         if [ ! -d $DIR/$tdir ]; then
391                 test_mkdir $DIR/$tdir
392         fi
393         $MCREATE $DIR/$tdir/$tfile
394         echo -n foo > $DIR/$tdir/$tfile
395         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
396         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
397 }
398 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
399
400 test_8() {
401         test_mkdir $DIR/$tdir
402         touch $DIR/$tdir/$tfile
403         chmod 0666 $DIR/$tdir/$tfile
404         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
405                 error "$tfile mode not 0666"
406 }
407 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
408
409 test_9() {
410         test_mkdir $DIR/$tdir
411         test_mkdir $DIR/$tdir/d2
412         test_mkdir $DIR/$tdir/d2/d3
413         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
414 }
415 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
416
417 test_10() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         touch $DIR/$tdir/d2/$tfile
421         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
422                 error "$tdir/d2/$tfile not a file"
423 }
424 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
425
426 test_11() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         chmod 0666 $DIR/$tdir/d2
430         chmod 0705 $DIR/$tdir/d2
431         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
432                 error "$tdir/d2 mode not 0705"
433 }
434 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
435
436 test_12() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         chmod 0666 $DIR/$tdir/$tfile
440         chmod 0654 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
442                 error "$tdir/d2 mode not 0654"
443 }
444 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
445
446 test_13() {
447         test_mkdir $DIR/$tdir
448         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
449         >  $DIR/$tdir/$tfile
450         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
451                 error "$tdir/$tfile size not 0 after truncate"
452 }
453 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
454
455 test_14() {
456         test_mkdir $DIR/$tdir
457         touch $DIR/$tdir/$tfile
458         rm $DIR/$tdir/$tfile
459         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
460 }
461 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
462
463 test_15() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
467         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
468                 error "$tdir/${tfile_2} not a file after rename"
469         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
470 }
471 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
472
473 test_16() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         rm -rf $DIR/$tdir/$tfile
477         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
478 }
479 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
480
481 test_17a() {
482         test_mkdir $DIR/$tdir
483         touch $DIR/$tdir/$tfile
484         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
485         ls -l $DIR/$tdir
486         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not a symlink"
488         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
489                 error "$tdir/l-exist not referencing a file"
490         rm -f $DIR/$tdir/l-exist
491         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
492 }
493 run_test 17a "symlinks: create, remove (real)"
494
495 test_17b() {
496         test_mkdir $DIR/$tdir
497         ln -s no-such-file $DIR/$tdir/l-dangle
498         ls -l $DIR/$tdir
499         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing no-such-file"
501         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
502                 error "$tdir/l-dangle not referencing non-existent file"
503         rm -f $DIR/$tdir/l-dangle
504         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
505 }
506 run_test 17b "symlinks: create, remove (dangling)"
507
508 test_17c() { # bug 3440 - don't save failed open RPC for replay
509         test_mkdir $DIR/$tdir
510         ln -s foo $DIR/$tdir/$tfile
511         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
512 }
513 run_test 17c "symlinks: open dangling (should return error)"
514
515 test_17d() {
516         test_mkdir $DIR/$tdir
517         ln -s foo $DIR/$tdir/$tfile
518         touch $DIR/$tdir/$tfile || error "creating to new symlink"
519 }
520 run_test 17d "symlinks: create dangling"
521
522 test_17e() {
523         test_mkdir $DIR/$tdir
524         local foo=$DIR/$tdir/$tfile
525         ln -s $foo $foo || error "create symlink failed"
526         ls -l $foo || error "ls -l failed"
527         ls $foo && error "ls not failed" || true
528 }
529 run_test 17e "symlinks: create recursive symlink (should return error)"
530
531 test_17f() {
532         test_mkdir $DIR/$tdir
533         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
536         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
537         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
538         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
539         ls -l  $DIR/$tdir
540 }
541 run_test 17f "symlinks: long and very long symlink name"
542
543 # str_repeat(S, N) generate a string that is string S repeated N times
544 str_repeat() {
545         local s=$1
546         local n=$2
547         local ret=''
548         while [ $((n -= 1)) -ge 0 ]; do
549                 ret=$ret$s
550         done
551         echo $ret
552 }
553
554 # Long symlinks and LU-2241
555 test_17g() {
556         test_mkdir $DIR/$tdir
557         local TESTS="59 60 61 4094 4095"
558
559         # Fix for inode size boundary in 2.1.4
560         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
561                 TESTS="4094 4095"
562
563         # Patch not applied to 2.2 or 2.3 branches
564         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
565         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
566                 TESTS="4094 4095"
567
568         for i in $TESTS; do
569                 local SYMNAME=$(str_repeat 'x' $i)
570                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
571                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
572         done
573 }
574 run_test 17g "symlinks: really long symlink name and inode boundaries"
575
576 test_17h() { #bug 17378
577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
578         remote_mds_nodsh && skip "remote MDS with nodsh"
579
580         local mdt_idx
581
582         test_mkdir $DIR/$tdir
583         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
584         $LFS setstripe -c -1 $DIR/$tdir
585         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
586         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
587         touch $DIR/$tdir/$tfile || true
588 }
589 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
590
591 test_17i() { #bug 20018
592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
593         remote_mds_nodsh && skip "remote MDS with nodsh"
594
595         local foo=$DIR/$tdir/$tfile
596         local mdt_idx
597
598         test_mkdir -c1 $DIR/$tdir
599         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
600         ln -s $foo $foo || error "create symlink failed"
601 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
602         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
603         ls -l $foo && error "error not detected"
604         return 0
605 }
606 run_test 17i "don't panic on short symlink (should return error)"
607
608 test_17k() { #bug 22301
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         [[ -z "$(which rsync 2>/dev/null)" ]] &&
611                 skip "no rsync command"
612         rsync --help | grep -q xattr ||
613                 skip_env "$(rsync --version | head -n1) does not support xattrs"
614         test_mkdir $DIR/$tdir
615         test_mkdir $DIR/$tdir.new
616         touch $DIR/$tdir/$tfile
617         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
618         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
619                 error "rsync failed with xattrs enabled"
620 }
621 run_test 17k "symlinks: rsync with xattrs enabled"
622
623 test_17l() { # LU-279
624         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
625                 skip "no getfattr command"
626
627         test_mkdir $DIR/$tdir
628         touch $DIR/$tdir/$tfile
629         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
630         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
631                 # -h to not follow symlinks. -m '' to list all the xattrs.
632                 # grep to remove first line: '# file: $path'.
633                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
634                 do
635                         lgetxattr_size_check $path $xattr ||
636                                 error "lgetxattr_size_check $path $xattr failed"
637                 done
638         done
639 }
640 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
641
642 # LU-1540
643 test_17m() {
644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
645         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
646         remote_mds_nodsh && skip "remote MDS with nodsh"
647         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
648         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
649                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
650
651         local short_sym="0123456789"
652         local wdir=$DIR/$tdir
653         local i
654
655         test_mkdir $wdir
656         long_sym=$short_sym
657         # create a long symlink file
658         for ((i = 0; i < 4; ++i)); do
659                 long_sym=${long_sym}${long_sym}
660         done
661
662         echo "create 512 short and long symlink files under $wdir"
663         for ((i = 0; i < 256; ++i)); do
664                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
665                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
666         done
667
668         echo "erase them"
669         rm -f $wdir/*
670         sync
671         wait_delete_completed
672
673         echo "recreate the 512 symlink files with a shorter string"
674         for ((i = 0; i < 512; ++i)); do
675                 # rewrite the symlink file with a shorter string
676                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
677                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
678         done
679
680         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
681         local devname=$(mdsdevname $mds_index)
682
683         echo "stop and checking mds${mds_index}:"
684         # e2fsck should not return error
685         stop mds${mds_index}
686         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
687         rc=$?
688
689         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
690                 error "start mds${mds_index} failed"
691         df $MOUNT > /dev/null 2>&1
692         [ $rc -eq 0 ] ||
693                 error "e2fsck detected error for short/long symlink: rc=$rc"
694         rm -f $wdir/*
695 }
696 run_test 17m "run e2fsck against MDT which contains short/long symlink"
697
698 check_fs_consistency_17n() {
699         local mdt_index
700         local rc=0
701
702         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
703         # so it only check MDT1/MDT2 instead of all of MDTs.
704         for mdt_index in 1 2; do
705                 local devname=$(mdsdevname $mdt_index)
706                 # e2fsck should not return error
707                 stop mds${mdt_index}
708                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
709                         rc=$((rc + $?))
710
711                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
712                         error "mount mds$mdt_index failed"
713                 df $MOUNT > /dev/null 2>&1
714         done
715         return $rc
716 }
717
718 test_17n() {
719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
721         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
722         remote_mds_nodsh && skip "remote MDS with nodsh"
723         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
724         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
725                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
726
727         local i
728
729         test_mkdir $DIR/$tdir
730         for ((i=0; i<10; i++)); do
731                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
732                         error "create remote dir error $i"
733                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
734                         error "create files under remote dir failed $i"
735         done
736
737         check_fs_consistency_17n ||
738                 error "e2fsck report error after create files under remote dir"
739
740         for ((i = 0; i < 10; i++)); do
741                 rm -rf $DIR/$tdir/remote_dir_${i} ||
742                         error "destroy remote dir error $i"
743         done
744
745         check_fs_consistency_17n ||
746                 error "e2fsck report error after unlink files under remote dir"
747
748         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
749                 skip "lustre < 2.4.50 does not support migrate mv"
750
751         for ((i = 0; i < 10; i++)); do
752                 mkdir -p $DIR/$tdir/remote_dir_${i}
753                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
754                         error "create files under remote dir failed $i"
755                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
756                         error "migrate remote dir error $i"
757         done
758         check_fs_consistency_17n || error "e2fsck report error after migration"
759
760         for ((i = 0; i < 10; i++)); do
761                 rm -rf $DIR/$tdir/remote_dir_${i} ||
762                         error "destroy remote dir error $i"
763         done
764
765         check_fs_consistency_17n || error "e2fsck report error after unlink"
766 }
767 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
768
769 test_17o() {
770         remote_mds_nodsh && skip "remote MDS with nodsh"
771         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
772                 skip "Need MDS version at least 2.3.64"
773
774         local wdir=$DIR/${tdir}o
775         local mdt_index
776         local rc=0
777
778         test_mkdir $wdir
779         touch $wdir/$tfile
780         mdt_index=$($LFS getstripe -m $wdir/$tfile)
781         mdt_index=$((mdt_index + 1))
782
783         cancel_lru_locks mdc
784         #fail mds will wait the failover finish then set
785         #following fail_loc to avoid interfer the recovery process.
786         fail mds${mdt_index}
787
788         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
789         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
790         ls -l $wdir/$tfile && rc=1
791         do_facet mds${mdt_index} lctl set_param fail_loc=0
792         [[ $rc -eq 0 ]] || error "stat file should fail"
793 }
794 run_test 17o "stat file with incompat LMA feature"
795
796 test_18() {
797         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
798         ls $DIR || error "Failed to ls $DIR: $?"
799 }
800 run_test 18 "touch .../f ; ls ... =============================="
801
802 test_19a() {
803         touch $DIR/$tfile
804         ls -l $DIR
805         rm $DIR/$tfile
806         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
807 }
808 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
809
810 test_19b() {
811         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
812 }
813 run_test 19b "ls -l .../f19 (should return error) =============="
814
815 test_19c() {
816         [ $RUNAS_ID -eq $UID ] &&
817                 skip_env "RUNAS_ID = UID = $UID -- skipping"
818
819         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
820 }
821 run_test 19c "$RUNAS touch .../f19 (should return error) =="
822
823 test_19d() {
824         cat $DIR/f19 && error || true
825 }
826 run_test 19d "cat .../f19 (should return error) =============="
827
828 test_20() {
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         touch $DIR/$tfile
834         rm $DIR/$tfile
835         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
836 }
837 run_test 20 "touch .../f ; ls -l ..."
838
839 test_21() {
840         test_mkdir $DIR/$tdir
841         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
842         ln -s dangle $DIR/$tdir/link
843         echo foo >> $DIR/$tdir/link
844         cat $DIR/$tdir/dangle
845         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
846         $CHECKSTAT -f -t file $DIR/$tdir/link ||
847                 error "$tdir/link not linked to a file"
848 }
849 run_test 21 "write to dangling link"
850
851 test_22() {
852         local wdir=$DIR/$tdir
853         test_mkdir $wdir
854         chown $RUNAS_ID:$RUNAS_GID $wdir
855         (cd $wdir || error "cd $wdir failed";
856                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
857                 $RUNAS tar xf -)
858         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
859         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
860         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
861                 error "checkstat -u failed"
862 }
863 run_test 22 "unpack tar archive as non-root user"
864
865 # was test_23
866 test_23a() {
867         test_mkdir $DIR/$tdir
868         local file=$DIR/$tdir/$tfile
869
870         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
871         openfile -f O_CREAT:O_EXCL $file &&
872                 error "$file recreate succeeded" || true
873 }
874 run_test 23a "O_CREAT|O_EXCL in subdir"
875
876 test_23b() { # bug 18988
877         test_mkdir $DIR/$tdir
878         local file=$DIR/$tdir/$tfile
879
880         rm -f $file
881         echo foo > $file || error "write filed"
882         echo bar >> $file || error "append filed"
883         $CHECKSTAT -s 8 $file || error "wrong size"
884         rm $file
885 }
886 run_test 23b "O_APPEND check"
887
888 # LU-9409, size with O_APPEND and tiny writes
889 test_23c() {
890         local file=$DIR/$tfile
891
892         # single dd
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
894         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
895         rm -f $file
896
897         # racing tiny writes
898         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
900         wait
901         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
902         rm -f $file
903
904         #racing tiny & normal writes
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
906         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
907         wait
908         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
909         rm -f $file
910
911         #racing tiny & normal writes 2, ugly numbers
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
914         wait
915         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
916         rm -f $file
917 }
918 run_test 23c "O_APPEND size checks for tiny writes"
919
920 # LU-11069 file offset is correct after appending writes
921 test_23d() {
922         local file=$DIR/$tfile
923         local offset
924
925         echo CentaurHauls > $file
926         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
927         if ((offset != 26)); then
928                 error "wrong offset, expected 26, got '$offset'"
929         fi
930 }
931 run_test 23d "file offset is correct after appending writes"
932
933 # rename sanity
934 test_24a() {
935         echo '-- same directory rename'
936         test_mkdir $DIR/$tdir
937         touch $DIR/$tdir/$tfile.1
938         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24a "rename file to non-existent target"
942
943 test_24b() {
944         test_mkdir $DIR/$tdir
945         touch $DIR/$tdir/$tfile.{1,2}
946         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
947         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
948         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
949 }
950 run_test 24b "rename file to existing target"
951
952 test_24c() {
953         test_mkdir $DIR/$tdir
954         test_mkdir $DIR/$tdir/d$testnum.1
955         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
956         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
957         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
958 }
959 run_test 24c "rename directory to non-existent target"
960
961 test_24d() {
962         test_mkdir -c1 $DIR/$tdir
963         test_mkdir -c1 $DIR/$tdir/d$testnum.1
964         test_mkdir -c1 $DIR/$tdir/d$testnum.2
965         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
966         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
967         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
968 }
969 run_test 24d "rename directory to existing target"
970
971 test_24e() {
972         echo '-- cross directory renames --'
973         test_mkdir $DIR/R5a
974         test_mkdir $DIR/R5b
975         touch $DIR/R5a/f
976         mv $DIR/R5a/f $DIR/R5b/g
977         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
978         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
979 }
980 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
981
982 test_24f() {
983         test_mkdir $DIR/R6a
984         test_mkdir $DIR/R6b
985         touch $DIR/R6a/f $DIR/R6b/g
986         mv $DIR/R6a/f $DIR/R6b/g
987         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
988         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
989 }
990 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
991
992 test_24g() {
993         test_mkdir $DIR/R7a
994         test_mkdir $DIR/R7b
995         test_mkdir $DIR/R7a/d
996         mv $DIR/R7a/d $DIR/R7b/e
997         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
998         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
999 }
1000 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1001
1002 test_24h() {
1003         test_mkdir -c1 $DIR/R8a
1004         test_mkdir -c1 $DIR/R8b
1005         test_mkdir -c1 $DIR/R8a/d
1006         test_mkdir -c1 $DIR/R8b/e
1007         mrename $DIR/R8a/d $DIR/R8b/e
1008         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1009         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1010 }
1011 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1012
1013 test_24i() {
1014         echo "-- rename error cases"
1015         test_mkdir $DIR/R9
1016         test_mkdir $DIR/R9/a
1017         touch $DIR/R9/f
1018         mrename $DIR/R9/f $DIR/R9/a
1019         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1020         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1021         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1022 }
1023 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1024
1025 test_24j() {
1026         test_mkdir $DIR/R10
1027         mrename $DIR/R10/f $DIR/R10/g
1028         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1029         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1030         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1031 }
1032 run_test 24j "source does not exist ============================"
1033
1034 test_24k() {
1035         test_mkdir $DIR/R11a
1036         test_mkdir $DIR/R11a/d
1037         touch $DIR/R11a/f
1038         mv $DIR/R11a/f $DIR/R11a/d
1039         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1040         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1041 }
1042 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1043
1044 # bug 2429 - rename foo foo foo creates invalid file
1045 test_24l() {
1046         f="$DIR/f24l"
1047         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1048 }
1049 run_test 24l "Renaming a file to itself ========================"
1050
1051 test_24m() {
1052         f="$DIR/f24m"
1053         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1054         # on ext3 this does not remove either the source or target files
1055         # though the "expected" operation would be to remove the source
1056         $CHECKSTAT -t file ${f} || error "${f} missing"
1057         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1058 }
1059 run_test 24m "Renaming a file to a hard link to itself ========="
1060
1061 test_24n() {
1062     f="$DIR/f24n"
1063     # this stats the old file after it was renamed, so it should fail
1064     touch ${f}
1065     $CHECKSTAT ${f} || error "${f} missing"
1066     mv ${f} ${f}.rename
1067     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1068     $CHECKSTAT -a ${f} || error "${f} exists"
1069 }
1070 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1071
1072 test_24o() {
1073         test_mkdir $DIR/$tdir
1074         rename_many -s random -v -n 10 $DIR/$tdir
1075 }
1076 run_test 24o "rename of files during htree split"
1077
1078 test_24p() {
1079         test_mkdir $DIR/R12a
1080         test_mkdir $DIR/R12b
1081         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1082         mrename $DIR/R12a $DIR/R12b
1083         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1084         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1085         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1086         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1087 }
1088 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1089
1090 cleanup_multiop_pause() {
1091         trap 0
1092         kill -USR1 $MULTIPID
1093 }
1094
1095 test_24q() {
1096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1097
1098         test_mkdir $DIR/R13a
1099         test_mkdir $DIR/R13b
1100         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1101         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1102         MULTIPID=$!
1103
1104         trap cleanup_multiop_pause EXIT
1105         mrename $DIR/R13a $DIR/R13b
1106         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1107         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1108         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1110         cleanup_multiop_pause
1111         wait $MULTIPID || error "multiop close failed"
1112 }
1113 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1114
1115 test_24r() { #bug 3789
1116         test_mkdir $DIR/R14a
1117         test_mkdir $DIR/R14a/b
1118         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1119         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1120         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1121 }
1122 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1123
1124 test_24s() {
1125         test_mkdir $DIR/R15a
1126         test_mkdir $DIR/R15a/b
1127         test_mkdir $DIR/R15a/b/c
1128         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1130         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1131 }
1132 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1133 test_24t() {
1134         test_mkdir $DIR/R16a
1135         test_mkdir $DIR/R16a/b
1136         test_mkdir $DIR/R16a/b/c
1137         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1138         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1139         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1140 }
1141 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1142
1143 test_24u() { # bug12192
1144         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1145         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1146 }
1147 run_test 24u "create stripe file"
1148
1149 simple_cleanup_common() {
1150         local rc=0
1151         trap 0
1152         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1153
1154         local start=$SECONDS
1155         rm -rf $DIR/$tdir
1156         rc=$?
1157         wait_delete_completed
1158         echo "cleanup time $((SECONDS - start))"
1159         return $rc
1160 }
1161
1162 max_pages_per_rpc() {
1163         local mdtname="$(printf "MDT%04x" ${1:-0})"
1164         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1165 }
1166
1167 test_24v() {
1168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1169
1170         local nrfiles=${COUNT:-100000}
1171         local fname="$DIR/$tdir/$tfile"
1172
1173         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1174         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1175
1176         test_mkdir "$(dirname $fname)"
1177         # assume MDT0000 has the fewest inodes
1178         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1179         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1180         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1181
1182         trap simple_cleanup_common EXIT
1183
1184         createmany -m "$fname" $nrfiles
1185
1186         cancel_lru_locks mdc
1187         lctl set_param mdc.*.stats clear
1188
1189         # was previously test_24D: LU-6101
1190         # readdir() returns correct number of entries after cursor reload
1191         local num_ls=$(ls $DIR/$tdir | wc -l)
1192         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1193         local num_all=$(ls -a $DIR/$tdir | wc -l)
1194         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1195                 [ $num_all -ne $((nrfiles + 2)) ]; then
1196                         error "Expected $nrfiles files, got $num_ls " \
1197                                 "($num_uniq unique $num_all .&..)"
1198         fi
1199         # LU-5 large readdir
1200         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1201         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1202         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1203         # take into account of overhead in lu_dirpage header and end mark in
1204         # each page, plus one in rpc_num calculation.
1205         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1206         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1207         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1208         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1209         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1210         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1211         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1212         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1213                 error "large readdir doesn't take effect: " \
1214                       "$mds_readpage should be about $rpc_max"
1215
1216         simple_cleanup_common
1217 }
1218 run_test 24v "list large directory (test hash collision, b=17560)"
1219
1220 test_24w() { # bug21506
1221         SZ1=234852
1222         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1223         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1224         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1225         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1226         [[ "$SZ1" -eq "$SZ2" ]] ||
1227                 error "Error reading at the end of the file $tfile"
1228 }
1229 run_test 24w "Reading a file larger than 4Gb"
1230
1231 test_24x() {
1232         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1234         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1235                 skip "Need MDS version at least 2.7.56"
1236
1237         local MDTIDX=1
1238         local remote_dir=$DIR/$tdir/remote_dir
1239
1240         test_mkdir $DIR/$tdir
1241         $LFS mkdir -i $MDTIDX $remote_dir ||
1242                 error "create remote directory failed"
1243
1244         test_mkdir $DIR/$tdir/src_dir
1245         touch $DIR/$tdir/src_file
1246         test_mkdir $remote_dir/tgt_dir
1247         touch $remote_dir/tgt_file
1248
1249         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1250                 error "rename dir cross MDT failed!"
1251
1252         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1253                 error "rename file cross MDT failed!"
1254
1255         touch $DIR/$tdir/ln_file
1256         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1257                 error "ln file cross MDT failed"
1258
1259         rm -rf $DIR/$tdir || error "Can not delete directories"
1260 }
1261 run_test 24x "cross MDT rename/link"
1262
1263 test_24y() {
1264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1266
1267         local remote_dir=$DIR/$tdir/remote_dir
1268         local mdtidx=1
1269
1270         test_mkdir $DIR/$tdir
1271         $LFS mkdir -i $mdtidx $remote_dir ||
1272                 error "create remote directory failed"
1273
1274         test_mkdir $remote_dir/src_dir
1275         touch $remote_dir/src_file
1276         test_mkdir $remote_dir/tgt_dir
1277         touch $remote_dir/tgt_file
1278
1279         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1280                 error "rename subdir in the same remote dir failed!"
1281
1282         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1283                 error "rename files in the same remote dir failed!"
1284
1285         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1286                 error "link files in the same remote dir failed!"
1287
1288         rm -rf $DIR/$tdir || error "Can not delete directories"
1289 }
1290 run_test 24y "rename/link on the same dir should succeed"
1291
1292 test_24z() {
1293         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1294         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1295                 skip "Need MDS version at least 2.12.51"
1296
1297         local index
1298
1299         for index in 0 1; do
1300                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1301                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1302         done
1303
1304         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1305
1306         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1307         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1308
1309         local mdts=$(comma_list $(mdts_nodes))
1310
1311         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1312         stack_trap "do_nodes $mdts $LCTL \
1313                 set_param mdt.*.enable_remote_rename=1" EXIT
1314
1315         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1316
1317         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1318         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1319 }
1320 run_test 24z "cross-MDT rename is done as cp"
1321
1322 test_24A() { # LU-3182
1323         local NFILES=5000
1324
1325         rm -rf $DIR/$tdir
1326         test_mkdir $DIR/$tdir
1327         trap simple_cleanup_common EXIT
1328         createmany -m $DIR/$tdir/$tfile $NFILES
1329         local t=$(ls $DIR/$tdir | wc -l)
1330         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1331         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1332         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1333            [ $v -ne $((NFILES + 2)) ] ; then
1334                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1335         fi
1336
1337         simple_cleanup_common || error "Can not delete directories"
1338 }
1339 run_test 24A "readdir() returns correct number of entries."
1340
1341 test_24B() { # LU-4805
1342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1343
1344         local count
1345
1346         test_mkdir $DIR/$tdir
1347         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1348                 error "create striped dir failed"
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 2 ] || error "Expected 2, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/a
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 3 ] || error "Expected 3, got $count"
1357
1358         touch $DIR/$tdir/striped_dir/.f
1359
1360         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1361         [ $count -eq 4 ] || error "Expected 4, got $count"
1362
1363         rm -rf $DIR/$tdir || error "Can not delete directories"
1364 }
1365 run_test 24B "readdir for striped dir return correct number of entries"
1366
1367 test_24C() {
1368         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1369
1370         mkdir $DIR/$tdir
1371         mkdir $DIR/$tdir/d0
1372         mkdir $DIR/$tdir/d1
1373
1374         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1375                 error "create striped dir failed"
1376
1377         cd $DIR/$tdir/d0/striped_dir
1378
1379         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1380         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1381         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1382
1383         [ "$d0_ino" = "$parent_ino" ] ||
1384                 error ".. wrong, expect $d0_ino, get $parent_ino"
1385
1386         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1387                 error "mv striped dir failed"
1388
1389         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1390
1391         [ "$d1_ino" = "$parent_ino" ] ||
1392                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1393 }
1394 run_test 24C "check .. in striped dir"
1395
1396 test_24E() {
1397         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1399
1400         mkdir -p $DIR/$tdir
1401         mkdir $DIR/$tdir/src_dir
1402         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1403                 error "create remote source failed"
1404
1405         touch $DIR/$tdir/src_dir/src_child/a
1406
1407         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1408                 error "create remote target dir failed"
1409
1410         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1411                 error "create remote target child failed"
1412
1413         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1414                 error "rename dir cross MDT failed!"
1415
1416         find $DIR/$tdir
1417
1418         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1419                 error "src_child still exists after rename"
1420
1421         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1422                 error "missing file(a) after rename"
1423
1424         rm -rf $DIR/$tdir || error "Can not delete directories"
1425 }
1426 run_test 24E "cross MDT rename/link"
1427
1428 test_24F () {
1429         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1430
1431         local repeats=1000
1432         [ "$SLOW" = "no" ] && repeats=100
1433
1434         mkdir -p $DIR/$tdir
1435
1436         echo "$repeats repeats"
1437         for ((i = 0; i < repeats; i++)); do
1438                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1439                 touch $DIR/$tdir/test/a || error "touch fails"
1440                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1441                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1442         done
1443
1444         true
1445 }
1446 run_test 24F "hash order vs readdir (LU-11330)"
1447
1448 test_25a() {
1449         echo '== symlink sanity ============================================='
1450
1451         test_mkdir $DIR/d25
1452         ln -s d25 $DIR/s25
1453         touch $DIR/s25/foo ||
1454                 error "File creation in symlinked directory failed"
1455 }
1456 run_test 25a "create file in symlinked directory ==============="
1457
1458 test_25b() {
1459         [ ! -d $DIR/d25 ] && test_25a
1460         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1461 }
1462 run_test 25b "lookup file in symlinked directory ==============="
1463
1464 test_26a() {
1465         test_mkdir $DIR/d26
1466         test_mkdir $DIR/d26/d26-2
1467         ln -s d26/d26-2 $DIR/s26
1468         touch $DIR/s26/foo || error "File creation failed"
1469 }
1470 run_test 26a "multiple component symlink ======================="
1471
1472 test_26b() {
1473         test_mkdir -p $DIR/$tdir/d26-2
1474         ln -s $tdir/d26-2/foo $DIR/s26-2
1475         touch $DIR/s26-2 || error "File creation failed"
1476 }
1477 run_test 26b "multiple component symlink at end of lookup ======"
1478
1479 test_26c() {
1480         test_mkdir $DIR/d26.2
1481         touch $DIR/d26.2/foo
1482         ln -s d26.2 $DIR/s26.2-1
1483         ln -s s26.2-1 $DIR/s26.2-2
1484         ln -s s26.2-2 $DIR/s26.2-3
1485         chmod 0666 $DIR/s26.2-3/foo
1486 }
1487 run_test 26c "chain of symlinks"
1488
1489 # recursive symlinks (bug 439)
1490 test_26d() {
1491         ln -s d26-3/foo $DIR/d26-3
1492 }
1493 run_test 26d "create multiple component recursive symlink"
1494
1495 test_26e() {
1496         [ ! -h $DIR/d26-3 ] && test_26d
1497         rm $DIR/d26-3
1498 }
1499 run_test 26e "unlink multiple component recursive symlink"
1500
1501 # recursive symlinks (bug 7022)
1502 test_26f() {
1503         test_mkdir $DIR/$tdir
1504         test_mkdir $DIR/$tdir/$tfile
1505         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1506         test_mkdir -p lndir/bar1
1507         test_mkdir $DIR/$tdir/$tfile/$tfile
1508         cd $tfile                || error "cd $tfile failed"
1509         ln -s .. dotdot          || error "ln dotdot failed"
1510         ln -s dotdot/lndir lndir || error "ln lndir failed"
1511         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1512         output=`ls $tfile/$tfile/lndir/bar1`
1513         [ "$output" = bar1 ] && error "unexpected output"
1514         rm -r $tfile             || error "rm $tfile failed"
1515         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1516 }
1517 run_test 26f "rm -r of a directory which has recursive symlink"
1518
1519 test_27a() {
1520         test_mkdir $DIR/$tdir
1521         $LFS getstripe $DIR/$tdir
1522         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1523         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1524         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1525 }
1526 run_test 27a "one stripe file"
1527
1528 test_27b() {
1529         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1530
1531         test_mkdir $DIR/$tdir
1532         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1533         $LFS getstripe -c $DIR/$tdir/$tfile
1534         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1535                 error "two-stripe file doesn't have two stripes"
1536
1537         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1538 }
1539 run_test 27b "create and write to two stripe file"
1540
1541 # 27c family tests specific striping, setstripe -o
1542 test_27ca() {
1543         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1544         test_mkdir -p $DIR/$tdir
1545         local osts="1"
1546
1547         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1548         $LFS getstripe -i $DIR/$tdir/$tfile
1549         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1550                 error "stripe not on specified OST"
1551
1552         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1553 }
1554 run_test 27ca "one stripe on specified OST"
1555
1556 test_27cb() {
1557         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1558         test_mkdir -p $DIR/$tdir
1559         local osts="1,0"
1560         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1561         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1562         echo "$getstripe"
1563
1564         # Strip getstripe output to a space separated list of OSTs
1565         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1566                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1567         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1568                 error "stripes not on specified OSTs"
1569
1570         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1571 }
1572 run_test 27cb "two stripes on specified OSTs"
1573
1574 test_27cc() {
1575         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1576         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1577                 skip "server does not support overstriping"
1578
1579         test_mkdir -p $DIR/$tdir
1580         local osts="0,0"
1581         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1582         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1583         echo "$getstripe"
1584
1585         # Strip getstripe output to a space separated list of OSTs
1586         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1587                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1588         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1589                 error "stripes not on specified OSTs"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1592 }
1593 run_test 27cc "two stripes on the same OST"
1594
1595 test_27cd() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1597         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1598                 skip "server does not support overstriping"
1599         test_mkdir -p $DIR/$tdir
1600         local osts="0,1,1,0"
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1602         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1603         echo "$getstripe"
1604
1605         # Strip getstripe output to a space separated list of OSTs
1606         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1607                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1608         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1609                 error "stripes not on specified OSTs"
1610
1611         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1612 }
1613 run_test 27cd "four stripes on two OSTs"
1614
1615 test_27ce() {
1616         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1617                 skip_env "too many osts, skipping"
1618         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1619                 skip "server does not support overstriping"
1620         # We do one more stripe than we have OSTs
1621         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1622                 skip_env "ea_inode feature disabled"
1623
1624         test_mkdir -p $DIR/$tdir
1625         local osts=""
1626         for i in $(seq 0 $OSTCOUNT);
1627         do
1628                 osts=$osts"0"
1629                 if [ $i -ne $OSTCOUNT ]; then
1630                         osts=$osts","
1631                 fi
1632         done
1633         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1634         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1635         echo "$getstripe"
1636
1637         # Strip getstripe output to a space separated list of OSTs
1638         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1639                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1640         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1641                 error "stripes not on specified OSTs"
1642
1643         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1644 }
1645 run_test 27ce "more stripes than OSTs with -o"
1646
1647 test_27cf() {
1648         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1649         local pid=0
1650
1651         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1652         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1653         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1654         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1655                 error "failed to set $osp_proc=0"
1656
1657         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1658         pid=$!
1659         sleep 1
1660         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1661         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1662                 error "failed to set $osp_proc=1"
1663         wait $pid
1664         [[ $pid -ne 0 ]] ||
1665                 error "should return error due to $osp_proc=0"
1666 }
1667 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1668
1669 test_27d() {
1670         test_mkdir $DIR/$tdir
1671         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1672                 error "setstripe failed"
1673         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1674         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1675 }
1676 run_test 27d "create file with default settings"
1677
1678 test_27e() {
1679         # LU-5839 adds check for existed layout before setting it
1680         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1681                 skip "Need MDS version at least 2.7.56"
1682
1683         test_mkdir $DIR/$tdir
1684         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1685         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1686         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1687 }
1688 run_test 27e "setstripe existing file (should return error)"
1689
1690 test_27f() {
1691         test_mkdir $DIR/$tdir
1692         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1693                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1694         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1695                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1696         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1697         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1698 }
1699 run_test 27f "setstripe with bad stripe size (should return error)"
1700
1701 test_27g() {
1702         test_mkdir $DIR/$tdir
1703         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1704         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1705                 error "$DIR/$tdir/$tfile has object"
1706 }
1707 run_test 27g "$LFS getstripe with no objects"
1708
1709 test_27ga() {
1710         test_mkdir $DIR/$tdir
1711         touch $DIR/$tdir/$tfile || error "touch failed"
1712         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1713         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1714         local rc=$?
1715         (( rc == 2 )) || error "getstripe did not return ENOENT"
1716 }
1717 run_test 27ga "$LFS getstripe with missing file (should return error)"
1718
1719 test_27i() {
1720         test_mkdir $DIR/$tdir
1721         touch $DIR/$tdir/$tfile || error "touch failed"
1722         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1723                 error "missing objects"
1724 }
1725 run_test 27i "$LFS getstripe with some objects"
1726
1727 test_27j() {
1728         test_mkdir $DIR/$tdir
1729         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1730                 error "setstripe failed" || true
1731 }
1732 run_test 27j "setstripe with bad stripe offset (should return error)"
1733
1734 test_27k() { # bug 2844
1735         test_mkdir $DIR/$tdir
1736         local file=$DIR/$tdir/$tfile
1737         local ll_max_blksize=$((4 * 1024 * 1024))
1738         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1739         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1740         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1741         dd if=/dev/zero of=$file bs=4k count=1
1742         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1743         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1744 }
1745 run_test 27k "limit i_blksize for broken user apps"
1746
1747 test_27l() {
1748         mcreate $DIR/$tfile || error "creating file"
1749         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1750                 error "setstripe should have failed" || true
1751 }
1752 run_test 27l "check setstripe permissions (should return error)"
1753
1754 test_27m() {
1755         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1756
1757         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1758                 skip_env "multiple clients -- skipping"
1759
1760         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1761                    head -n1)
1762         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1763                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1764         fi
1765         trap simple_cleanup_common EXIT
1766         test_mkdir $DIR/$tdir
1767         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1768         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1769                 error "dd should fill OST0"
1770         i=2
1771         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1772                 i=$((i + 1))
1773                 [ $i -gt 256 ] && break
1774         done
1775         i=$((i + 1))
1776         touch $DIR/$tdir/$tfile.$i
1777         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1778             awk '{print $1}'| grep -w "0") ] &&
1779                 error "OST0 was full but new created file still use it"
1780         i=$((i + 1))
1781         touch $DIR/$tdir/$tfile.$i
1782         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1783             awk '{print $1}'| grep -w "0") ] &&
1784                 error "OST0 was full but new created file still use it"
1785         simple_cleanup_common
1786 }
1787 run_test 27m "create file while OST0 was full"
1788
1789 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1790 # if the OST isn't full anymore.
1791 reset_enospc() {
1792         local ostidx=${1:-""}
1793         local delay
1794         local ready
1795         local get_prealloc
1796
1797         local list=$(comma_list $(osts_nodes))
1798         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1799
1800         do_nodes $list lctl set_param fail_loc=0
1801         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1802         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1803                 awk '{print $1 * 2;exit;}')
1804         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1805                         grep -v \"^0$\""
1806         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1807 }
1808
1809 __exhaust_precreations() {
1810         local OSTIDX=$1
1811         local FAILLOC=$2
1812         local FAILIDX=${3:-$OSTIDX}
1813         local ofacet=ost$((OSTIDX + 1))
1814
1815         test_mkdir -p -c1 $DIR/$tdir
1816         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1817         local mfacet=mds$((mdtidx + 1))
1818         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1819
1820         local OST=$(ostname_from_index $OSTIDX)
1821
1822         # on the mdt's osc
1823         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1824         local last_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_last_id)
1826         local next_id=$(do_facet $mfacet lctl get_param -n \
1827                         osp.$mdtosc_proc1.prealloc_next_id)
1828
1829         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1830         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1831
1832         test_mkdir -p $DIR/$tdir/${OST}
1833         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1834 #define OBD_FAIL_OST_ENOSPC              0x215
1835         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1836         echo "Creating to objid $last_id on ost $OST..."
1837         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1838         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1839         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1840 }
1841
1842 exhaust_precreations() {
1843         __exhaust_precreations $1 $2 $3
1844         sleep_maxage
1845 }
1846
1847 exhaust_all_precreations() {
1848         local i
1849         for (( i=0; i < OSTCOUNT; i++ )) ; do
1850                 __exhaust_precreations $i $1 -1
1851         done
1852         sleep_maxage
1853 }
1854
1855 test_27n() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863         exhaust_precreations 0 0x80000215
1864         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1865         touch $DIR/$tdir/$tfile || error "touch failed"
1866         $LFS getstripe $DIR/$tdir/$tfile
1867         reset_enospc
1868 }
1869 run_test 27n "create file with some full OSTs"
1870
1871 test_27o() {
1872         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1874         remote_mds_nodsh && skip "remote MDS with nodsh"
1875         remote_ost_nodsh && skip "remote OST with nodsh"
1876
1877         reset_enospc
1878         rm -f $DIR/$tdir/$tfile
1879         exhaust_all_precreations 0x215
1880
1881         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1882
1883         reset_enospc
1884         rm -rf $DIR/$tdir/*
1885 }
1886 run_test 27o "create file with all full OSTs (should error)"
1887
1888 test_27p() {
1889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1891         remote_mds_nodsh && skip "remote MDS with nodsh"
1892         remote_ost_nodsh && skip "remote OST with nodsh"
1893
1894         reset_enospc
1895         rm -f $DIR/$tdir/$tfile
1896         test_mkdir $DIR/$tdir
1897
1898         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1899         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1900         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1901
1902         exhaust_precreations 0 0x80000215
1903         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1904         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1905         $LFS getstripe $DIR/$tdir/$tfile
1906
1907         reset_enospc
1908 }
1909 run_test 27p "append to a truncated file with some full OSTs"
1910
1911 test_27q() {
1912         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1914         remote_mds_nodsh && skip "remote MDS with nodsh"
1915         remote_ost_nodsh && skip "remote OST with nodsh"
1916
1917         reset_enospc
1918         rm -f $DIR/$tdir/$tfile
1919
1920         test_mkdir $DIR/$tdir
1921         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1922         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1923                 error "truncate $DIR/$tdir/$tfile failed"
1924         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1925
1926         exhaust_all_precreations 0x215
1927
1928         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1929         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1930
1931         reset_enospc
1932 }
1933 run_test 27q "append to truncated file with all OSTs full (should error)"
1934
1935 test_27r() {
1936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1938         remote_mds_nodsh && skip "remote MDS with nodsh"
1939         remote_ost_nodsh && skip "remote OST with nodsh"
1940
1941         reset_enospc
1942         rm -f $DIR/$tdir/$tfile
1943         exhaust_precreations 0 0x80000215
1944
1945         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1946
1947         reset_enospc
1948 }
1949 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1950
1951 test_27s() { # bug 10725
1952         test_mkdir $DIR/$tdir
1953         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1954         local stripe_count=0
1955         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1956         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1957                 error "stripe width >= 2^32 succeeded" || true
1958
1959 }
1960 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1961
1962 test_27t() { # bug 10864
1963         WDIR=$(pwd)
1964         WLFS=$(which lfs)
1965         cd $DIR
1966         touch $tfile
1967         $WLFS getstripe $tfile
1968         cd $WDIR
1969 }
1970 run_test 27t "check that utils parse path correctly"
1971
1972 test_27u() { # bug 4900
1973         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1974         remote_mds_nodsh && skip "remote MDS with nodsh"
1975
1976         local index
1977         local list=$(comma_list $(mdts_nodes))
1978
1979 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1980         do_nodes $list $LCTL set_param fail_loc=0x139
1981         test_mkdir -p $DIR/$tdir
1982         trap simple_cleanup_common EXIT
1983         createmany -o $DIR/$tdir/t- 1000
1984         do_nodes $list $LCTL set_param fail_loc=0
1985
1986         TLOG=$TMP/$tfile.getstripe
1987         $LFS getstripe $DIR/$tdir > $TLOG
1988         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1989         unlinkmany $DIR/$tdir/t- 1000
1990         trap 0
1991         [[ $OBJS -gt 0 ]] &&
1992                 error "$OBJS objects created on OST-0. See $TLOG" ||
1993                 rm -f $TLOG
1994 }
1995 run_test 27u "skip object creation on OSC w/o objects"
1996
1997 test_27v() { # bug 4900
1998         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2000         remote_mds_nodsh && skip "remote MDS with nodsh"
2001         remote_ost_nodsh && skip "remote OST with nodsh"
2002
2003         exhaust_all_precreations 0x215
2004         reset_enospc
2005
2006         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2007
2008         touch $DIR/$tdir/$tfile
2009         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2010         # all except ost1
2011         for (( i=1; i < OSTCOUNT; i++ )); do
2012                 do_facet ost$i lctl set_param fail_loc=0x705
2013         done
2014         local START=`date +%s`
2015         createmany -o $DIR/$tdir/$tfile 32
2016
2017         local FINISH=`date +%s`
2018         local TIMEOUT=`lctl get_param -n timeout`
2019         local PROCESS=$((FINISH - START))
2020         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2021                error "$FINISH - $START >= $TIMEOUT / 2"
2022         sleep $((TIMEOUT / 2 - PROCESS))
2023         reset_enospc
2024 }
2025 run_test 27v "skip object creation on slow OST"
2026
2027 test_27w() { # bug 10997
2028         test_mkdir $DIR/$tdir
2029         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2030         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2031                 error "stripe size $size != 65536" || true
2032         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2033                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2034 }
2035 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2036
2037 test_27wa() {
2038         [[ $OSTCOUNT -lt 2 ]] &&
2039                 skip_env "skipping multiple stripe count/offset test"
2040
2041         test_mkdir $DIR/$tdir
2042         for i in $(seq 1 $OSTCOUNT); do
2043                 offset=$((i - 1))
2044                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2045                         error "setstripe -c $i -i $offset failed"
2046                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2047                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2048                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2049                 [ $index -ne $offset ] &&
2050                         error "stripe offset $index != $offset" || true
2051         done
2052 }
2053 run_test 27wa "check $LFS setstripe -c -i options"
2054
2055 test_27x() {
2056         remote_ost_nodsh && skip "remote OST with nodsh"
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2059
2060         OFFSET=$(($OSTCOUNT - 1))
2061         OSTIDX=0
2062         local OST=$(ostname_from_index $OSTIDX)
2063
2064         test_mkdir $DIR/$tdir
2065         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2066         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2067         sleep_maxage
2068         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2069         for i in $(seq 0 $OFFSET); do
2070                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2071                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2072                 error "OST0 was degraded but new created file still use it"
2073         done
2074         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2075 }
2076 run_test 27x "create files while OST0 is degraded"
2077
2078 test_27y() {
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         remote_mds_nodsh && skip "remote MDS with nodsh"
2081         remote_ost_nodsh && skip "remote OST with nodsh"
2082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2083
2084         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2085         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_last_id)
2087         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2088                 osp.$mdtosc.prealloc_next_id)
2089         local fcount=$((last_id - next_id))
2090         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2091         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2092
2093         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2094                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2095         local OST_DEACTIVE_IDX=-1
2096         local OSC
2097         local OSTIDX
2098         local OST
2099
2100         for OSC in $MDS_OSCS; do
2101                 OST=$(osc_to_ost $OSC)
2102                 OSTIDX=$(index_from_ostuuid $OST)
2103                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2104                         OST_DEACTIVE_IDX=$OSTIDX
2105                 fi
2106                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2107                         echo $OSC "is Deactivated:"
2108                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2109                 fi
2110         done
2111
2112         OSTIDX=$(index_from_ostuuid $OST)
2113         test_mkdir $DIR/$tdir
2114         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2115
2116         for OSC in $MDS_OSCS; do
2117                 OST=$(osc_to_ost $OSC)
2118                 OSTIDX=$(index_from_ostuuid $OST)
2119                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2120                         echo $OST "is degraded:"
2121                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2122                                                 obdfilter.$OST.degraded=1
2123                 fi
2124         done
2125
2126         sleep_maxage
2127         createmany -o $DIR/$tdir/$tfile $fcount
2128
2129         for OSC in $MDS_OSCS; do
2130                 OST=$(osc_to_ost $OSC)
2131                 OSTIDX=$(index_from_ostuuid $OST)
2132                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2133                         echo $OST "is recovered from degraded:"
2134                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2135                                                 obdfilter.$OST.degraded=0
2136                 else
2137                         do_facet $SINGLEMDS lctl --device %$OSC activate
2138                 fi
2139         done
2140
2141         # all osp devices get activated, hence -1 stripe count restored
2142         local stripe_count=0
2143
2144         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2145         # devices get activated.
2146         sleep_maxage
2147         $LFS setstripe -c -1 $DIR/$tfile
2148         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2149         rm -f $DIR/$tfile
2150         [ $stripe_count -ne $OSTCOUNT ] &&
2151                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2152         return 0
2153 }
2154 run_test 27y "create files while OST0 is degraded and the rest inactive"
2155
2156 check_seq_oid()
2157 {
2158         log "check file $1"
2159
2160         lmm_count=$($LFS getstripe -c $1)
2161         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2162         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2163
2164         local old_ifs="$IFS"
2165         IFS=$'[:]'
2166         fid=($($LFS path2fid $1))
2167         IFS="$old_ifs"
2168
2169         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2170         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2171
2172         # compare lmm_seq and lu_fid->f_seq
2173         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2174         # compare lmm_object_id and lu_fid->oid
2175         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2176
2177         # check the trusted.fid attribute of the OST objects of the file
2178         local have_obdidx=false
2179         local stripe_nr=0
2180         $LFS getstripe $1 | while read obdidx oid hex seq; do
2181                 # skip lines up to and including "obdidx"
2182                 [ -z "$obdidx" ] && break
2183                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2184                 $have_obdidx || continue
2185
2186                 local ost=$((obdidx + 1))
2187                 local dev=$(ostdevname $ost)
2188                 local oid_hex
2189
2190                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2191
2192                 seq=$(echo $seq | sed -e "s/^0x//g")
2193                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2194                         oid_hex=$(echo $oid)
2195                 else
2196                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2197                 fi
2198                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2199
2200                 local ff=""
2201                 #
2202                 # Don't unmount/remount the OSTs if we don't need to do that.
2203                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2204                 # update too, until that use mount/ll_decode_filter_fid/mount.
2205                 # Re-enable when debugfs will understand new filter_fid.
2206                 #
2207                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2208                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2209                                 $dev 2>/dev/null" | grep "parent=")
2210                 fi
2211                 if [ -z "$ff" ]; then
2212                         stop ost$ost
2213                         mount_fstype ost$ost
2214                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2215                                 $(facet_mntpt ost$ost)/$obj_file)
2216                         unmount_fstype ost$ost
2217                         start ost$ost $dev $OST_MOUNT_OPTS
2218                         clients_up
2219                 fi
2220
2221                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2222
2223                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2224
2225                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2226                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2227                 #
2228                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2229                 #       stripe_size=1048576 component_id=1 component_start=0 \
2230                 #       component_end=33554432
2231                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2232                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2233                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2234                 local ff_pstripe
2235                 if grep -q 'stripe=' <<<$ff; then
2236                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2237                 else
2238                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2239                         # into f_ver in this case.  See comment on ff_parent.
2240                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2241                 fi
2242
2243                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2244                 [ $ff_pseq = $lmm_seq ] ||
2245                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2246                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2247                 [ $ff_poid = $lmm_oid ] ||
2248                         error "FF parent OID $ff_poid != $lmm_oid"
2249                 (($ff_pstripe == $stripe_nr)) ||
2250                         error "FF stripe $ff_pstripe != $stripe_nr"
2251
2252                 stripe_nr=$((stripe_nr + 1))
2253                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2254                         continue
2255                 if grep -q 'stripe_count=' <<<$ff; then
2256                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2257                                             -e 's/ .*//' <<<$ff)
2258                         [ $lmm_count = $ff_scnt ] ||
2259                                 error "FF stripe count $lmm_count != $ff_scnt"
2260                 fi
2261         done
2262 }
2263
2264 test_27z() {
2265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2266         remote_ost_nodsh && skip "remote OST with nodsh"
2267
2268         test_mkdir $DIR/$tdir
2269         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2270                 { error "setstripe -c -1 failed"; return 1; }
2271         # We need to send a write to every object to get parent FID info set.
2272         # This _should_ also work for setattr, but does not currently.
2273         # touch $DIR/$tdir/$tfile-1 ||
2274         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2275                 { error "dd $tfile-1 failed"; return 2; }
2276         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2277                 { error "setstripe -c -1 failed"; return 3; }
2278         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2279                 { error "dd $tfile-2 failed"; return 4; }
2280
2281         # make sure write RPCs have been sent to OSTs
2282         sync; sleep 5; sync
2283
2284         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2285         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2286 }
2287 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2288
2289 test_27A() { # b=19102
2290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2291
2292         save_layout_restore_at_exit $MOUNT
2293         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2294         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2295                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2296         local default_size=$($LFS getstripe -S $MOUNT)
2297         local default_offset=$($LFS getstripe -i $MOUNT)
2298         local dsize=$(do_facet $SINGLEMDS \
2299                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2300         [ $default_size -eq $dsize ] ||
2301                 error "stripe size $default_size != $dsize"
2302         [ $default_offset -eq -1 ] ||
2303                 error "stripe offset $default_offset != -1"
2304 }
2305 run_test 27A "check filesystem-wide default LOV EA values"
2306
2307 test_27B() { # LU-2523
2308         test_mkdir $DIR/$tdir
2309         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2310         touch $DIR/$tdir/f0
2311         # open f1 with O_LOV_DELAY_CREATE
2312         # rename f0 onto f1
2313         # call setstripe ioctl on open file descriptor for f1
2314         # close
2315         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2316                 $DIR/$tdir/f0
2317
2318         rm -f $DIR/$tdir/f1
2319         # open f1 with O_LOV_DELAY_CREATE
2320         # unlink f1
2321         # call setstripe ioctl on open file descriptor for f1
2322         # close
2323         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2324
2325         # Allow multiop to fail in imitation of NFS's busted semantics.
2326         true
2327 }
2328 run_test 27B "call setstripe on open unlinked file/rename victim"
2329
2330 # 27C family tests full striping and overstriping
2331 test_27Ca() { #LU-2871
2332         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2333
2334         declare -a ost_idx
2335         local index
2336         local found
2337         local i
2338         local j
2339
2340         test_mkdir $DIR/$tdir
2341         cd $DIR/$tdir
2342         for i in $(seq 0 $((OSTCOUNT - 1))); do
2343                 # set stripe across all OSTs starting from OST$i
2344                 $LFS setstripe -i $i -c -1 $tfile$i
2345                 # get striping information
2346                 ost_idx=($($LFS getstripe $tfile$i |
2347                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2348                 echo ${ost_idx[@]}
2349
2350                 # check the layout
2351                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2352                         error "${#ost_idx[@]} != $OSTCOUNT"
2353
2354                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2355                         found=0
2356                         for j in $(echo ${ost_idx[@]}); do
2357                                 if [ $index -eq $j ]; then
2358                                         found=1
2359                                         break
2360                                 fi
2361                         done
2362                         [ $found = 1 ] ||
2363                                 error "Can not find $index in ${ost_idx[@]}"
2364                 done
2365         done
2366 }
2367 run_test 27Ca "check full striping across all OSTs"
2368
2369 test_27Cb() {
2370         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2371                 skip "server does not support overstriping"
2372         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2373                 skip_env "too many osts, skipping"
2374
2375         test_mkdir -p $DIR/$tdir
2376         local setcount=$(($OSTCOUNT * 2))
2377         [ $setcount -ge 160 ] || large_xattr_enabled ||
2378                 skip_env "ea_inode feature disabled"
2379
2380         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2381                 error "setstripe failed"
2382
2383         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2384         [ $count -eq $setcount ] ||
2385                 error "stripe count $count, should be $setcount"
2386
2387         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2388                 error "overstriped should be set in pattern"
2389
2390         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2391                 error "dd failed"
2392 }
2393 run_test 27Cb "more stripes than OSTs with -C"
2394
2395 test_27Cc() {
2396         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2397                 skip "server does not support overstriping"
2398         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2399
2400         test_mkdir -p $DIR/$tdir
2401         local setcount=$(($OSTCOUNT - 1))
2402
2403         [ $setcount -ge 160 ] || large_xattr_enabled ||
2404                 skip_env "ea_inode feature disabled"
2405
2406         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2407                 error "setstripe failed"
2408
2409         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2410         [ $count -eq $setcount ] ||
2411                 error "stripe count $count, should be $setcount"
2412
2413         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2414                 error "overstriped should not be set in pattern"
2415
2416         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2417                 error "dd failed"
2418 }
2419 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2420
2421 test_27Cd() {
2422         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2423                 skip "server does not support overstriping"
2424         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2425         large_xattr_enabled || skip_env "ea_inode feature disabled"
2426
2427         test_mkdir -p $DIR/$tdir
2428         local setcount=$LOV_MAX_STRIPE_COUNT
2429
2430         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2431                 error "setstripe failed"
2432
2433         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2434         [ $count -eq $setcount ] ||
2435                 error "stripe count $count, should be $setcount"
2436
2437         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2438                 error "overstriped should be set in pattern"
2439
2440         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2441                 error "dd failed"
2442
2443         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2444 }
2445 run_test 27Cd "test maximum stripe count"
2446
2447 test_27Ce() {
2448         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2449                 skip "server does not support overstriping"
2450         test_mkdir -p $DIR/$tdir
2451
2452         pool_add $TESTNAME || error "Pool creation failed"
2453         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2454
2455         local setcount=8
2456
2457         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2465                 error "overstriped should be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469
2470         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2471 }
2472 run_test 27Ce "test pool with overstriping"
2473
2474 test_27Cf() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2478                 skip_env "too many osts, skipping"
2479
2480         test_mkdir -p $DIR/$tdir
2481
2482         local setcount=$(($OSTCOUNT * 2))
2483         [ $setcount -ge 160 ] || large_xattr_enabled ||
2484                 skip_env "ea_inode feature disabled"
2485
2486         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2487                 error "setstripe failed"
2488
2489         echo 1 > $DIR/$tdir/$tfile
2490
2491         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2492         [ $count -eq $setcount ] ||
2493                 error "stripe count $count, should be $setcount"
2494
2495         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2496                 error "overstriped should be set in pattern"
2497
2498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2499                 error "dd failed"
2500
2501         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2502 }
2503 run_test 27Cf "test default inheritance with overstriping"
2504
2505 test_27D() {
2506         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2507         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2508         remote_mds_nodsh && skip "remote MDS with nodsh"
2509
2510         local POOL=${POOL:-testpool}
2511         local first_ost=0
2512         local last_ost=$(($OSTCOUNT - 1))
2513         local ost_step=1
2514         local ost_list=$(seq $first_ost $ost_step $last_ost)
2515         local ost_range="$first_ost $last_ost $ost_step"
2516
2517         test_mkdir $DIR/$tdir
2518         pool_add $POOL || error "pool_add failed"
2519         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2520
2521         local skip27D
2522         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2523                 skip27D+="-s 29"
2524         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2525                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2526                         skip27D+=" -s 30,31"
2527         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2528           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip27D+=" -s 32,33"
2530         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2531                 skip27D+=" -s 34"
2532         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2533                 error "llapi_layout_test failed"
2534
2535         destroy_test_pools || error "destroy test pools failed"
2536 }
2537 run_test 27D "validate llapi_layout API"
2538
2539 # Verify that default_easize is increased from its initial value after
2540 # accessing a widely striped file.
2541 test_27E() {
2542         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2543         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2544                 skip "client does not have LU-3338 fix"
2545
2546         # 72 bytes is the minimum space required to store striping
2547         # information for a file striped across one OST:
2548         # (sizeof(struct lov_user_md_v3) +
2549         #  sizeof(struct lov_user_ost_data_v1))
2550         local min_easize=72
2551         $LCTL set_param -n llite.*.default_easize $min_easize ||
2552                 error "lctl set_param failed"
2553         local easize=$($LCTL get_param -n llite.*.default_easize)
2554
2555         [ $easize -eq $min_easize ] ||
2556                 error "failed to set default_easize"
2557
2558         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2559                 error "setstripe failed"
2560         # In order to ensure stat() call actually talks to MDS we need to
2561         # do something drastic to this file to shake off all lock, e.g.
2562         # rename it (kills lookup lock forcing cache cleaning)
2563         mv $DIR/$tfile $DIR/${tfile}-1
2564         ls -l $DIR/${tfile}-1
2565         rm $DIR/${tfile}-1
2566
2567         easize=$($LCTL get_param -n llite.*.default_easize)
2568
2569         [ $easize -gt $min_easize ] ||
2570                 error "default_easize not updated"
2571 }
2572 run_test 27E "check that default extended attribute size properly increases"
2573
2574 test_27F() { # LU-5346/LU-7975
2575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2576         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2577         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2578                 skip "Need MDS version at least 2.8.51"
2579         remote_ost_nodsh && skip "remote OST with nodsh"
2580
2581         test_mkdir $DIR/$tdir
2582         rm -f $DIR/$tdir/f0
2583         $LFS setstripe -c 2 $DIR/$tdir
2584
2585         # stop all OSTs to reproduce situation for LU-7975 ticket
2586         for num in $(seq $OSTCOUNT); do
2587                 stop ost$num
2588         done
2589
2590         # open/create f0 with O_LOV_DELAY_CREATE
2591         # truncate f0 to a non-0 size
2592         # close
2593         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2594
2595         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2596         # open/write it again to force delayed layout creation
2597         cat /etc/hosts > $DIR/$tdir/f0 &
2598         catpid=$!
2599
2600         # restart OSTs
2601         for num in $(seq $OSTCOUNT); do
2602                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2603                         error "ost$num failed to start"
2604         done
2605
2606         wait $catpid || error "cat failed"
2607
2608         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2609         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2610                 error "wrong stripecount"
2611
2612 }
2613 run_test 27F "Client resend delayed layout creation with non-zero size"
2614
2615 test_27G() { #LU-10629
2616         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2617                 skip "Need MDS version at least 2.11.51"
2618         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2619         remote_mds_nodsh && skip "remote MDS with nodsh"
2620         local POOL=${POOL:-testpool}
2621         local ostrange="0 0 1"
2622
2623         test_mkdir $DIR/$tdir
2624         touch $DIR/$tdir/$tfile.nopool
2625         pool_add $POOL || error "pool_add failed"
2626         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2627         $LFS setstripe -p $POOL $DIR/$tdir
2628
2629         local pool=$($LFS getstripe -p $DIR/$tdir)
2630
2631         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2632         touch $DIR/$tdir/$tfile.default
2633         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2634         $LFS find $DIR/$tdir -type f --pool $POOL
2635         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2636         [[ "$found" == "2" ]] ||
2637                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2638
2639         $LFS setstripe -d $DIR/$tdir
2640
2641         pool=$($LFS getstripe -p -d $DIR/$tdir)
2642
2643         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2644 }
2645 run_test 27G "Clear OST pool from stripe"
2646
2647 test_27H() {
2648         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2649                 skip "Need MDS version newer than 2.11.54"
2650         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2651         test_mkdir $DIR/$tdir
2652         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2653         touch $DIR/$tdir/$tfile
2654         $LFS getstripe -c $DIR/$tdir/$tfile
2655         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2656                 error "two-stripe file doesn't have two stripes"
2657
2658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2659         $LFS getstripe -y $DIR/$tdir/$tfile
2660         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2661              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2662                 error "expected l_ost_idx: [02]$ not matched"
2663
2664         # make sure ost list has been cleared
2665         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2666         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2667                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2668         touch $DIR/$tdir/f3
2669         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2670 }
2671 run_test 27H "Set specific OSTs stripe"
2672
2673 test_27I() {
2674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2675         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2676         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2677                 skip "Need MDS version newer than 2.12.52"
2678         local pool=$TESTNAME
2679         local ostrange="1 1 1"
2680
2681         save_layout_restore_at_exit $MOUNT
2682         $LFS setstripe -c 2 -i 0 $MOUNT
2683         pool_add $pool || error "pool_add failed"
2684         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2685         test_mkdir $DIR/$tdir
2686         $LFS setstripe -p $pool $DIR/$tdir
2687         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2688         $LFS getstripe $DIR/$tdir/$tfile
2689 }
2690 run_test 27I "check that root dir striping does not break parent dir one"
2691
2692 test_27J() {
2693         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2694                 skip "Need MDS version newer than 2.12.51"
2695
2696         test_mkdir $DIR/$tdir
2697         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2698         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2699
2700         # create foreign file (raw way)
2701         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2702                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2703
2704         # verify foreign file (raw way)
2705         parse_foreign_file -f $DIR/$tdir/$tfile |
2706                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2708         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2709                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2710         parse_foreign_file -f $DIR/$tdir/$tfile |
2711                 grep "lov_foreign_size: 73" ||
2712                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2713         parse_foreign_file -f $DIR/$tdir/$tfile |
2714                 grep "lov_foreign_type: 1" ||
2715                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2716         parse_foreign_file -f $DIR/$tdir/$tfile |
2717                 grep "lov_foreign_flags: 0x0000DA08" ||
2718                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2719         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2720                 grep "lov_foreign_value: 0x" |
2721                 sed -e 's/lov_foreign_value: 0x//')
2722         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2723         [[ $lov = ${lov2// /} ]] ||
2724                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2725
2726         # create foreign file (lfs + API)
2727         $LFS setstripe --foreign=daos --flags 0xda08 \
2728                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2729                 error "$DIR/$tdir/${tfile}2: create failed"
2730
2731         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2732                 grep "lfm_magic:.*0x0BD70BD0" ||
2733                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2734         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2738                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2739         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2740                 grep "lfm_flags:.*0x0000DA08" ||
2741                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2742         $LFS getstripe $DIR/$tdir/${tfile}2 |
2743                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2744                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2745
2746         # modify striping should fail
2747         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2748                 error "$DIR/$tdir/$tfile: setstripe should fail"
2749         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2750                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2751
2752         # R/W should fail
2753         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2754         cat $DIR/$tdir/${tfile}2 &&
2755                 error "$DIR/$tdir/${tfile}2: read should fail"
2756         cat /etc/passwd > $DIR/$tdir/$tfile &&
2757                 error "$DIR/$tdir/$tfile: write should fail"
2758         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2759                 error "$DIR/$tdir/${tfile}2: write should fail"
2760
2761         # chmod should work
2762         chmod 222 $DIR/$tdir/$tfile ||
2763                 error "$DIR/$tdir/$tfile: chmod failed"
2764         chmod 222 $DIR/$tdir/${tfile}2 ||
2765                 error "$DIR/$tdir/${tfile}2: chmod failed"
2766
2767         # chown should work
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2769                 error "$DIR/$tdir/$tfile: chown failed"
2770         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2771                 error "$DIR/$tdir/${tfile}2: chown failed"
2772
2773         # rename should work
2774         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2775                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2776         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2777                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2778
2779         #remove foreign file
2780         rm $DIR/$tdir/${tfile}.new ||
2781                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2782         rm $DIR/$tdir/${tfile}2.new ||
2783                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2784 }
2785 run_test 27J "basic ops on file with foreign LOV"
2786
2787 test_27K() {
2788         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2789                 skip "Need MDS version newer than 2.12.49"
2790
2791         test_mkdir $DIR/$tdir
2792         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2793         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2794
2795         # create foreign dir (raw way)
2796         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2797                 error "create_foreign_dir FAILED"
2798
2799         # verify foreign dir (raw way)
2800         parse_foreign_dir -d $DIR/$tdir/$tdir |
2801                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2802                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2807         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2808                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2809         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2810                 grep "lmv_foreign_value: 0x" |
2811                 sed 's/lmv_foreign_value: 0x//')
2812         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2813                 sed 's/ //g')
2814         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2815
2816         # create foreign dir (lfs + API)
2817         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2818                 $DIR/$tdir/${tdir}2 ||
2819                 error "$DIR/$tdir/${tdir}2: create failed"
2820
2821         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2822                 grep "lfm_magic:.*0x0CD50CD0" ||
2823                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2824         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2825         # - sizeof(lfm_type) - sizeof(lfm_flags)
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2829                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2830         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2831                 grep "lfm_flags:.*0x0000DA05" ||
2832                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2833         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2834                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2835                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2836
2837         # file create in dir should fail
2838         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2839         touch $DIR/$tdir/${tdir}2/$tfile &&
2840                 "$DIR/${tdir}2: file create should fail"
2841
2842         # chmod should work
2843         chmod 777 $DIR/$tdir/$tdir ||
2844                 error "$DIR/$tdir: chmod failed"
2845         chmod 777 $DIR/$tdir/${tdir}2 ||
2846                 error "$DIR/${tdir}2: chmod failed"
2847
2848         # chown should work
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2850                 error "$DIR/$tdir: chown failed"
2851         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2852                 error "$DIR/${tdir}2: chown failed"
2853
2854         # rename should work
2855         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2856                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2857         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2858                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2859
2860         #remove foreign dir
2861         rmdir $DIR/$tdir/${tdir}.new ||
2862                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2863         rmdir $DIR/$tdir/${tdir}2.new ||
2864                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2865 }
2866 run_test 27K "basic ops on dir with foreign LMV"
2867
2868 test_27L() {
2869         remote_mds_nodsh && skip "remote MDS with nodsh"
2870
2871         local POOL=${POOL:-$TESTNAME}
2872
2873         pool_add $POOL || error "pool_add failed"
2874
2875         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2876                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2877                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2878 }
2879 run_test 27L "lfs pool_list gives correct pool name"
2880
2881 test_27M() {
2882         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2883                 skip "Need MDS version >= than 2.12.57"
2884         remote_mds_nodsh && skip "remote MDS with nodsh"
2885         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2886
2887         test_mkdir $DIR/$tdir
2888
2889         # Set default striping on directory
2890         $LFS setstripe -C 4 $DIR/$tdir
2891
2892         echo 1 > $DIR/$tdir/${tfile}.1
2893         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2894         local setcount=4
2895         [ $count -eq $setcount ] ||
2896                 error "(1) stripe count $count, should be $setcount"
2897
2898         # Capture existing append_stripe_count setting for restore
2899         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2900         local mdts=$(comma_list $(mdts_nodes))
2901         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2902
2903         local appendcount=$orig_count
2904         echo 1 >> $DIR/$tdir/${tfile}.2_append
2905         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2906         [ $count -eq $appendcount ] ||
2907                 error "(2)stripe count $count, should be $appendcount for append"
2908
2909         # Disable O_APPEND striping, verify it works
2910         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2911
2912         # Should now get the default striping, which is 4
2913         setcount=4
2914         echo 1 >> $DIR/$tdir/${tfile}.3_append
2915         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2916         [ $count -eq $setcount ] ||
2917                 error "(3) stripe count $count, should be $setcount"
2918
2919         # Try changing the stripe count for append files
2920         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2921
2922         # Append striping is now 2 (directory default is still 4)
2923         appendcount=2
2924         echo 1 >> $DIR/$tdir/${tfile}.4_append
2925         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2926         [ $count -eq $appendcount ] ||
2927                 error "(4) stripe count $count, should be $appendcount for append"
2928
2929         # Test append stripe count of -1
2930         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2931         appendcount=$OSTCOUNT
2932         echo 1 >> $DIR/$tdir/${tfile}.5
2933         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2934         [ $count -eq $appendcount ] ||
2935                 error "(5) stripe count $count, should be $appendcount for append"
2936
2937         # Set append striping back to default of 1
2938         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2939
2940         # Try a new default striping, PFL + DOM
2941         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2942
2943         # Create normal DOM file, DOM returns stripe count == 0
2944         setcount=0
2945         touch $DIR/$tdir/${tfile}.6
2946         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2947         [ $count -eq $setcount ] ||
2948                 error "(6) stripe count $count, should be $setcount"
2949
2950         # Show
2951         appendcount=1
2952         echo 1 >> $DIR/$tdir/${tfile}.7_append
2953         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2954         [ $count -eq $appendcount ] ||
2955                 error "(7) stripe count $count, should be $appendcount for append"
2956
2957         # Clean up DOM layout
2958         $LFS setstripe -d $DIR/$tdir
2959
2960         # Now test that append striping works when layout is from root
2961         $LFS setstripe -c 2 $MOUNT
2962         # Make a special directory for this
2963         mkdir $DIR/${tdir}/${tdir}.2
2964         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2965
2966         # Verify for normal file
2967         setcount=2
2968         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2969         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2970         [ $count -eq $setcount ] ||
2971                 error "(8) stripe count $count, should be $setcount"
2972
2973         appendcount=1
2974         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2975         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2976         [ $count -eq $appendcount ] ||
2977                 error "(9) stripe count $count, should be $appendcount for append"
2978
2979         # Now test O_APPEND striping with pools
2980         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2981         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2982
2983         # Create the pool
2984         pool_add $TESTNAME || error "pool creation failed"
2985         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2986
2987         echo 1 >> $DIR/$tdir/${tfile}.10_append
2988
2989         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2990         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2991
2992         # Check that count is still correct
2993         appendcount=1
2994         echo 1 >> $DIR/$tdir/${tfile}.11_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(11) stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND stripe count, verify pool works separately
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         echo 1 >> $DIR/$tdir/${tfile}.12_append
3003
3004         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3005         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3006
3007         # Remove pool setting, verify it's not applied
3008         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3009
3010         echo 1 >> $DIR/$tdir/${tfile}.13_append
3011
3012         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3013         [ "$pool" = "" ] || error "(13) pool found: $pool"
3014 }
3015 run_test 27M "test O_APPEND striping"
3016
3017 test_27N() {
3018         combined_mgs_mds && skip "needs separate MGS/MDT"
3019
3020         pool_add $TESTNAME || error "pool_add failed"
3021         do_facet mgs "$LCTL pool_list $FSNAME" |
3022                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3023                 error "lctl pool_list on MGS failed"
3024 }
3025 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3026
3027 # createtest also checks that device nodes are created and
3028 # then visible correctly (#2091)
3029 test_28() { # bug 2091
3030         test_mkdir $DIR/d28
3031         $CREATETEST $DIR/d28/ct || error "createtest failed"
3032 }
3033 run_test 28 "create/mknod/mkdir with bad file types ============"
3034
3035 test_29() {
3036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3037
3038         sync; sleep 1; sync # flush out any dirty pages from previous tests
3039         cancel_lru_locks
3040         test_mkdir $DIR/d29
3041         touch $DIR/d29/foo
3042         log 'first d29'
3043         ls -l $DIR/d29
3044
3045         declare -i LOCKCOUNTORIG=0
3046         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3047                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3048         done
3049         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3050
3051         declare -i LOCKUNUSEDCOUNTORIG=0
3052         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3053                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3054         done
3055
3056         log 'second d29'
3057         ls -l $DIR/d29
3058         log 'done'
3059
3060         declare -i LOCKCOUNTCURRENT=0
3061         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3062                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3063         done
3064
3065         declare -i LOCKUNUSEDCOUNTCURRENT=0
3066         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3067                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3068         done
3069
3070         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3071                 $LCTL set_param -n ldlm.dump_namespaces ""
3072                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3073                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3074                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3075                 return 2
3076         fi
3077         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3078                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3079                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3080                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3081                 return 3
3082         fi
3083 }
3084 run_test 29 "IT_GETATTR regression  ============================"
3085
3086 test_30a() { # was test_30
3087         cp $(which ls) $DIR || cp /bin/ls $DIR
3088         $DIR/ls / || error "Can't execute binary from lustre"
3089         rm $DIR/ls
3090 }
3091 run_test 30a "execute binary from Lustre (execve) =============="
3092
3093 test_30b() {
3094         cp `which ls` $DIR || cp /bin/ls $DIR
3095         chmod go+rx $DIR/ls
3096         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3097         rm $DIR/ls
3098 }
3099 run_test 30b "execute binary from Lustre as non-root ==========="
3100
3101 test_30c() { # b=22376
3102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3103
3104         cp $(which ls) $DIR || cp /bin/ls $DIR
3105         chmod a-rw $DIR/ls
3106         cancel_lru_locks mdc
3107         cancel_lru_locks osc
3108         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3109         rm -f $DIR/ls
3110 }
3111 run_test 30c "execute binary from Lustre without read perms ===="
3112
3113 test_30d() {
3114         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3115
3116         for i in {1..10}; do
3117                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3118                 local PID=$!
3119                 sleep 1
3120                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3121                 wait $PID || error "executing dd from Lustre failed"
3122                 rm -f $DIR/$tfile
3123         done
3124
3125         rm -f $DIR/dd
3126 }
3127 run_test 30d "execute binary from Lustre while clear locks"
3128
3129 test_31a() {
3130         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3131         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3132 }
3133 run_test 31a "open-unlink file =================================="
3134
3135 test_31b() {
3136         touch $DIR/f31 || error "touch $DIR/f31 failed"
3137         ln $DIR/f31 $DIR/f31b || error "ln failed"
3138         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3139         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3140 }
3141 run_test 31b "unlink file with multiple links while open ======="
3142
3143 test_31c() {
3144         touch $DIR/f31 || error "touch $DIR/f31 failed"
3145         ln $DIR/f31 $DIR/f31c || error "ln failed"
3146         multiop_bg_pause $DIR/f31 O_uc ||
3147                 error "multiop_bg_pause for $DIR/f31 failed"
3148         MULTIPID=$!
3149         $MULTIOP $DIR/f31c Ouc
3150         kill -USR1 $MULTIPID
3151         wait $MULTIPID
3152 }
3153 run_test 31c "open-unlink file with multiple links ============="
3154
3155 test_31d() {
3156         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3157         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3158 }
3159 run_test 31d "remove of open directory ========================="
3160
3161 test_31e() { # bug 2904
3162         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3163 }
3164 run_test 31e "remove of open non-empty directory ==============="
3165
3166 test_31f() { # bug 4554
3167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3168
3169         set -vx
3170         test_mkdir $DIR/d31f
3171         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3172         cp /etc/hosts $DIR/d31f
3173         ls -l $DIR/d31f
3174         $LFS getstripe $DIR/d31f/hosts
3175         multiop_bg_pause $DIR/d31f D_c || return 1
3176         MULTIPID=$!
3177
3178         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3179         test_mkdir $DIR/d31f
3180         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3181         cp /etc/hosts $DIR/d31f
3182         ls -l $DIR/d31f
3183         $LFS getstripe $DIR/d31f/hosts
3184         multiop_bg_pause $DIR/d31f D_c || return 1
3185         MULTIPID2=$!
3186
3187         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3188         wait $MULTIPID || error "first opendir $MULTIPID failed"
3189
3190         sleep 6
3191
3192         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3193         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3194         set +vx
3195 }
3196 run_test 31f "remove of open directory with open-unlink file ==="
3197
3198 test_31g() {
3199         echo "-- cross directory link --"
3200         test_mkdir -c1 $DIR/${tdir}ga
3201         test_mkdir -c1 $DIR/${tdir}gb
3202         touch $DIR/${tdir}ga/f
3203         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3204         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3205         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3206         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3207         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3208 }
3209 run_test 31g "cross directory link==============="
3210
3211 test_31h() {
3212         echo "-- cross directory link --"
3213         test_mkdir -c1 $DIR/${tdir}
3214         test_mkdir -c1 $DIR/${tdir}/dir
3215         touch $DIR/${tdir}/f
3216         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3217         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3218         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3219         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3220         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3221 }
3222 run_test 31h "cross directory link under child==============="
3223
3224 test_31i() {
3225         echo "-- cross directory link --"
3226         test_mkdir -c1 $DIR/$tdir
3227         test_mkdir -c1 $DIR/$tdir/dir
3228         touch $DIR/$tdir/dir/f
3229         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3230         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3231         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3232         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3233         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3234 }
3235 run_test 31i "cross directory link under parent==============="
3236
3237 test_31j() {
3238         test_mkdir -c1 -p $DIR/$tdir
3239         test_mkdir -c1 -p $DIR/$tdir/dir1
3240         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3241         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3242         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3243         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3244         return 0
3245 }
3246 run_test 31j "link for directory==============="
3247
3248 test_31k() {
3249         test_mkdir -c1 -p $DIR/$tdir
3250         touch $DIR/$tdir/s
3251         touch $DIR/$tdir/exist
3252         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3253         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3254         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3255         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3256         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3257         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3258         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3259         return 0
3260 }
3261 run_test 31k "link to file: the same, non-existing, dir==============="
3262
3263 test_31m() {
3264         mkdir $DIR/d31m
3265         touch $DIR/d31m/s
3266         mkdir $DIR/d31m2
3267         touch $DIR/d31m2/exist
3268         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3269         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3270         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3271         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3272         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3273         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3274         return 0
3275 }
3276 run_test 31m "link to file: the same, non-existing, dir==============="
3277
3278 test_31n() {
3279         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3280         nlink=$(stat --format=%h $DIR/$tfile)
3281         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3282         local fd=$(free_fd)
3283         local cmd="exec $fd<$DIR/$tfile"
3284         eval $cmd
3285         cmd="exec $fd<&-"
3286         trap "eval $cmd" EXIT
3287         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3288         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3289         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3290         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3291         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3292         eval $cmd
3293 }
3294 run_test 31n "check link count of unlinked file"
3295
3296 link_one() {
3297         local tempfile=$(mktemp $1_XXXXXX)
3298         mlink $tempfile $1 2> /dev/null &&
3299                 echo "$BASHPID: link $tempfile to $1 succeeded"
3300         munlink $tempfile
3301 }
3302
3303 test_31o() { # LU-2901
3304         test_mkdir $DIR/$tdir
3305         for LOOP in $(seq 100); do
3306                 rm -f $DIR/$tdir/$tfile*
3307                 for THREAD in $(seq 8); do
3308                         link_one $DIR/$tdir/$tfile.$LOOP &
3309                 done
3310                 wait
3311                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3312                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3313                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3314                         break || true
3315         done
3316 }
3317 run_test 31o "duplicate hard links with same filename"
3318
3319 test_31p() {
3320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3321
3322         test_mkdir $DIR/$tdir
3323         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3324         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3325
3326         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3327                 error "open unlink test1 failed"
3328         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3329                 error "open unlink test2 failed"
3330
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3332                 error "test1 still exists"
3333         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3334                 error "test2 still exists"
3335 }
3336 run_test 31p "remove of open striped directory"
3337
3338 cleanup_test32_mount() {
3339         local rc=0
3340         trap 0
3341         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3342         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3343         losetup -d $loopdev || true
3344         rm -rf $DIR/$tdir
3345         return $rc
3346 }
3347
3348 test_32a() {
3349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3350
3351         echo "== more mountpoints and symlinks ================="
3352         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3353         trap cleanup_test32_mount EXIT
3354         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3355         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3356                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3357         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3358                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3359         cleanup_test32_mount
3360 }
3361 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3362
3363 test_32b() {
3364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3365
3366         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3367         trap cleanup_test32_mount EXIT
3368         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3369         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3370                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3371         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3372                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3373         cleanup_test32_mount
3374 }
3375 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3376
3377 test_32c() {
3378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3379
3380         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3381         trap cleanup_test32_mount EXIT
3382         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3383         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3384                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3385         test_mkdir -p $DIR/$tdir/d2/test_dir
3386         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3387                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3388         cleanup_test32_mount
3389 }
3390 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3391
3392 test_32d() {
3393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3394
3395         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3396         trap cleanup_test32_mount EXIT
3397         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3398         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3399                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3400         test_mkdir -p $DIR/$tdir/d2/test_dir
3401         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3402                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3403         cleanup_test32_mount
3404 }
3405 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3406
3407 test_32e() {
3408         rm -fr $DIR/$tdir
3409         test_mkdir -p $DIR/$tdir/tmp
3410         local tmp_dir=$DIR/$tdir/tmp
3411         ln -s $DIR/$tdir $tmp_dir/symlink11
3412         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3413         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3414         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3415 }
3416 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3417
3418 test_32f() {
3419         rm -fr $DIR/$tdir
3420         test_mkdir -p $DIR/$tdir/tmp
3421         local tmp_dir=$DIR/$tdir/tmp
3422         ln -s $DIR/$tdir $tmp_dir/symlink11
3423         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3424         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3425         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3426 }
3427 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3428
3429 test_32g() {
3430         local tmp_dir=$DIR/$tdir/tmp
3431         test_mkdir -p $tmp_dir
3432         test_mkdir $DIR/${tdir}2
3433         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3434         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3435         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3436         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3437         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3438         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3439 }
3440 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3441
3442 test_32h() {
3443         rm -fr $DIR/$tdir $DIR/${tdir}2
3444         tmp_dir=$DIR/$tdir/tmp
3445         test_mkdir -p $tmp_dir
3446         test_mkdir $DIR/${tdir}2
3447         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3448         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3449         ls $tmp_dir/symlink12 || error "listing symlink12"
3450         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3451 }
3452 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3453
3454 test_32i() {
3455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3456
3457         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3458         trap cleanup_test32_mount EXIT
3459         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3460         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3461                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3462         touch $DIR/$tdir/test_file
3463         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3464                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3465         cleanup_test32_mount
3466 }
3467 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3468
3469 test_32j() {
3470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3471
3472         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3473         trap cleanup_test32_mount EXIT
3474         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3475         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3476                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3477         touch $DIR/$tdir/test_file
3478         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3479                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3480         cleanup_test32_mount
3481 }
3482 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3483
3484 test_32k() {
3485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3486
3487         rm -fr $DIR/$tdir
3488         trap cleanup_test32_mount EXIT
3489         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3490         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3491                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3492         test_mkdir -p $DIR/$tdir/d2
3493         touch $DIR/$tdir/d2/test_file || error "touch failed"
3494         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3495                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3496         cleanup_test32_mount
3497 }
3498 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3499
3500 test_32l() {
3501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3502
3503         rm -fr $DIR/$tdir
3504         trap cleanup_test32_mount EXIT
3505         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3506         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3507                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3508         test_mkdir -p $DIR/$tdir/d2
3509         touch $DIR/$tdir/d2/test_file || error "touch failed"
3510         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3511                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3512         cleanup_test32_mount
3513 }
3514 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3515
3516 test_32m() {
3517         rm -fr $DIR/d32m
3518         test_mkdir -p $DIR/d32m/tmp
3519         TMP_DIR=$DIR/d32m/tmp
3520         ln -s $DIR $TMP_DIR/symlink11
3521         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3522         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3523                 error "symlink11 not a link"
3524         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3525                 error "symlink01 not a link"
3526 }
3527 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3528
3529 test_32n() {
3530         rm -fr $DIR/d32n
3531         test_mkdir -p $DIR/d32n/tmp
3532         TMP_DIR=$DIR/d32n/tmp
3533         ln -s $DIR $TMP_DIR/symlink11
3534         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3535         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3536         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3537 }
3538 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3539
3540 test_32o() {
3541         touch $DIR/$tfile
3542         test_mkdir -p $DIR/d32o/tmp
3543         TMP_DIR=$DIR/d32o/tmp
3544         ln -s $DIR/$tfile $TMP_DIR/symlink12
3545         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3546         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3547                 error "symlink12 not a link"
3548         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3549         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3550                 error "$DIR/d32o/tmp/symlink12 not file type"
3551         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3552                 error "$DIR/d32o/symlink02 not file type"
3553 }
3554 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3555
3556 test_32p() {
3557         log 32p_1
3558         rm -fr $DIR/d32p
3559         log 32p_2
3560         rm -f $DIR/$tfile
3561         log 32p_3
3562         touch $DIR/$tfile
3563         log 32p_4
3564         test_mkdir -p $DIR/d32p/tmp
3565         log 32p_5
3566         TMP_DIR=$DIR/d32p/tmp
3567         log 32p_6
3568         ln -s $DIR/$tfile $TMP_DIR/symlink12
3569         log 32p_7
3570         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3571         log 32p_8
3572         cat $DIR/d32p/tmp/symlink12 ||
3573                 error "Can't open $DIR/d32p/tmp/symlink12"
3574         log 32p_9
3575         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3576         log 32p_10
3577 }
3578 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3579
3580 test_32q() {
3581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3582
3583         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3584         trap cleanup_test32_mount EXIT
3585         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3586         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3587         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3588                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3589         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3590         cleanup_test32_mount
3591 }
3592 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3593
3594 test_32r() {
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3598         trap cleanup_test32_mount EXIT
3599         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3600         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3601         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3602                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3603         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3604         cleanup_test32_mount
3605 }
3606 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3607
3608 test_33aa() {
3609         rm -f $DIR/$tfile
3610         touch $DIR/$tfile
3611         chmod 444 $DIR/$tfile
3612         chown $RUNAS_ID $DIR/$tfile
3613         log 33_1
3614         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3615         log 33_2
3616 }
3617 run_test 33aa "write file with mode 444 (should return error)"
3618
3619 test_33a() {
3620         rm -fr $DIR/$tdir
3621         test_mkdir $DIR/$tdir
3622         chown $RUNAS_ID $DIR/$tdir
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3624                 error "$RUNAS create $tdir/$tfile failed"
3625         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3626                 error "open RDWR" || true
3627 }
3628 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3629
3630 test_33b() {
3631         rm -fr $DIR/$tdir
3632         test_mkdir $DIR/$tdir
3633         chown $RUNAS_ID $DIR/$tdir
3634         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3635 }
3636 run_test 33b "test open file with malformed flags (No panic)"
3637
3638 test_33c() {
3639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3640         remote_ost_nodsh && skip "remote OST with nodsh"
3641
3642         local ostnum
3643         local ostname
3644         local write_bytes
3645         local all_zeros
3646
3647         all_zeros=:
3648         rm -fr $DIR/$tdir
3649         test_mkdir $DIR/$tdir
3650         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3651
3652         sync
3653         for ostnum in $(seq $OSTCOUNT); do
3654                 # test-framework's OST numbering is one-based, while Lustre's
3655                 # is zero-based
3656                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3657                 # Parsing llobdstat's output sucks; we could grep the /proc
3658                 # path, but that's likely to not be as portable as using the
3659                 # llobdstat utility.  So we parse lctl output instead.
3660                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3661                         obdfilter/$ostname/stats |
3662                         awk '/^write_bytes/ {print $7}' )
3663                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3664                 if (( ${write_bytes:-0} > 0 ))
3665                 then
3666                         all_zeros=false
3667                         break;
3668                 fi
3669         done
3670
3671         $all_zeros || return 0
3672
3673         # Write four bytes
3674         echo foo > $DIR/$tdir/bar
3675         # Really write them
3676         sync
3677
3678         # Total up write_bytes after writing.  We'd better find non-zeros.
3679         for ostnum in $(seq $OSTCOUNT); do
3680                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3681                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3682                         obdfilter/$ostname/stats |
3683                         awk '/^write_bytes/ {print $7}' )
3684                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3685                 if (( ${write_bytes:-0} > 0 ))
3686                 then
3687                         all_zeros=false
3688                         break;
3689                 fi
3690         done
3691
3692         if $all_zeros
3693         then
3694                 for ostnum in $(seq $OSTCOUNT); do
3695                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3696                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3697                         do_facet ost$ostnum lctl get_param -n \
3698                                 obdfilter/$ostname/stats
3699                 done
3700                 error "OST not keeping write_bytes stats (b22312)"
3701         fi
3702 }
3703 run_test 33c "test llobdstat and write_bytes"
3704
3705 test_33d() {
3706         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3708
3709         local MDTIDX=1
3710         local remote_dir=$DIR/$tdir/remote_dir
3711
3712         test_mkdir $DIR/$tdir
3713         $LFS mkdir -i $MDTIDX $remote_dir ||
3714                 error "create remote directory failed"
3715
3716         touch $remote_dir/$tfile
3717         chmod 444 $remote_dir/$tfile
3718         chown $RUNAS_ID $remote_dir/$tfile
3719
3720         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3721
3722         chown $RUNAS_ID $remote_dir
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3724                                         error "create" || true
3725         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3726                                     error "open RDWR" || true
3727         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3728 }
3729 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3730
3731 test_33e() {
3732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3733
3734         mkdir $DIR/$tdir
3735
3736         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3737         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3738         mkdir $DIR/$tdir/local_dir
3739
3740         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3741         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3742         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3743
3744         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3745                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3746
3747         rmdir $DIR/$tdir/* || error "rmdir failed"
3748
3749         umask 777
3750         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3751         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3752         mkdir $DIR/$tdir/local_dir
3753
3754         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3755         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3756         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3757
3758         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3759                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3760
3761         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3762
3763         umask 000
3764         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3765         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3766         mkdir $DIR/$tdir/local_dir
3767
3768         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3769         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3770         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3771
3772         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3773                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3774 }
3775 run_test 33e "mkdir and striped directory should have same mode"
3776
3777 cleanup_33f() {
3778         trap 0
3779         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3780 }
3781
3782 test_33f() {
3783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3784         remote_mds_nodsh && skip "remote MDS with nodsh"
3785
3786         mkdir $DIR/$tdir
3787         chmod go+rwx $DIR/$tdir
3788         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3789         trap cleanup_33f EXIT
3790
3791         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3792                 error "cannot create striped directory"
3793
3794         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3795                 error "cannot create files in striped directory"
3796
3797         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3798                 error "cannot remove files in striped directory"
3799
3800         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3801                 error "cannot remove striped directory"
3802
3803         cleanup_33f
3804 }
3805 run_test 33f "nonroot user can create, access, and remove a striped directory"
3806
3807 test_33g() {
3808         mkdir -p $DIR/$tdir/dir2
3809
3810         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3811         echo $err
3812         [[ $err =~ "exists" ]] || error "Not exists error"
3813 }
3814 run_test 33g "nonroot user create already existing root created file"
3815
3816 test_33h() {
3817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3818         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3819                 skip "Need MDS version at least 2.13.50"
3820
3821         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3822                 error "mkdir $tdir failed"
3823         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3824
3825         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3826         local index2
3827
3828         for fname in $DIR/$tdir/$tfile.bak \
3829                      $DIR/$tdir/$tfile.SAV \
3830                      $DIR/$tdir/$tfile.orig \
3831                      $DIR/$tdir/$tfile~; do
3832                 touch $fname  || error "touch $fname failed"
3833                 index2=$($LFS getstripe -m $fname)
3834                 [ $index -eq $index2 ] ||
3835                         error "$fname MDT index mismatch $index != $index2"
3836         done
3837
3838         local failed=0
3839         for i in {1..250}; do
3840                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3841                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3842                         touch $fname  || error "touch $fname failed"
3843                         index2=$($LFS getstripe -m $fname)
3844                         if [[ $index != $index2 ]]; then
3845                                 failed=$((failed + 1))
3846                                 echo "$fname MDT index mismatch $index != $index2"
3847                         fi
3848                 done
3849         done
3850         echo "$failed MDT index mismatches"
3851         (( failed < 20 )) || error "MDT index mismatch $failed times"
3852
3853 }
3854 run_test 33h "temp file is located on the same MDT as target"
3855
3856 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3857 test_34a() {
3858         rm -f $DIR/f34
3859         $MCREATE $DIR/f34 || error "mcreate failed"
3860         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3861                 error "getstripe failed"
3862         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3863         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3864                 error "getstripe failed"
3865         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3866                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3867 }
3868 run_test 34a "truncate file that has not been opened ==========="
3869
3870 test_34b() {
3871         [ ! -f $DIR/f34 ] && test_34a
3872         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3873                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3874         $OPENFILE -f O_RDONLY $DIR/f34
3875         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3876                 error "getstripe failed"
3877         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3878                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3879 }
3880 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3881
3882 test_34c() {
3883         [ ! -f $DIR/f34 ] && test_34a
3884         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3885                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3886         $OPENFILE -f O_RDWR $DIR/f34
3887         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3888                 error "$LFS getstripe failed"
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891 }
3892 run_test 34c "O_RDWR opening file-with-size works =============="
3893
3894 test_34d() {
3895         [ ! -f $DIR/f34 ] && test_34a
3896         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3897                 error "dd failed"
3898         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3899                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3900         rm $DIR/f34
3901 }
3902 run_test 34d "write to sparse file ============================="
3903
3904 test_34e() {
3905         rm -f $DIR/f34e
3906         $MCREATE $DIR/f34e || error "mcreate failed"
3907         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3908         $CHECKSTAT -s 1000 $DIR/f34e ||
3909                 error "Size of $DIR/f34e not equal to 1000 bytes"
3910         $OPENFILE -f O_RDWR $DIR/f34e
3911         $CHECKSTAT -s 1000 $DIR/f34e ||
3912                 error "Size of $DIR/f34e not equal to 1000 bytes"
3913 }
3914 run_test 34e "create objects, some with size and some without =="
3915
3916 test_34f() { # bug 6242, 6243
3917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3918
3919         SIZE34F=48000
3920         rm -f $DIR/f34f
3921         $MCREATE $DIR/f34f || error "mcreate failed"
3922         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3923         dd if=$DIR/f34f of=$TMP/f34f
3924         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3925         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3926         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3927         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3928         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3929 }
3930 run_test 34f "read from a file with no objects until EOF ======="
3931
3932 test_34g() {
3933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3934
3935         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3936                 error "dd failed"
3937         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3938         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3939                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3940         cancel_lru_locks osc
3941         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3942                 error "wrong size after lock cancel"
3943
3944         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3945         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3946                 error "expanding truncate failed"
3947         cancel_lru_locks osc
3948         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3949                 error "wrong expanded size after lock cancel"
3950 }
3951 run_test 34g "truncate long file ==============================="
3952
3953 test_34h() {
3954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3955
3956         local gid=10
3957         local sz=1000
3958
3959         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3960         sync # Flush the cache so that multiop below does not block on cache
3961              # flush when getting the group lock
3962         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3963         MULTIPID=$!
3964
3965         # Since just timed wait is not good enough, let's do a sync write
3966         # that way we are sure enough time for a roundtrip + processing
3967         # passed + 2 seconds of extra margin.
3968         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3969         rm $DIR/${tfile}-1
3970         sleep 2
3971
3972         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3973                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3974                 kill -9 $MULTIPID
3975         fi
3976         wait $MULTIPID
3977         local nsz=`stat -c %s $DIR/$tfile`
3978         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3979 }
3980 run_test 34h "ftruncate file under grouplock should not block"
3981
3982 test_35a() {
3983         cp /bin/sh $DIR/f35a
3984         chmod 444 $DIR/f35a
3985         chown $RUNAS_ID $DIR/f35a
3986         $RUNAS $DIR/f35a && error || true
3987         rm $DIR/f35a
3988 }
3989 run_test 35a "exec file with mode 444 (should return and not leak)"
3990
3991 test_36a() {
3992         rm -f $DIR/f36
3993         utime $DIR/f36 || error "utime failed for MDS"
3994 }
3995 run_test 36a "MDS utime check (mknod, utime)"
3996
3997 test_36b() {
3998         echo "" > $DIR/f36
3999         utime $DIR/f36 || error "utime failed for OST"
4000 }
4001 run_test 36b "OST utime check (open, utime)"
4002
4003 test_36c() {
4004         rm -f $DIR/d36/f36
4005         test_mkdir $DIR/d36
4006         chown $RUNAS_ID $DIR/d36
4007         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4008 }
4009 run_test 36c "non-root MDS utime check (mknod, utime)"
4010
4011 test_36d() {
4012         [ ! -d $DIR/d36 ] && test_36c
4013         echo "" > $DIR/d36/f36
4014         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4015 }
4016 run_test 36d "non-root OST utime check (open, utime)"
4017
4018 test_36e() {
4019         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4020
4021         test_mkdir $DIR/$tdir
4022         touch $DIR/$tdir/$tfile
4023         $RUNAS utime $DIR/$tdir/$tfile &&
4024                 error "utime worked, expected failure" || true
4025 }
4026 run_test 36e "utime on non-owned file (should return error)"
4027
4028 subr_36fh() {
4029         local fl="$1"
4030         local LANG_SAVE=$LANG
4031         local LC_LANG_SAVE=$LC_LANG
4032         export LANG=C LC_LANG=C # for date language
4033
4034         DATESTR="Dec 20  2000"
4035         test_mkdir $DIR/$tdir
4036         lctl set_param fail_loc=$fl
4037         date; date +%s
4038         cp /etc/hosts $DIR/$tdir/$tfile
4039         sync & # write RPC generated with "current" inode timestamp, but delayed
4040         sleep 1
4041         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4042         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4043         cancel_lru_locks $OSC
4044         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4045         date; date +%s
4046         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4047                 echo "BEFORE: $LS_BEFORE" && \
4048                 echo "AFTER : $LS_AFTER" && \
4049                 echo "WANT  : $DATESTR" && \
4050                 error "$DIR/$tdir/$tfile timestamps changed" || true
4051
4052         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4053 }
4054
4055 test_36f() {
4056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4057
4058         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4059         subr_36fh "0x80000214"
4060 }
4061 run_test 36f "utime on file racing with OST BRW write =========="
4062
4063 test_36g() {
4064         remote_ost_nodsh && skip "remote OST with nodsh"
4065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4066         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4067                 skip "Need MDS version at least 2.12.51"
4068
4069         local fmd_max_age
4070         local fmd
4071         local facet="ost1"
4072         local tgt="obdfilter"
4073
4074         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4075
4076         test_mkdir $DIR/$tdir
4077         fmd_max_age=$(do_facet $facet \
4078                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4079                 head -n 1")
4080
4081         echo "FMD max age: ${fmd_max_age}s"
4082         touch $DIR/$tdir/$tfile
4083         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4084                 gawk '{cnt=cnt+$1}  END{print cnt}')
4085         echo "FMD before: $fmd"
4086         [[ $fmd == 0 ]] &&
4087                 error "FMD wasn't create by touch"
4088         sleep $((fmd_max_age + 12))
4089         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4090                 gawk '{cnt=cnt+$1}  END{print cnt}')
4091         echo "FMD after: $fmd"
4092         [[ $fmd == 0 ]] ||
4093                 error "FMD wasn't expired by ping"
4094 }
4095 run_test 36g "FMD cache expiry ====================="
4096
4097 test_36h() {
4098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4099
4100         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4101         subr_36fh "0x80000227"
4102 }
4103 run_test 36h "utime on file racing with OST BRW write =========="
4104
4105 test_36i() {
4106         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4107
4108         test_mkdir $DIR/$tdir
4109         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4110
4111         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4112         local new_mtime=$((mtime + 200))
4113
4114         #change Modify time of striped dir
4115         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4116                         error "change mtime failed"
4117
4118         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4119
4120         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4121 }
4122 run_test 36i "change mtime on striped directory"
4123
4124 # test_37 - duplicate with tests 32q 32r
4125
4126 test_38() {
4127         local file=$DIR/$tfile
4128         touch $file
4129         openfile -f O_DIRECTORY $file
4130         local RC=$?
4131         local ENOTDIR=20
4132         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4133         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4134 }
4135 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4136
4137 test_39a() { # was test_39
4138         touch $DIR/$tfile
4139         touch $DIR/${tfile}2
4140 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4141 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4142 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4143         sleep 2
4144         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4145         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4146                 echo "mtime"
4147                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "atime"
4149                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4150                 echo "ctime"
4151                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4152                 error "O_TRUNC didn't change timestamps"
4153         fi
4154 }
4155 run_test 39a "mtime changed on create"
4156
4157 test_39b() {
4158         test_mkdir -c1 $DIR/$tdir
4159         cp -p /etc/passwd $DIR/$tdir/fopen
4160         cp -p /etc/passwd $DIR/$tdir/flink
4161         cp -p /etc/passwd $DIR/$tdir/funlink
4162         cp -p /etc/passwd $DIR/$tdir/frename
4163         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4164
4165         sleep 1
4166         echo "aaaaaa" >> $DIR/$tdir/fopen
4167         echo "aaaaaa" >> $DIR/$tdir/flink
4168         echo "aaaaaa" >> $DIR/$tdir/funlink
4169         echo "aaaaaa" >> $DIR/$tdir/frename
4170
4171         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4172         local link_new=`stat -c %Y $DIR/$tdir/flink`
4173         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4174         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4175
4176         cat $DIR/$tdir/fopen > /dev/null
4177         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4178         rm -f $DIR/$tdir/funlink2
4179         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4180
4181         for (( i=0; i < 2; i++ )) ; do
4182                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4183                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4184                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4185                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4186
4187                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4188                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4189                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4190                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4191
4192                 cancel_lru_locks $OSC
4193                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4194         done
4195 }
4196 run_test 39b "mtime change on open, link, unlink, rename  ======"
4197
4198 # this should be set to past
4199 TEST_39_MTIME=`date -d "1 year ago" +%s`
4200
4201 # bug 11063
4202 test_39c() {
4203         touch $DIR1/$tfile
4204         sleep 2
4205         local mtime0=`stat -c %Y $DIR1/$tfile`
4206
4207         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4208         local mtime1=`stat -c %Y $DIR1/$tfile`
4209         [ "$mtime1" = $TEST_39_MTIME ] || \
4210                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4211
4212         local d1=`date +%s`
4213         echo hello >> $DIR1/$tfile
4214         local d2=`date +%s`
4215         local mtime2=`stat -c %Y $DIR1/$tfile`
4216         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4217                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4218
4219         mv $DIR1/$tfile $DIR1/$tfile-1
4220
4221         for (( i=0; i < 2; i++ )) ; do
4222                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4223                 [ "$mtime2" = "$mtime3" ] || \
4224                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4225
4226                 cancel_lru_locks $OSC
4227                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4228         done
4229 }
4230 run_test 39c "mtime change on rename ==========================="
4231
4232 # bug 21114
4233 test_39d() {
4234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4235
4236         touch $DIR1/$tfile
4237         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4238
4239         for (( i=0; i < 2; i++ )) ; do
4240                 local mtime=`stat -c %Y $DIR1/$tfile`
4241                 [ $mtime = $TEST_39_MTIME ] || \
4242                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4243
4244                 cancel_lru_locks $OSC
4245                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4246         done
4247 }
4248 run_test 39d "create, utime, stat =============================="
4249
4250 # bug 21114
4251 test_39e() {
4252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4253
4254         touch $DIR1/$tfile
4255         local mtime1=`stat -c %Y $DIR1/$tfile`
4256
4257         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4258
4259         for (( i=0; i < 2; i++ )) ; do
4260                 local mtime2=`stat -c %Y $DIR1/$tfile`
4261                 [ $mtime2 = $TEST_39_MTIME ] || \
4262                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4263
4264                 cancel_lru_locks $OSC
4265                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4266         done
4267 }
4268 run_test 39e "create, stat, utime, stat ========================"
4269
4270 # bug 21114
4271 test_39f() {
4272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4273
4274         touch $DIR1/$tfile
4275         mtime1=`stat -c %Y $DIR1/$tfile`
4276
4277         sleep 2
4278         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4279
4280         for (( i=0; i < 2; i++ )) ; do
4281                 local mtime2=`stat -c %Y $DIR1/$tfile`
4282                 [ $mtime2 = $TEST_39_MTIME ] || \
4283                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4284
4285                 cancel_lru_locks $OSC
4286                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4287         done
4288 }
4289 run_test 39f "create, stat, sleep, utime, stat ================="
4290
4291 # bug 11063
4292 test_39g() {
4293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4294
4295         echo hello >> $DIR1/$tfile
4296         local mtime1=`stat -c %Y $DIR1/$tfile`
4297
4298         sleep 2
4299         chmod o+r $DIR1/$tfile
4300
4301         for (( i=0; i < 2; i++ )) ; do
4302                 local mtime2=`stat -c %Y $DIR1/$tfile`
4303                 [ "$mtime1" = "$mtime2" ] || \
4304                         error "lost mtime: $mtime2, should be $mtime1"
4305
4306                 cancel_lru_locks $OSC
4307                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4308         done
4309 }
4310 run_test 39g "write, chmod, stat ==============================="
4311
4312 # bug 11063
4313 test_39h() {
4314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4315
4316         touch $DIR1/$tfile
4317         sleep 1
4318
4319         local d1=`date`
4320         echo hello >> $DIR1/$tfile
4321         local mtime1=`stat -c %Y $DIR1/$tfile`
4322
4323         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4324         local d2=`date`
4325         if [ "$d1" != "$d2" ]; then
4326                 echo "write and touch not within one second"
4327         else
4328                 for (( i=0; i < 2; i++ )) ; do
4329                         local mtime2=`stat -c %Y $DIR1/$tfile`
4330                         [ "$mtime2" = $TEST_39_MTIME ] || \
4331                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4332
4333                         cancel_lru_locks $OSC
4334                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4335                 done
4336         fi
4337 }
4338 run_test 39h "write, utime within one second, stat ============="
4339
4340 test_39i() {
4341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4342
4343         touch $DIR1/$tfile
4344         sleep 1
4345
4346         echo hello >> $DIR1/$tfile
4347         local mtime1=`stat -c %Y $DIR1/$tfile`
4348
4349         mv $DIR1/$tfile $DIR1/$tfile-1
4350
4351         for (( i=0; i < 2; i++ )) ; do
4352                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4353
4354                 [ "$mtime1" = "$mtime2" ] || \
4355                         error "lost mtime: $mtime2, should be $mtime1"
4356
4357                 cancel_lru_locks $OSC
4358                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4359         done
4360 }
4361 run_test 39i "write, rename, stat =============================="
4362
4363 test_39j() {
4364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4365
4366         start_full_debug_logging
4367         touch $DIR1/$tfile
4368         sleep 1
4369
4370         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4371         lctl set_param fail_loc=0x80000412
4372         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4373                 error "multiop failed"
4374         local multipid=$!
4375         local mtime1=`stat -c %Y $DIR1/$tfile`
4376
4377         mv $DIR1/$tfile $DIR1/$tfile-1
4378
4379         kill -USR1 $multipid
4380         wait $multipid || error "multiop close failed"
4381
4382         for (( i=0; i < 2; i++ )) ; do
4383                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4384                 [ "$mtime1" = "$mtime2" ] ||
4385                         error "mtime is lost on close: $mtime2, " \
4386                               "should be $mtime1"
4387
4388                 cancel_lru_locks
4389                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4390         done
4391         lctl set_param fail_loc=0
4392         stop_full_debug_logging
4393 }
4394 run_test 39j "write, rename, close, stat ======================="
4395
4396 test_39k() {
4397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4398
4399         touch $DIR1/$tfile
4400         sleep 1
4401
4402         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4403         local multipid=$!
4404         local mtime1=`stat -c %Y $DIR1/$tfile`
4405
4406         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4407
4408         kill -USR1 $multipid
4409         wait $multipid || error "multiop close failed"
4410
4411         for (( i=0; i < 2; i++ )) ; do
4412                 local mtime2=`stat -c %Y $DIR1/$tfile`
4413
4414                 [ "$mtime2" = $TEST_39_MTIME ] || \
4415                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4416
4417                 cancel_lru_locks
4418                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4419         done
4420 }
4421 run_test 39k "write, utime, close, stat ========================"
4422
4423 # this should be set to future
4424 TEST_39_ATIME=`date -d "1 year" +%s`
4425
4426 test_39l() {
4427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4428         remote_mds_nodsh && skip "remote MDS with nodsh"
4429
4430         local atime_diff=$(do_facet $SINGLEMDS \
4431                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4432         rm -rf $DIR/$tdir
4433         mkdir -p $DIR/$tdir
4434
4435         # test setting directory atime to future
4436         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4437         local atime=$(stat -c %X $DIR/$tdir)
4438         [ "$atime" = $TEST_39_ATIME ] ||
4439                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4440
4441         # test setting directory atime from future to now
4442         local now=$(date +%s)
4443         touch -a -d @$now $DIR/$tdir
4444
4445         atime=$(stat -c %X $DIR/$tdir)
4446         [ "$atime" -eq "$now"  ] ||
4447                 error "atime is not updated from future: $atime, $now"
4448
4449         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4450         sleep 3
4451
4452         # test setting directory atime when now > dir atime + atime_diff
4453         local d1=$(date +%s)
4454         ls $DIR/$tdir
4455         local d2=$(date +%s)
4456         cancel_lru_locks mdc
4457         atime=$(stat -c %X $DIR/$tdir)
4458         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4459                 error "atime is not updated  : $atime, should be $d2"
4460
4461         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4462         sleep 3
4463
4464         # test not setting directory atime when now < dir atime + atime_diff
4465         ls $DIR/$tdir
4466         cancel_lru_locks mdc
4467         atime=$(stat -c %X $DIR/$tdir)
4468         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4469                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4470
4471         do_facet $SINGLEMDS \
4472                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4473 }
4474 run_test 39l "directory atime update ==========================="
4475
4476 test_39m() {
4477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4478
4479         touch $DIR1/$tfile
4480         sleep 2
4481         local far_past_mtime=$(date -d "May 29 1953" +%s)
4482         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4483
4484         touch -m -d @$far_past_mtime $DIR1/$tfile
4485         touch -a -d @$far_past_atime $DIR1/$tfile
4486
4487         for (( i=0; i < 2; i++ )) ; do
4488                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4489                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4490                         error "atime or mtime set incorrectly"
4491
4492                 cancel_lru_locks $OSC
4493                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4494         done
4495 }
4496 run_test 39m "test atime and mtime before 1970"
4497
4498 test_39n() { # LU-3832
4499         remote_mds_nodsh && skip "remote MDS with nodsh"
4500
4501         local atime_diff=$(do_facet $SINGLEMDS \
4502                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4503         local atime0
4504         local atime1
4505         local atime2
4506
4507         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4508
4509         rm -rf $DIR/$tfile
4510         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4511         atime0=$(stat -c %X $DIR/$tfile)
4512
4513         sleep 5
4514         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4515         atime1=$(stat -c %X $DIR/$tfile)
4516
4517         sleep 5
4518         cancel_lru_locks mdc
4519         cancel_lru_locks osc
4520         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4521         atime2=$(stat -c %X $DIR/$tfile)
4522
4523         do_facet $SINGLEMDS \
4524                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4525
4526         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4527         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4528 }
4529 run_test 39n "check that O_NOATIME is honored"
4530
4531 test_39o() {
4532         TESTDIR=$DIR/$tdir/$tfile
4533         [ -e $TESTDIR ] && rm -rf $TESTDIR
4534         mkdir -p $TESTDIR
4535         cd $TESTDIR
4536         links1=2
4537         ls
4538         mkdir a b
4539         ls
4540         links2=$(stat -c %h .)
4541         [ $(($links1 + 2)) != $links2 ] &&
4542                 error "wrong links count $(($links1 + 2)) != $links2"
4543         rmdir b
4544         links3=$(stat -c %h .)
4545         [ $(($links1 + 1)) != $links3 ] &&
4546                 error "wrong links count $links1 != $links3"
4547         return 0
4548 }
4549 run_test 39o "directory cached attributes updated after create"
4550
4551 test_39p() {
4552         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4553
4554         local MDTIDX=1
4555         TESTDIR=$DIR/$tdir/$tdir
4556         [ -e $TESTDIR ] && rm -rf $TESTDIR
4557         test_mkdir -p $TESTDIR
4558         cd $TESTDIR
4559         links1=2
4560         ls
4561         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4562         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4563         ls
4564         links2=$(stat -c %h .)
4565         [ $(($links1 + 2)) != $links2 ] &&
4566                 error "wrong links count $(($links1 + 2)) != $links2"
4567         rmdir remote_dir2
4568         links3=$(stat -c %h .)
4569         [ $(($links1 + 1)) != $links3 ] &&
4570                 error "wrong links count $links1 != $links3"
4571         return 0
4572 }
4573 run_test 39p "remote directory cached attributes updated after create ========"
4574
4575 test_39r() {
4576         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4577                 skip "no atime update on old OST"
4578         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4579                 skip_env "ldiskfs only test"
4580         fi
4581
4582         local saved_adiff
4583         saved_adiff=$(do_facet ost1 \
4584                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4585         stack_trap "do_facet ost1 \
4586                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4587
4588         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4589
4590         $LFS setstripe -i 0 $DIR/$tfile
4591         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4592                 error "can't write initial file"
4593         cancel_lru_locks osc
4594
4595         # exceed atime_diff and access file
4596         sleep 6
4597         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4598
4599         local atime_cli=$(stat -c %X $DIR/$tfile)
4600         echo "client atime: $atime_cli"
4601         # allow atime update to be written to device
4602         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4603         sleep 5
4604
4605         local ostdev=$(ostdevname 1)
4606         local fid=($(lfs getstripe -y $DIR/$tfile |
4607                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4608         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4609         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4610
4611         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4612         local atime_ost=$(do_facet ost1 "$cmd" |&
4613                           awk -F'[: ]' '/atime:/ { print $4 }')
4614         (( atime_cli == atime_ost )) ||
4615                 error "atime on client $atime_cli != ost $atime_ost"
4616 }
4617 run_test 39r "lazy atime update on OST"
4618
4619 test_39q() { # LU-8041
4620         local testdir=$DIR/$tdir
4621         mkdir -p $testdir
4622         multiop_bg_pause $testdir D_c || error "multiop failed"
4623         local multipid=$!
4624         cancel_lru_locks mdc
4625         kill -USR1 $multipid
4626         local atime=$(stat -c %X $testdir)
4627         [ "$atime" -ne 0 ] || error "atime is zero"
4628 }
4629 run_test 39q "close won't zero out atime"
4630
4631 test_40() {
4632         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4633         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4634                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4635         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4636                 error "$tfile is not 4096 bytes in size"
4637 }
4638 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4639
4640 test_41() {
4641         # bug 1553
4642         small_write $DIR/f41 18
4643 }
4644 run_test 41 "test small file write + fstat ====================="
4645
4646 count_ost_writes() {
4647         lctl get_param -n ${OSC}.*.stats |
4648                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4649                         END { printf("%0.0f", writes) }'
4650 }
4651
4652 # decent default
4653 WRITEBACK_SAVE=500
4654 DIRTY_RATIO_SAVE=40
4655 MAX_DIRTY_RATIO=50
4656 BG_DIRTY_RATIO_SAVE=10
4657 MAX_BG_DIRTY_RATIO=25
4658
4659 start_writeback() {
4660         trap 0
4661         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4662         # dirty_ratio, dirty_background_ratio
4663         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4664                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4665                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4666                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4667         else
4668                 # if file not here, we are a 2.4 kernel
4669                 kill -CONT `pidof kupdated`
4670         fi
4671 }
4672
4673 stop_writeback() {
4674         # setup the trap first, so someone cannot exit the test at the
4675         # exact wrong time and mess up a machine
4676         trap start_writeback EXIT
4677         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4678         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4679                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4680                 sysctl -w vm.dirty_writeback_centisecs=0
4681                 sysctl -w vm.dirty_writeback_centisecs=0
4682                 # save and increase /proc/sys/vm/dirty_ratio
4683                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4684                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4685                 # save and increase /proc/sys/vm/dirty_background_ratio
4686                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4687                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4688         else
4689                 # if file not here, we are a 2.4 kernel
4690                 kill -STOP `pidof kupdated`
4691         fi
4692 }
4693
4694 # ensure that all stripes have some grant before we test client-side cache
4695 setup_test42() {
4696         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4697                 dd if=/dev/zero of=$i bs=4k count=1
4698                 rm $i
4699         done
4700 }
4701
4702 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4703 # file truncation, and file removal.
4704 test_42a() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         setup_test42
4708         cancel_lru_locks $OSC
4709         stop_writeback
4710         sync; sleep 1; sync # just to be safe
4711         BEFOREWRITES=`count_ost_writes`
4712         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4713         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4714         AFTERWRITES=`count_ost_writes`
4715         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4716                 error "$BEFOREWRITES < $AFTERWRITES"
4717         start_writeback
4718 }
4719 run_test 42a "ensure that we don't flush on close"
4720
4721 test_42b() {
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723
4724         setup_test42
4725         cancel_lru_locks $OSC
4726         stop_writeback
4727         sync
4728         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4729         BEFOREWRITES=$(count_ost_writes)
4730         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4731         AFTERWRITES=$(count_ost_writes)
4732         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4733                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4734         fi
4735         BEFOREWRITES=$(count_ost_writes)
4736         sync || error "sync: $?"
4737         AFTERWRITES=$(count_ost_writes)
4738         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4739                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4740         fi
4741         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4742         start_writeback
4743         return 0
4744 }
4745 run_test 42b "test destroy of file with cached dirty data ======"
4746
4747 # if these tests just want to test the effect of truncation,
4748 # they have to be very careful.  consider:
4749 # - the first open gets a {0,EOF}PR lock
4750 # - the first write conflicts and gets a {0, count-1}PW
4751 # - the rest of the writes are under {count,EOF}PW
4752 # - the open for truncate tries to match a {0,EOF}PR
4753 #   for the filesize and cancels the PWs.
4754 # any number of fixes (don't get {0,EOF} on open, match
4755 # composite locks, do smarter file size management) fix
4756 # this, but for now we want these tests to verify that
4757 # the cancellation with truncate intent works, so we
4758 # start the file with a full-file pw lock to match against
4759 # until the truncate.
4760 trunc_test() {
4761         test=$1
4762         file=$DIR/$test
4763         offset=$2
4764         cancel_lru_locks $OSC
4765         stop_writeback
4766         # prime the file with 0,EOF PW to match
4767         touch $file
4768         $TRUNCATE $file 0
4769         sync; sync
4770         # now the real test..
4771         dd if=/dev/zero of=$file bs=1024 count=100
4772         BEFOREWRITES=`count_ost_writes`
4773         $TRUNCATE $file $offset
4774         cancel_lru_locks $OSC
4775         AFTERWRITES=`count_ost_writes`
4776         start_writeback
4777 }
4778
4779 test_42c() {
4780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4781
4782         trunc_test 42c 1024
4783         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4784                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4785         rm $file
4786 }
4787 run_test 42c "test partial truncate of file with cached dirty data"
4788
4789 test_42d() {
4790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4791
4792         trunc_test 42d 0
4793         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4794                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4795         rm $file
4796 }
4797 run_test 42d "test complete truncate of file with cached dirty data"
4798
4799 test_42e() { # bug22074
4800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4801
4802         local TDIR=$DIR/${tdir}e
4803         local pages=16 # hardcoded 16 pages, don't change it.
4804         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4805         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4806         local max_dirty_mb
4807         local warmup_files
4808
4809         test_mkdir $DIR/${tdir}e
4810         $LFS setstripe -c 1 $TDIR
4811         createmany -o $TDIR/f $files
4812
4813         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4814
4815         # we assume that with $OSTCOUNT files, at least one of them will
4816         # be allocated on OST0.
4817         warmup_files=$((OSTCOUNT * max_dirty_mb))
4818         createmany -o $TDIR/w $warmup_files
4819
4820         # write a large amount of data into one file and sync, to get good
4821         # avail_grant number from OST.
4822         for ((i=0; i<$warmup_files; i++)); do
4823                 idx=$($LFS getstripe -i $TDIR/w$i)
4824                 [ $idx -ne 0 ] && continue
4825                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4826                 break
4827         done
4828         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4829         sync
4830         $LCTL get_param $proc_osc0/cur_dirty_bytes
4831         $LCTL get_param $proc_osc0/cur_grant_bytes
4832
4833         # create as much dirty pages as we can while not to trigger the actual
4834         # RPCs directly. but depends on the env, VFS may trigger flush during this
4835         # period, hopefully we are good.
4836         for ((i=0; i<$warmup_files; i++)); do
4837                 idx=$($LFS getstripe -i $TDIR/w$i)
4838                 [ $idx -ne 0 ] && continue
4839                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4840         done
4841         $LCTL get_param $proc_osc0/cur_dirty_bytes
4842         $LCTL get_param $proc_osc0/cur_grant_bytes
4843
4844         # perform the real test
4845         $LCTL set_param $proc_osc0/rpc_stats 0
4846         for ((;i<$files; i++)); do
4847                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4848                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4849         done
4850         sync
4851         $LCTL get_param $proc_osc0/rpc_stats
4852
4853         local percent=0
4854         local have_ppr=false
4855         $LCTL get_param $proc_osc0/rpc_stats |
4856                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4857                         # skip lines until we are at the RPC histogram data
4858                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4859                         $have_ppr || continue
4860
4861                         # we only want the percent stat for < 16 pages
4862                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4863
4864                         percent=$((percent + WPCT))
4865                         if [[ $percent -gt 15 ]]; then
4866                                 error "less than 16-pages write RPCs" \
4867                                       "$percent% > 15%"
4868                                 break
4869                         fi
4870                 done
4871         rm -rf $TDIR
4872 }
4873 run_test 42e "verify sub-RPC writes are not done synchronously"
4874
4875 test_43A() { # was test_43
4876         test_mkdir $DIR/$tdir
4877         cp -p /bin/ls $DIR/$tdir/$tfile
4878         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4879         pid=$!
4880         # give multiop a chance to open
4881         sleep 1
4882
4883         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4884         kill -USR1 $pid
4885         # Wait for multiop to exit
4886         wait $pid
4887 }
4888 run_test 43A "execution of file opened for write should return -ETXTBSY"
4889
4890 test_43a() {
4891         test_mkdir $DIR/$tdir
4892         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4893         $DIR/$tdir/sleep 60 &
4894         SLEEP_PID=$!
4895         # Make sure exec of $tdir/sleep wins race with truncate
4896         sleep 1
4897         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4898         kill $SLEEP_PID
4899 }
4900 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4901
4902 test_43b() {
4903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4904
4905         test_mkdir $DIR/$tdir
4906         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4907         $DIR/$tdir/sleep 60 &
4908         SLEEP_PID=$!
4909         # Make sure exec of $tdir/sleep wins race with truncate
4910         sleep 1
4911         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4912         kill $SLEEP_PID
4913 }
4914 run_test 43b "truncate of file being executed should return -ETXTBSY"
4915
4916 test_43c() {
4917         local testdir="$DIR/$tdir"
4918         test_mkdir $testdir
4919         cp $SHELL $testdir/
4920         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4921                 ( cd $testdir && md5sum -c )
4922 }
4923 run_test 43c "md5sum of copy into lustre"
4924
4925 test_44A() { # was test_44
4926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4927
4928         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4929         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4930 }
4931 run_test 44A "zero length read from a sparse stripe"
4932
4933 test_44a() {
4934         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4935                 awk '{ print $2 }')
4936         [ -z "$nstripe" ] && skip "can't get stripe info"
4937         [[ $nstripe -gt $OSTCOUNT ]] &&
4938                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4939
4940         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4941                 awk '{ print $2 }')
4942         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4943                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4944                         awk '{ print $2 }')
4945         fi
4946
4947         OFFSETS="0 $((stride/2)) $((stride-1))"
4948         for offset in $OFFSETS; do
4949                 for i in $(seq 0 $((nstripe-1))); do
4950                         local GLOBALOFFSETS=""
4951                         # size in Bytes
4952                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4953                         local myfn=$DIR/d44a-$size
4954                         echo "--------writing $myfn at $size"
4955                         ll_sparseness_write $myfn $size ||
4956                                 error "ll_sparseness_write"
4957                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4958                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4959                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4960
4961                         for j in $(seq 0 $((nstripe-1))); do
4962                                 # size in Bytes
4963                                 size=$((((j + $nstripe )*$stride + $offset)))
4964                                 ll_sparseness_write $myfn $size ||
4965                                         error "ll_sparseness_write"
4966                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4967                         done
4968                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4969                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4970                         rm -f $myfn
4971                 done
4972         done
4973 }
4974 run_test 44a "test sparse pwrite ==============================="
4975
4976 dirty_osc_total() {
4977         tot=0
4978         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4979                 tot=$(($tot + $d))
4980         done
4981         echo $tot
4982 }
4983 do_dirty_record() {
4984         before=`dirty_osc_total`
4985         echo executing "\"$*\""
4986         eval $*
4987         after=`dirty_osc_total`
4988         echo before $before, after $after
4989 }
4990 test_45() {
4991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4992
4993         f="$DIR/f45"
4994         # Obtain grants from OST if it supports it
4995         echo blah > ${f}_grant
4996         stop_writeback
4997         sync
4998         do_dirty_record "echo blah > $f"
4999         [[ $before -eq $after ]] && error "write wasn't cached"
5000         do_dirty_record "> $f"
5001         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5002         do_dirty_record "echo blah > $f"
5003         [[ $before -eq $after ]] && error "write wasn't cached"
5004         do_dirty_record "sync"
5005         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5006         do_dirty_record "echo blah > $f"
5007         [[ $before -eq $after ]] && error "write wasn't cached"
5008         do_dirty_record "cancel_lru_locks osc"
5009         [[ $before -gt $after ]] ||
5010                 error "lock cancellation didn't lower dirty count"
5011         start_writeback
5012 }
5013 run_test 45 "osc io page accounting ============================"
5014
5015 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5016 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5017 # objects offset and an assert hit when an rpc was built with 1023's mapped
5018 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5019 test_46() {
5020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5021
5022         f="$DIR/f46"
5023         stop_writeback
5024         sync
5025         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5026         sync
5027         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5028         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5029         sync
5030         start_writeback
5031 }
5032 run_test 46 "dirtying a previously written page ================"
5033
5034 # test_47 is removed "Device nodes check" is moved to test_28
5035
5036 test_48a() { # bug 2399
5037         [ "$mds1_FSTYPE" = "zfs" ] &&
5038         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5039                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5040
5041         test_mkdir $DIR/$tdir
5042         cd $DIR/$tdir
5043         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5044         test_mkdir $DIR/$tdir
5045         touch foo || error "'touch foo' failed after recreating cwd"
5046         test_mkdir bar
5047         touch .foo || error "'touch .foo' failed after recreating cwd"
5048         test_mkdir .bar
5049         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5050         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5051         cd . || error "'cd .' failed after recreating cwd"
5052         mkdir . && error "'mkdir .' worked after recreating cwd"
5053         rmdir . && error "'rmdir .' worked after recreating cwd"
5054         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5055         cd .. || error "'cd ..' failed after recreating cwd"
5056 }
5057 run_test 48a "Access renamed working dir (should return errors)="
5058
5059 test_48b() { # bug 2399
5060         rm -rf $DIR/$tdir
5061         test_mkdir $DIR/$tdir
5062         cd $DIR/$tdir
5063         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5064         touch foo && error "'touch foo' worked after removing cwd"
5065         mkdir foo && error "'mkdir foo' worked after removing cwd"
5066         touch .foo && error "'touch .foo' worked after removing cwd"
5067         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5068         ls . > /dev/null && error "'ls .' worked after removing cwd"
5069         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5070         mkdir . && error "'mkdir .' worked after removing cwd"
5071         rmdir . && error "'rmdir .' worked after removing cwd"
5072         ln -s . foo && error "'ln -s .' worked after removing cwd"
5073         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5074 }
5075 run_test 48b "Access removed working dir (should return errors)="
5076
5077 test_48c() { # bug 2350
5078         #lctl set_param debug=-1
5079         #set -vx
5080         rm -rf $DIR/$tdir
5081         test_mkdir -p $DIR/$tdir/dir
5082         cd $DIR/$tdir/dir
5083         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5084         $TRACE touch foo && error "touch foo worked after removing cwd"
5085         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5086         touch .foo && error "touch .foo worked after removing cwd"
5087         mkdir .foo && error "mkdir .foo worked after removing cwd"
5088         $TRACE ls . && error "'ls .' worked after removing cwd"
5089         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5090         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5091         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5092         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5093         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5094 }
5095 run_test 48c "Access removed working subdir (should return errors)"
5096
5097 test_48d() { # bug 2350
5098         #lctl set_param debug=-1
5099         #set -vx
5100         rm -rf $DIR/$tdir
5101         test_mkdir -p $DIR/$tdir/dir
5102         cd $DIR/$tdir/dir
5103         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5104         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5105         $TRACE touch foo && error "'touch foo' worked after removing parent"
5106         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5107         touch .foo && error "'touch .foo' worked after removing parent"
5108         mkdir .foo && error "mkdir .foo worked after removing parent"
5109         $TRACE ls . && error "'ls .' worked after removing parent"
5110         $TRACE ls .. && error "'ls ..' worked after removing parent"
5111         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5112         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5113         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5114         true
5115 }
5116 run_test 48d "Access removed parent subdir (should return errors)"
5117
5118 test_48e() { # bug 4134
5119         #lctl set_param debug=-1
5120         #set -vx
5121         rm -rf $DIR/$tdir
5122         test_mkdir -p $DIR/$tdir/dir
5123         cd $DIR/$tdir/dir
5124         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5125         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5126         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5127         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5128         # On a buggy kernel addition of "touch foo" after cd .. will
5129         # produce kernel oops in lookup_hash_it
5130         touch ../foo && error "'cd ..' worked after recreate parent"
5131         cd $DIR
5132         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5133 }
5134 run_test 48e "Access to recreated parent subdir (should return errors)"
5135
5136 test_48f() {
5137         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5138                 skip "need MDS >= 2.13.55"
5139         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5140         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5141                 skip "needs different host for mdt1 mdt2"
5142         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5143
5144         $LFS mkdir -i0 $DIR/$tdir
5145         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5146
5147         for d in sub1 sub2 sub3; do
5148                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5149                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5150                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5151         done
5152
5153         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5154 }
5155 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5156
5157 test_49() { # LU-1030
5158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5159         remote_ost_nodsh && skip "remote OST with nodsh"
5160
5161         # get ost1 size - $FSNAME-OST0000
5162         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5163                 awk '{ print $4 }')
5164         # write 800M at maximum
5165         [[ $ost1_size -lt 2 ]] && ost1_size=2
5166         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5167
5168         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5169         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5170         local dd_pid=$!
5171
5172         # change max_pages_per_rpc while writing the file
5173         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5174         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5175         # loop until dd process exits
5176         while ps ax -opid | grep -wq $dd_pid; do
5177                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5178                 sleep $((RANDOM % 5 + 1))
5179         done
5180         # restore original max_pages_per_rpc
5181         $LCTL set_param $osc1_mppc=$orig_mppc
5182         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5183 }
5184 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5185
5186 test_50() {
5187         # bug 1485
5188         test_mkdir $DIR/$tdir
5189         cd $DIR/$tdir
5190         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5191 }
5192 run_test 50 "special situations: /proc symlinks  ==============="
5193
5194 test_51a() {    # was test_51
5195         # bug 1516 - create an empty entry right after ".." then split dir
5196         test_mkdir -c1 $DIR/$tdir
5197         touch $DIR/$tdir/foo
5198         $MCREATE $DIR/$tdir/bar
5199         rm $DIR/$tdir/foo
5200         createmany -m $DIR/$tdir/longfile 201
5201         FNUM=202
5202         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5203                 $MCREATE $DIR/$tdir/longfile$FNUM
5204                 FNUM=$(($FNUM + 1))
5205                 echo -n "+"
5206         done
5207         echo
5208         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5209 }
5210 run_test 51a "special situations: split htree with empty entry =="
5211
5212 cleanup_print_lfs_df () {
5213         trap 0
5214         $LFS df
5215         $LFS df -i
5216 }
5217
5218 test_51b() {
5219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5220
5221         local dir=$DIR/$tdir
5222         local nrdirs=$((65536 + 100))
5223
5224         # cleanup the directory
5225         rm -fr $dir
5226
5227         test_mkdir -c1 $dir
5228
5229         $LFS df
5230         $LFS df -i
5231         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5232         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5233         [[ $numfree -lt $nrdirs ]] &&
5234                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5235
5236         # need to check free space for the directories as well
5237         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5238         numfree=$(( blkfree / $(fs_inode_ksize) ))
5239         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5240
5241         trap cleanup_print_lfs_df EXIT
5242
5243         # create files
5244         createmany -d $dir/d $nrdirs || {
5245                 unlinkmany $dir/d $nrdirs
5246                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5247         }
5248
5249         # really created :
5250         nrdirs=$(ls -U $dir | wc -l)
5251
5252         # unlink all but 100 subdirectories, then check it still works
5253         local left=100
5254         local delete=$((nrdirs - left))
5255
5256         $LFS df
5257         $LFS df -i
5258
5259         # for ldiskfs the nlink count should be 1, but this is OSD specific
5260         # and so this is listed for informational purposes only
5261         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5262         unlinkmany -d $dir/d $delete ||
5263                 error "unlink of first $delete subdirs failed"
5264
5265         echo "nlink between: $(stat -c %h $dir)"
5266         local found=$(ls -U $dir | wc -l)
5267         [ $found -ne $left ] &&
5268                 error "can't find subdirs: found only $found, expected $left"
5269
5270         unlinkmany -d $dir/d $delete $left ||
5271                 error "unlink of second $left subdirs failed"
5272         # regardless of whether the backing filesystem tracks nlink accurately
5273         # or not, the nlink count shouldn't be more than "." and ".." here
5274         local after=$(stat -c %h $dir)
5275         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5276                 echo "nlink after: $after"
5277
5278         cleanup_print_lfs_df
5279 }
5280 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5281
5282 test_51d() {
5283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5284         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5285
5286         test_mkdir $DIR/$tdir
5287         createmany -o $DIR/$tdir/t- 1000
5288         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5289         for N in $(seq 0 $((OSTCOUNT - 1))); do
5290                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5291                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5292                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5293                         '($1 == '$N') { objs += 1 } \
5294                         END { printf("%0.0f", objs) }')
5295                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5296         done
5297         unlinkmany $DIR/$tdir/t- 1000
5298
5299         NLAST=0
5300         for N in $(seq 1 $((OSTCOUNT - 1))); do
5301                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5302                         error "OST $N has less objects vs OST $NLAST" \
5303                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5304                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5305                         error "OST $N has less objects vs OST $NLAST" \
5306                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5307
5308                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5309                         error "OST $N has less #0 objects vs OST $NLAST" \
5310                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5311                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5312                         error "OST $N has less #0 objects vs OST $NLAST" \
5313                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5314                 NLAST=$N
5315         done
5316         rm -f $TMP/$tfile
5317 }
5318 run_test 51d "check object distribution"
5319
5320 test_51e() {
5321         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5322                 skip_env "ldiskfs only test"
5323         fi
5324
5325         test_mkdir -c1 $DIR/$tdir
5326         test_mkdir -c1 $DIR/$tdir/d0
5327
5328         touch $DIR/$tdir/d0/foo
5329         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5330                 error "file exceed 65000 nlink limit!"
5331         unlinkmany $DIR/$tdir/d0/f- 65001
5332         return 0
5333 }
5334 run_test 51e "check file nlink limit"
5335
5336 test_51f() {
5337         test_mkdir $DIR/$tdir
5338
5339         local max=100000
5340         local ulimit_old=$(ulimit -n)
5341         local spare=20 # number of spare fd's for scripts/libraries, etc.
5342         local mdt=$($LFS getstripe -m $DIR/$tdir)
5343         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5344
5345         echo "MDT$mdt numfree=$numfree, max=$max"
5346         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5347         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5348                 while ! ulimit -n $((numfree + spare)); do
5349                         numfree=$((numfree * 3 / 4))
5350                 done
5351                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5352         else
5353                 echo "left ulimit at $ulimit_old"
5354         fi
5355
5356         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5357                 unlinkmany $DIR/$tdir/f $numfree
5358                 error "create+open $numfree files in $DIR/$tdir failed"
5359         }
5360         ulimit -n $ulimit_old
5361
5362         # if createmany exits at 120s there will be fewer than $numfree files
5363         unlinkmany $DIR/$tdir/f $numfree || true
5364 }
5365 run_test 51f "check many open files limit"
5366
5367 test_52a() {
5368         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5369         test_mkdir $DIR/$tdir
5370         touch $DIR/$tdir/foo
5371         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5372         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5373         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5374         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5375         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5376                                         error "link worked"
5377         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5378         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5379         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5380                                                      error "lsattr"
5381         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5382         cp -r $DIR/$tdir $TMP/
5383         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5384 }
5385 run_test 52a "append-only flag test (should return errors)"
5386
5387 test_52b() {
5388         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5389         test_mkdir $DIR/$tdir
5390         touch $DIR/$tdir/foo
5391         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5392         cat test > $DIR/$tdir/foo && error "cat test worked"
5393         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5394         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5395         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5396                                         error "link worked"
5397         echo foo >> $DIR/$tdir/foo && error "echo worked"
5398         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5399         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5400         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5401         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5402                                                         error "lsattr"
5403         chattr -i $DIR/$tdir/foo || error "chattr failed"
5404
5405         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5406 }
5407 run_test 52b "immutable flag test (should return errors) ======="
5408
5409 test_53() {
5410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5411         remote_mds_nodsh && skip "remote MDS with nodsh"
5412         remote_ost_nodsh && skip "remote OST with nodsh"
5413
5414         local param
5415         local param_seq
5416         local ostname
5417         local mds_last
5418         local mds_last_seq
5419         local ost_last
5420         local ost_last_seq
5421         local ost_last_id
5422         local ostnum
5423         local node
5424         local found=false
5425         local support_last_seq=true
5426
5427         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5428                 support_last_seq=false
5429
5430         # only test MDT0000
5431         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5432         local value
5433         for value in $(do_facet $SINGLEMDS \
5434                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5435                 param=$(echo ${value[0]} | cut -d "=" -f1)
5436                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5437
5438                 if $support_last_seq; then
5439                         param_seq=$(echo $param |
5440                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5441                         mds_last_seq=$(do_facet $SINGLEMDS \
5442                                        $LCTL get_param -n $param_seq)
5443                 fi
5444                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5445
5446                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5447                 node=$(facet_active_host ost$((ostnum+1)))
5448                 param="obdfilter.$ostname.last_id"
5449                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5450                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5451                         ost_last_id=$ost_last
5452
5453                         if $support_last_seq; then
5454                                 ost_last_id=$(echo $ost_last |
5455                                               awk -F':' '{print $2}' |
5456                                               sed -e "s/^0x//g")
5457                                 ost_last_seq=$(echo $ost_last |
5458                                                awk -F':' '{print $1}')
5459                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5460                         fi
5461
5462                         if [[ $ost_last_id != $mds_last ]]; then
5463                                 error "$ost_last_id != $mds_last"
5464                         else
5465                                 found=true
5466                                 break
5467                         fi
5468                 done
5469         done
5470         $found || error "can not match last_seq/last_id for $mdtosc"
5471         return 0
5472 }
5473 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5474
5475 test_54a() {
5476         perl -MSocket -e ';' || skip "no Socket perl module installed"
5477
5478         $SOCKETSERVER $DIR/socket ||
5479                 error "$SOCKETSERVER $DIR/socket failed: $?"
5480         $SOCKETCLIENT $DIR/socket ||
5481                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5482         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5483 }
5484 run_test 54a "unix domain socket test =========================="
5485
5486 test_54b() {
5487         f="$DIR/f54b"
5488         mknod $f c 1 3
5489         chmod 0666 $f
5490         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5491 }
5492 run_test 54b "char device works in lustre ======================"
5493
5494 find_loop_dev() {
5495         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5496         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5497         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5498
5499         for i in $(seq 3 7); do
5500                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5501                 LOOPDEV=$LOOPBASE$i
5502                 LOOPNUM=$i
5503                 break
5504         done
5505 }
5506
5507 cleanup_54c() {
5508         local rc=0
5509         loopdev="$DIR/loop54c"
5510
5511         trap 0
5512         $UMOUNT $DIR/$tdir || rc=$?
5513         losetup -d $loopdev || true
5514         losetup -d $LOOPDEV || true
5515         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5516         return $rc
5517 }
5518
5519 test_54c() {
5520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5521
5522         loopdev="$DIR/loop54c"
5523
5524         find_loop_dev
5525         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5526         trap cleanup_54c EXIT
5527         mknod $loopdev b 7 $LOOPNUM
5528         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5529         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5530         losetup $loopdev $DIR/$tfile ||
5531                 error "can't set up $loopdev for $DIR/$tfile"
5532         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5533         test_mkdir $DIR/$tdir
5534         mount -t ext2 $loopdev $DIR/$tdir ||
5535                 error "error mounting $loopdev on $DIR/$tdir"
5536         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5537                 error "dd write"
5538         df $DIR/$tdir
5539         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5540                 error "dd read"
5541         cleanup_54c
5542 }
5543 run_test 54c "block device works in lustre ====================="
5544
5545 test_54d() {
5546         f="$DIR/f54d"
5547         string="aaaaaa"
5548         mknod $f p
5549         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5550 }
5551 run_test 54d "fifo device works in lustre ======================"
5552
5553 test_54e() {
5554         f="$DIR/f54e"
5555         string="aaaaaa"
5556         cp -aL /dev/console $f
5557         echo $string > $f || error "echo $string to $f failed"
5558 }
5559 run_test 54e "console/tty device works in lustre ======================"
5560
5561 test_56a() {
5562         local numfiles=3
5563         local dir=$DIR/$tdir
5564
5565         rm -rf $dir
5566         test_mkdir -p $dir/dir
5567         for i in $(seq $numfiles); do
5568                 touch $dir/file$i
5569                 touch $dir/dir/file$i
5570         done
5571
5572         local numcomp=$($LFS getstripe --component-count $dir)
5573
5574         [[ $numcomp == 0 ]] && numcomp=1
5575
5576         # test lfs getstripe with --recursive
5577         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5578
5579         [[ $filenum -eq $((numfiles * 2)) ]] ||
5580                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5581         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5582         [[ $filenum -eq $numfiles ]] ||
5583                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5584         echo "$LFS getstripe showed obdidx or l_ost_idx"
5585
5586         # test lfs getstripe with file instead of dir
5587         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5588         [[ $filenum -eq 1 ]] ||
5589                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5590         echo "$LFS getstripe file1 passed"
5591
5592         #test lfs getstripe with --verbose
5593         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5594         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5595                 error "$LFS getstripe --verbose $dir: "\
5596                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5597         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5598                 error "$LFS getstripe $dir: showed lmm_magic"
5599
5600         #test lfs getstripe with -v prints lmm_fid
5601         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5602         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5603                 error "$LFS getstripe -v $dir: "\
5604                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5605         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5606                 error "$LFS getstripe $dir: showed lmm_fid by default"
5607         echo "$LFS getstripe --verbose passed"
5608
5609         #check for FID information
5610         local fid1=$($LFS getstripe --fid $dir/file1)
5611         local fid2=$($LFS getstripe --verbose $dir/file1 |
5612                      awk '/lmm_fid: / { print $2; exit; }')
5613         local fid3=$($LFS path2fid $dir/file1)
5614
5615         [ "$fid1" != "$fid2" ] &&
5616                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5617         [ "$fid1" != "$fid3" ] &&
5618                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5619         echo "$LFS getstripe --fid passed"
5620
5621         #test lfs getstripe with --obd
5622         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5623                 error "$LFS getstripe --obd wrong_uuid: should return error"
5624
5625         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5626
5627         local ostidx=1
5628         local obduuid=$(ostuuid_from_index $ostidx)
5629         local found=$($LFS getstripe -r --obd $obduuid $dir |
5630                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5631
5632         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5633         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5634                 ((filenum--))
5635         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5636                 ((filenum--))
5637
5638         [[ $found -eq $filenum ]] ||
5639                 error "$LFS getstripe --obd: found $found expect $filenum"
5640         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5641                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5642                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5643                 error "$LFS getstripe --obd: should not show file on other obd"
5644         echo "$LFS getstripe --obd passed"
5645 }
5646 run_test 56a "check $LFS getstripe"
5647
5648 test_56b() {
5649         local dir=$DIR/$tdir
5650         local numdirs=3
5651
5652         test_mkdir $dir
5653         for i in $(seq $numdirs); do
5654                 test_mkdir $dir/dir$i
5655         done
5656
5657         # test lfs getdirstripe default mode is non-recursion, which is
5658         # different from lfs getstripe
5659         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5660
5661         [[ $dircnt -eq 1 ]] ||
5662                 error "$LFS getdirstripe: found $dircnt, not 1"
5663         dircnt=$($LFS getdirstripe --recursive $dir |
5664                 grep -c lmv_stripe_count)
5665         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5666                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5667 }
5668 run_test 56b "check $LFS getdirstripe"
5669
5670 test_56c() {
5671         remote_ost_nodsh && skip "remote OST with nodsh"
5672
5673         local ost_idx=0
5674         local ost_name=$(ostname_from_index $ost_idx)
5675         local old_status=$(ost_dev_status $ost_idx)
5676         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5677
5678         [[ -z "$old_status" ]] ||
5679                 skip_env "OST $ost_name is in $old_status status"
5680
5681         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5682         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5683                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5684         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5685                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5686                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5687         fi
5688
5689         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5690                 error "$LFS df -v showing inactive devices"
5691         sleep_maxage
5692
5693         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5694
5695         [[ "$new_status" =~ "D" ]] ||
5696                 error "$ost_name status is '$new_status', missing 'D'"
5697         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5698                 [[ "$new_status" =~ "N" ]] ||
5699                         error "$ost_name status is '$new_status', missing 'N'"
5700         fi
5701         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5702                 [[ "$new_status" =~ "f" ]] ||
5703                         error "$ost_name status is '$new_status', missing 'f'"
5704         fi
5705
5706         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5707         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5708                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5709         [[ -z "$p" ]] && restore_lustre_params < $p || true
5710         sleep_maxage
5711
5712         new_status=$(ost_dev_status $ost_idx)
5713         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5714                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5715         # can't check 'f' as devices may actually be on flash
5716 }
5717 run_test 56c "check 'lfs df' showing device status"
5718
5719 test_56d() {
5720         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5721         local osts=$($LFS df -v $MOUNT | grep -c OST)
5722
5723         $LFS df $MOUNT
5724
5725         (( mdts == MDSCOUNT )) ||
5726                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5727         (( osts == OSTCOUNT )) ||
5728                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5729 }
5730 run_test 56d "'lfs df -v' prints only configured devices"
5731
5732 NUMFILES=3
5733 NUMDIRS=3
5734 setup_56() {
5735         local local_tdir="$1"
5736         local local_numfiles="$2"
5737         local local_numdirs="$3"
5738         local dir_params="$4"
5739         local dir_stripe_params="$5"
5740
5741         if [ ! -d "$local_tdir" ] ; then
5742                 test_mkdir -p $dir_stripe_params $local_tdir
5743                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5744                 for i in $(seq $local_numfiles) ; do
5745                         touch $local_tdir/file$i
5746                 done
5747                 for i in $(seq $local_numdirs) ; do
5748                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5749                         for j in $(seq $local_numfiles) ; do
5750                                 touch $local_tdir/dir$i/file$j
5751                         done
5752                 done
5753         fi
5754 }
5755
5756 setup_56_special() {
5757         local local_tdir=$1
5758         local local_numfiles=$2
5759         local local_numdirs=$3
5760
5761         setup_56 $local_tdir $local_numfiles $local_numdirs
5762
5763         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5764                 for i in $(seq $local_numfiles) ; do
5765                         mknod $local_tdir/loop${i}b b 7 $i
5766                         mknod $local_tdir/null${i}c c 1 3
5767                         ln -s $local_tdir/file1 $local_tdir/link${i}
5768                 done
5769                 for i in $(seq $local_numdirs) ; do
5770                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5771                         mknod $local_tdir/dir$i/null${i}c c 1 3
5772                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5773                 done
5774         fi
5775 }
5776
5777 test_56g() {
5778         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5779         local expected=$(($NUMDIRS + 2))
5780
5781         setup_56 $dir $NUMFILES $NUMDIRS
5782
5783         # test lfs find with -name
5784         for i in $(seq $NUMFILES) ; do
5785                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5786
5787                 [ $nums -eq $expected ] ||
5788                         error "lfs find -name '*$i' $dir wrong: "\
5789                               "found $nums, expected $expected"
5790         done
5791 }
5792 run_test 56g "check lfs find -name"
5793
5794 test_56h() {
5795         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5796         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5797
5798         setup_56 $dir $NUMFILES $NUMDIRS
5799
5800         # test lfs find with ! -name
5801         for i in $(seq $NUMFILES) ; do
5802                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5803
5804                 [ $nums -eq $expected ] ||
5805                         error "lfs find ! -name '*$i' $dir wrong: "\
5806                               "found $nums, expected $expected"
5807         done
5808 }
5809 run_test 56h "check lfs find ! -name"
5810
5811 test_56i() {
5812         local dir=$DIR/$tdir
5813
5814         test_mkdir $dir
5815
5816         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5817         local out=$($cmd)
5818
5819         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5820 }
5821 run_test 56i "check 'lfs find -ost UUID' skips directories"
5822
5823 test_56j() {
5824         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5825
5826         setup_56_special $dir $NUMFILES $NUMDIRS
5827
5828         local expected=$((NUMDIRS + 1))
5829         local cmd="$LFS find -type d $dir"
5830         local nums=$($cmd | wc -l)
5831
5832         [ $nums -eq $expected ] ||
5833                 error "'$cmd' wrong: found $nums, expected $expected"
5834 }
5835 run_test 56j "check lfs find -type d"
5836
5837 test_56k() {
5838         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5839
5840         setup_56_special $dir $NUMFILES $NUMDIRS
5841
5842         local expected=$(((NUMDIRS + 1) * NUMFILES))
5843         local cmd="$LFS find -type f $dir"
5844         local nums=$($cmd | wc -l)
5845
5846         [ $nums -eq $expected ] ||
5847                 error "'$cmd' wrong: found $nums, expected $expected"
5848 }
5849 run_test 56k "check lfs find -type f"
5850
5851 test_56l() {
5852         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5853
5854         setup_56_special $dir $NUMFILES $NUMDIRS
5855
5856         local expected=$((NUMDIRS + NUMFILES))
5857         local cmd="$LFS find -type b $dir"
5858         local nums=$($cmd | wc -l)
5859
5860         [ $nums -eq $expected ] ||
5861                 error "'$cmd' wrong: found $nums, expected $expected"
5862 }
5863 run_test 56l "check lfs find -type b"
5864
5865 test_56m() {
5866         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5867
5868         setup_56_special $dir $NUMFILES $NUMDIRS
5869
5870         local expected=$((NUMDIRS + NUMFILES))
5871         local cmd="$LFS find -type c $dir"
5872         local nums=$($cmd | wc -l)
5873         [ $nums -eq $expected ] ||
5874                 error "'$cmd' wrong: found $nums, expected $expected"
5875 }
5876 run_test 56m "check lfs find -type c"
5877
5878 test_56n() {
5879         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5880         setup_56_special $dir $NUMFILES $NUMDIRS
5881
5882         local expected=$((NUMDIRS + NUMFILES))
5883         local cmd="$LFS find -type l $dir"
5884         local nums=$($cmd | wc -l)
5885
5886         [ $nums -eq $expected ] ||
5887                 error "'$cmd' wrong: found $nums, expected $expected"
5888 }
5889 run_test 56n "check lfs find -type l"
5890
5891 test_56o() {
5892         local dir=$DIR/$tdir
5893
5894         setup_56 $dir $NUMFILES $NUMDIRS
5895         utime $dir/file1 > /dev/null || error "utime (1)"
5896         utime $dir/file2 > /dev/null || error "utime (2)"
5897         utime $dir/dir1 > /dev/null || error "utime (3)"
5898         utime $dir/dir2 > /dev/null || error "utime (4)"
5899         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5900         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5901
5902         local expected=4
5903         local nums=$($LFS find -mtime +0 $dir | wc -l)
5904
5905         [ $nums -eq $expected ] ||
5906                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5907
5908         expected=12
5909         cmd="$LFS find -mtime 0 $dir"
5910         nums=$($cmd | wc -l)
5911         [ $nums -eq $expected ] ||
5912                 error "'$cmd' wrong: found $nums, expected $expected"
5913 }
5914 run_test 56o "check lfs find -mtime for old files"
5915
5916 test_56ob() {
5917         local dir=$DIR/$tdir
5918         local expected=1
5919         local count=0
5920
5921         # just to make sure there is something that won't be found
5922         test_mkdir $dir
5923         touch $dir/$tfile.now
5924
5925         for age in year week day hour min; do
5926                 count=$((count + 1))
5927
5928                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5929                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5930                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5931
5932                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5933                 local nums=$($cmd | wc -l)
5934                 [ $nums -eq $expected ] ||
5935                         error "'$cmd' wrong: found $nums, expected $expected"
5936
5937                 cmd="$LFS find $dir -atime $count${age:0:1}"
5938                 nums=$($cmd | wc -l)
5939                 [ $nums -eq $expected ] ||
5940                         error "'$cmd' wrong: found $nums, expected $expected"
5941         done
5942
5943         sleep 2
5944         cmd="$LFS find $dir -ctime +1s -type f"
5945         nums=$($cmd | wc -l)
5946         (( $nums == $count * 2 + 1)) ||
5947                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5948 }
5949 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5950
5951 test_newerXY_base() {
5952         local x=$1
5953         local y=$2
5954         local dir=$DIR/$tdir
5955         local ref
5956         local negref
5957
5958         if [ $y == "t" ]; then
5959                 if [ $x == "b" ]; then
5960                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5961                 else
5962                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5963                 fi
5964         else
5965                 ref=$DIR/$tfile.newer.$x$y
5966                 touch $ref || error "touch $ref failed"
5967         fi
5968         sleep 2
5969         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5970         sleep 2
5971         if [ $y == "t" ]; then
5972                 if [ $x == "b" ]; then
5973                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5974                 else
5975                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5976                 fi
5977         else
5978                 negref=$DIR/$tfile.negnewer.$x$y
5979                 touch $negref || error "touch $negref failed"
5980         fi
5981
5982         local cmd="$LFS find $dir -newer$x$y $ref"
5983         local nums=$(eval $cmd | wc -l)
5984         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5985
5986         [ $nums -eq $expected ] ||
5987                 error "'$cmd' wrong: found $nums, expected $expected"
5988
5989         cmd="$LFS find $dir ! -newer$x$y $negref"
5990         nums=$(eval $cmd | wc -l)
5991         [ $nums -eq $expected ] ||
5992                 error "'$cmd' wrong: found $nums, expected $expected"
5993
5994         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5995         nums=$(eval $cmd | wc -l)
5996         [ $nums -eq $expected ] ||
5997                 error "'$cmd' wrong: found $nums, expected $expected"
5998
5999         rm -rf $DIR/*
6000 }
6001
6002 test_56oc() {
6003         test_newerXY_base "b" "t"
6004         test_newerXY_base "a" "a"
6005         test_newerXY_base "a" "m"
6006         test_newerXY_base "a" "c"
6007         test_newerXY_base "m" "a"
6008         test_newerXY_base "m" "m"
6009         test_newerXY_base "m" "c"
6010         test_newerXY_base "c" "a"
6011         test_newerXY_base "c" "m"
6012         test_newerXY_base "c" "c"
6013         test_newerXY_base "b" "b"
6014         test_newerXY_base "a" "t"
6015         test_newerXY_base "m" "t"
6016         test_newerXY_base "c" "t"
6017         test_newerXY_base "b" "t"
6018 }
6019 run_test 56oc "check lfs find -newerXY work"
6020
6021 btime_supported() {
6022         local dir=$DIR/$tdir
6023         local rc
6024
6025         mkdir -p $dir
6026         touch $dir/$tfile
6027         $LFS find $dir -btime -1d -type f
6028         rc=$?
6029         rm -rf $dir
6030         return $rc
6031 }
6032
6033 test_56od() {
6034         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6035                 ! btime_supported && skip "btime unsupported on MDS"
6036
6037         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6038                 ! btime_supported && skip "btime unsupported on clients"
6039
6040         local dir=$DIR/$tdir
6041         local ref=$DIR/$tfile.ref
6042         local negref=$DIR/$tfile.negref
6043
6044         mkdir $dir || error "mkdir $dir failed"
6045         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6046         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6047         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6048         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6049         touch $ref || error "touch $ref failed"
6050         # sleep 3 seconds at least
6051         sleep 3
6052
6053         local before=$(do_facet mds1 date +%s)
6054         local skew=$(($(date +%s) - before + 1))
6055
6056         if (( skew < 0 && skew > -5 )); then
6057                 sleep $((0 - skew + 1))
6058                 skew=0
6059         fi
6060
6061         # Set the dir stripe params to limit files all on MDT0,
6062         # otherwise we need to calc the max clock skew between
6063         # the client and MDTs.
6064         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6065         sleep 2
6066         touch $negref || error "touch $negref failed"
6067
6068         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6069         local nums=$($cmd | wc -l)
6070         local expected=$(((NUMFILES + 1) * NUMDIRS))
6071
6072         [ $nums -eq $expected ] ||
6073                 error "'$cmd' wrong: found $nums, expected $expected"
6074
6075         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6076         nums=$($cmd | wc -l)
6077         expected=$((NUMFILES + 1))
6078         [ $nums -eq $expected ] ||
6079                 error "'$cmd' wrong: found $nums, expected $expected"
6080
6081         [ $skew -lt 0 ] && return
6082
6083         local after=$(do_facet mds1 date +%s)
6084         local age=$((after - before + 1 + skew))
6085
6086         cmd="$LFS find $dir -btime -${age}s -type f"
6087         nums=$($cmd | wc -l)
6088         expected=$(((NUMFILES + 1) * NUMDIRS))
6089
6090         echo "Clock skew between client and server: $skew, age:$age"
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(($NUMDIRS + 1))
6095         cmd="$LFS find $dir -btime -${age}s -type d"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099         rm -f $ref $negref || error "Failed to remove $ref $negref"
6100 }
6101 run_test 56od "check lfs find -btime with units"
6102
6103 test_56p() {
6104         [ $RUNAS_ID -eq $UID ] &&
6105                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6106
6107         local dir=$DIR/$tdir
6108
6109         setup_56 $dir $NUMFILES $NUMDIRS
6110         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6111
6112         local expected=$NUMFILES
6113         local cmd="$LFS find -uid $RUNAS_ID $dir"
6114         local nums=$($cmd | wc -l)
6115
6116         [ $nums -eq $expected ] ||
6117                 error "'$cmd' wrong: found $nums, expected $expected"
6118
6119         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6120         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6121         nums=$($cmd | wc -l)
6122         [ $nums -eq $expected ] ||
6123                 error "'$cmd' wrong: found $nums, expected $expected"
6124 }
6125 run_test 56p "check lfs find -uid and ! -uid"
6126
6127 test_56q() {
6128         [ $RUNAS_ID -eq $UID ] &&
6129                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6130
6131         local dir=$DIR/$tdir
6132
6133         setup_56 $dir $NUMFILES $NUMDIRS
6134         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6135
6136         local expected=$NUMFILES
6137         local cmd="$LFS find -gid $RUNAS_GID $dir"
6138         local nums=$($cmd | wc -l)
6139
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142
6143         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6144         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6145         nums=$($cmd | wc -l)
6146         [ $nums -eq $expected ] ||
6147                 error "'$cmd' wrong: found $nums, expected $expected"
6148 }
6149 run_test 56q "check lfs find -gid and ! -gid"
6150
6151 test_56r() {
6152         local dir=$DIR/$tdir
6153
6154         setup_56 $dir $NUMFILES $NUMDIRS
6155
6156         local expected=12
6157         local cmd="$LFS find -size 0 -type f -lazy $dir"
6158         local nums=$($cmd | wc -l)
6159
6160         [ $nums -eq $expected ] ||
6161                 error "'$cmd' wrong: found $nums, expected $expected"
6162         cmd="$LFS find -size 0 -type f $dir"
6163         nums=$($cmd | wc -l)
6164         [ $nums -eq $expected ] ||
6165                 error "'$cmd' wrong: found $nums, expected $expected"
6166
6167         expected=0
6168         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6169         nums=$($cmd | wc -l)
6170         [ $nums -eq $expected ] ||
6171                 error "'$cmd' wrong: found $nums, expected $expected"
6172         cmd="$LFS find ! -size 0 -type f $dir"
6173         nums=$($cmd | wc -l)
6174         [ $nums -eq $expected ] ||
6175                 error "'$cmd' wrong: found $nums, expected $expected"
6176
6177         echo "test" > $dir/$tfile
6178         echo "test2" > $dir/$tfile.2 && sync
6179         expected=1
6180         cmd="$LFS find -size 5 -type f -lazy $dir"
6181         nums=$($cmd | wc -l)
6182         [ $nums -eq $expected ] ||
6183                 error "'$cmd' wrong: found $nums, expected $expected"
6184         cmd="$LFS find -size 5 -type f $dir"
6185         nums=$($cmd | wc -l)
6186         [ $nums -eq $expected ] ||
6187                 error "'$cmd' wrong: found $nums, expected $expected"
6188
6189         expected=1
6190         cmd="$LFS find -size +5 -type f -lazy $dir"
6191         nums=$($cmd | wc -l)
6192         [ $nums -eq $expected ] ||
6193                 error "'$cmd' wrong: found $nums, expected $expected"
6194         cmd="$LFS find -size +5 -type f $dir"
6195         nums=$($cmd | wc -l)
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198
6199         expected=2
6200         cmd="$LFS find -size +0 -type f -lazy $dir"
6201         nums=$($cmd | wc -l)
6202         [ $nums -eq $expected ] ||
6203                 error "'$cmd' wrong: found $nums, expected $expected"
6204         cmd="$LFS find -size +0 -type f $dir"
6205         nums=$($cmd | wc -l)
6206         [ $nums -eq $expected ] ||
6207                 error "'$cmd' wrong: found $nums, expected $expected"
6208
6209         expected=2
6210         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6211         nums=$($cmd | wc -l)
6212         [ $nums -eq $expected ] ||
6213                 error "'$cmd' wrong: found $nums, expected $expected"
6214         cmd="$LFS find ! -size -5 -type f $dir"
6215         nums=$($cmd | wc -l)
6216         [ $nums -eq $expected ] ||
6217                 error "'$cmd' wrong: found $nums, expected $expected"
6218
6219         expected=12
6220         cmd="$LFS find -size -5 -type f -lazy $dir"
6221         nums=$($cmd | wc -l)
6222         [ $nums -eq $expected ] ||
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224         cmd="$LFS find -size -5 -type f $dir"
6225         nums=$($cmd | wc -l)
6226         [ $nums -eq $expected ] ||
6227                 error "'$cmd' wrong: found $nums, expected $expected"
6228 }
6229 run_test 56r "check lfs find -size works"
6230
6231 test_56ra_sub() {
6232         local expected=$1
6233         local glimpses=$2
6234         local cmd="$3"
6235
6236         cancel_lru_locks $OSC
6237
6238         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6239         local nums=$($cmd | wc -l)
6240
6241         [ $nums -eq $expected ] ||
6242                 error "'$cmd' wrong: found $nums, expected $expected"
6243
6244         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6245
6246         if (( rpcs_before + glimpses != rpcs_after )); then
6247                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6248                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6249
6250                 if [[ $glimpses == 0 ]]; then
6251                         error "'$cmd' should not send glimpse RPCs to OST"
6252                 else
6253                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6254                 fi
6255         fi
6256 }
6257
6258 test_56ra() {
6259         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6260                 skip "MDS < 2.12.58 doesn't return LSOM data"
6261         local dir=$DIR/$tdir
6262         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6263
6264         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6265
6266         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6267         $LCTL set_param -n llite.*.statahead_agl=0
6268         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6269
6270         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6271         # open and close all files to ensure LSOM is updated
6272         cancel_lru_locks $OSC
6273         find $dir -type f | xargs cat > /dev/null
6274
6275         #   expect_found  glimpse_rpcs  command_to_run
6276         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6277         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6278         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6279         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6280
6281         echo "test" > $dir/$tfile
6282         echo "test2" > $dir/$tfile.2 && sync
6283         cancel_lru_locks $OSC
6284         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6285
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         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6289         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6290
6291         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6292         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6293         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6294         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6295         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6296         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6297 }
6298 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6299
6300 test_56rb() {
6301         local dir=$DIR/$tdir
6302         local tmp=$TMP/$tfile.log
6303         local mdt_idx;
6304
6305         test_mkdir -p $dir || error "failed to mkdir $dir"
6306         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6307                 error "failed to setstripe $dir/$tfile"
6308         mdt_idx=$($LFS getdirstripe -i $dir)
6309         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6310
6311         stack_trap "rm -f $tmp" EXIT
6312         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6313         ! grep -q obd_uuid $tmp ||
6314                 error "failed to find --size +100K --ost 0 $dir"
6315         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6316         ! grep -q obd_uuid $tmp ||
6317                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6318 }
6319 run_test 56rb "check lfs find --size --ost/--mdt works"
6320
6321 test_56s() { # LU-611 #LU-9369
6322         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6323
6324         local dir=$DIR/$tdir
6325         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6326
6327         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6328         for i in $(seq $NUMDIRS); do
6329                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6330         done
6331
6332         local expected=$NUMDIRS
6333         local cmd="$LFS find -c $OSTCOUNT $dir"
6334         local nums=$($cmd | wc -l)
6335
6336         [ $nums -eq $expected ] || {
6337                 $LFS getstripe -R $dir
6338                 error "'$cmd' wrong: found $nums, expected $expected"
6339         }
6340
6341         expected=$((NUMDIRS + onestripe))
6342         cmd="$LFS find -stripe-count +0 -type f $dir"
6343         nums=$($cmd | wc -l)
6344         [ $nums -eq $expected ] || {
6345                 $LFS getstripe -R $dir
6346                 error "'$cmd' wrong: found $nums, expected $expected"
6347         }
6348
6349         expected=$onestripe
6350         cmd="$LFS find -stripe-count 1 -type f $dir"
6351         nums=$($cmd | wc -l)
6352         [ $nums -eq $expected ] || {
6353                 $LFS getstripe -R $dir
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355         }
6356
6357         cmd="$LFS find -stripe-count -2 -type f $dir"
6358         nums=$($cmd | wc -l)
6359         [ $nums -eq $expected ] || {
6360                 $LFS getstripe -R $dir
6361                 error "'$cmd' wrong: found $nums, expected $expected"
6362         }
6363
6364         expected=0
6365         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6366         nums=$($cmd | wc -l)
6367         [ $nums -eq $expected ] || {
6368                 $LFS getstripe -R $dir
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370         }
6371 }
6372 run_test 56s "check lfs find -stripe-count works"
6373
6374 test_56t() { # LU-611 #LU-9369
6375         local dir=$DIR/$tdir
6376
6377         setup_56 $dir 0 $NUMDIRS
6378         for i in $(seq $NUMDIRS); do
6379                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6380         done
6381
6382         local expected=$NUMDIRS
6383         local cmd="$LFS find -S 8M $dir"
6384         local nums=$($cmd | wc -l)
6385
6386         [ $nums -eq $expected ] || {
6387                 $LFS getstripe -R $dir
6388                 error "'$cmd' wrong: found $nums, expected $expected"
6389         }
6390         rm -rf $dir
6391
6392         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6393
6394         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6395
6396         expected=$(((NUMDIRS + 1) * NUMFILES))
6397         cmd="$LFS find -stripe-size 512k -type f $dir"
6398         nums=$($cmd | wc -l)
6399         [ $nums -eq $expected ] ||
6400                 error "'$cmd' wrong: found $nums, expected $expected"
6401
6402         cmd="$LFS find -stripe-size +320k -type f $dir"
6403         nums=$($cmd | wc -l)
6404         [ $nums -eq $expected ] ||
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406
6407         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6408         cmd="$LFS find -stripe-size +200k -type f $dir"
6409         nums=$($cmd | wc -l)
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412
6413         cmd="$LFS find -stripe-size -640k -type f $dir"
6414         nums=$($cmd | wc -l)
6415         [ $nums -eq $expected ] ||
6416                 error "'$cmd' wrong: found $nums, expected $expected"
6417
6418         expected=4
6419         cmd="$LFS find -stripe-size 256k -type f $dir"
6420         nums=$($cmd | wc -l)
6421         [ $nums -eq $expected ] ||
6422                 error "'$cmd' wrong: found $nums, expected $expected"
6423
6424         cmd="$LFS find -stripe-size -320k -type f $dir"
6425         nums=$($cmd | wc -l)
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         expected=0
6430         cmd="$LFS find -stripe-size 1024k -type f $dir"
6431         nums=$($cmd | wc -l)
6432         [ $nums -eq $expected ] ||
6433                 error "'$cmd' wrong: found $nums, expected $expected"
6434 }
6435 run_test 56t "check lfs find -stripe-size works"
6436
6437 test_56u() { # LU-611
6438         local dir=$DIR/$tdir
6439
6440         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6441
6442         if [[ $OSTCOUNT -gt 1 ]]; then
6443                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6444                 onestripe=4
6445         else
6446                 onestripe=0
6447         fi
6448
6449         local expected=$(((NUMDIRS + 1) * NUMFILES))
6450         local cmd="$LFS find -stripe-index 0 -type f $dir"
6451         local nums=$($cmd | wc -l)
6452
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         expected=$onestripe
6457         cmd="$LFS find -stripe-index 1 -type f $dir"
6458         nums=$($cmd | wc -l)
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461
6462         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6463         nums=$($cmd | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         expected=0
6468         # This should produce an error and not return any files
6469         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6470         nums=$($cmd 2>/dev/null | wc -l)
6471         [ $nums -eq $expected ] ||
6472                 error "'$cmd' wrong: found $nums, expected $expected"
6473
6474         if [[ $OSTCOUNT -gt 1 ]]; then
6475                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6476                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6477                 nums=$($cmd | wc -l)
6478                 [ $nums -eq $expected ] ||
6479                         error "'$cmd' wrong: found $nums, expected $expected"
6480         fi
6481 }
6482 run_test 56u "check lfs find -stripe-index works"
6483
6484 test_56v() {
6485         local mdt_idx=0
6486         local dir=$DIR/$tdir
6487
6488         setup_56 $dir $NUMFILES $NUMDIRS
6489
6490         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6491         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6492
6493         for file in $($LFS find -m $UUID $dir); do
6494                 file_midx=$($LFS getstripe -m $file)
6495                 [ $file_midx -eq $mdt_idx ] ||
6496                         error "lfs find -m $UUID != getstripe -m $file_midx"
6497         done
6498 }
6499 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6500
6501 test_56w() {
6502         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6504
6505         local dir=$DIR/$tdir
6506
6507         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6508
6509         local stripe_size=$($LFS getstripe -S -d $dir) ||
6510                 error "$LFS getstripe -S -d $dir failed"
6511         stripe_size=${stripe_size%% *}
6512
6513         local file_size=$((stripe_size * OSTCOUNT))
6514         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6515         local required_space=$((file_num * file_size))
6516         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6517                            head -n1)
6518         [[ $free_space -le $((required_space / 1024)) ]] &&
6519                 skip_env "need $required_space, have $free_space kbytes"
6520
6521         local dd_bs=65536
6522         local dd_count=$((file_size / dd_bs))
6523
6524         # write data into the files
6525         local i
6526         local j
6527         local file
6528
6529         for i in $(seq $NUMFILES); do
6530                 file=$dir/file$i
6531                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6532                         error "write data into $file failed"
6533         done
6534         for i in $(seq $NUMDIRS); do
6535                 for j in $(seq $NUMFILES); do
6536                         file=$dir/dir$i/file$j
6537                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6538                                 error "write data into $file failed"
6539                 done
6540         done
6541
6542         # $LFS_MIGRATE will fail if hard link migration is unsupported
6543         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6544                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6545                         error "creating links to $dir/dir1/file1 failed"
6546         fi
6547
6548         local expected=-1
6549
6550         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6551
6552         # lfs_migrate file
6553         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6554
6555         echo "$cmd"
6556         eval $cmd || error "$cmd failed"
6557
6558         check_stripe_count $dir/file1 $expected
6559
6560         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6561         then
6562                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6563                 # OST 1 if it is on OST 0. This file is small enough to
6564                 # be on only one stripe.
6565                 file=$dir/migr_1_ost
6566                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6567                         error "write data into $file failed"
6568                 local obdidx=$($LFS getstripe -i $file)
6569                 local oldmd5=$(md5sum $file)
6570                 local newobdidx=0
6571
6572                 [[ $obdidx -eq 0 ]] && newobdidx=1
6573                 cmd="$LFS migrate -i $newobdidx $file"
6574                 echo $cmd
6575                 eval $cmd || error "$cmd failed"
6576
6577                 local realobdix=$($LFS getstripe -i $file)
6578                 local newmd5=$(md5sum $file)
6579
6580                 [[ $newobdidx -ne $realobdix ]] &&
6581                         error "new OST is different (was=$obdidx, "\
6582                               "wanted=$newobdidx, got=$realobdix)"
6583                 [[ "$oldmd5" != "$newmd5" ]] &&
6584                         error "md5sum differ: $oldmd5, $newmd5"
6585         fi
6586
6587         # lfs_migrate dir
6588         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6589         echo "$cmd"
6590         eval $cmd || error "$cmd failed"
6591
6592         for j in $(seq $NUMFILES); do
6593                 check_stripe_count $dir/dir1/file$j $expected
6594         done
6595
6596         # lfs_migrate works with lfs find
6597         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6598              $LFS_MIGRATE -y -c $expected"
6599         echo "$cmd"
6600         eval $cmd || error "$cmd failed"
6601
6602         for i in $(seq 2 $NUMFILES); do
6603                 check_stripe_count $dir/file$i $expected
6604         done
6605         for i in $(seq 2 $NUMDIRS); do
6606                 for j in $(seq $NUMFILES); do
6607                 check_stripe_count $dir/dir$i/file$j $expected
6608                 done
6609         done
6610 }
6611 run_test 56w "check lfs_migrate -c stripe_count works"
6612
6613 test_56wb() {
6614         local file1=$DIR/$tdir/file1
6615         local create_pool=false
6616         local initial_pool=$($LFS getstripe -p $DIR)
6617         local pool_list=()
6618         local pool=""
6619
6620         echo -n "Creating test dir..."
6621         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6622         echo "done."
6623
6624         echo -n "Creating test file..."
6625         touch $file1 || error "cannot create file"
6626         echo "done."
6627
6628         echo -n "Detecting existing pools..."
6629         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6630
6631         if [ ${#pool_list[@]} -gt 0 ]; then
6632                 echo "${pool_list[@]}"
6633                 for thispool in "${pool_list[@]}"; do
6634                         if [[ -z "$initial_pool" ||
6635                               "$initial_pool" != "$thispool" ]]; then
6636                                 pool="$thispool"
6637                                 echo "Using existing pool '$pool'"
6638                                 break
6639                         fi
6640                 done
6641         else
6642                 echo "none detected."
6643         fi
6644         if [ -z "$pool" ]; then
6645                 pool=${POOL:-testpool}
6646                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6647                 echo -n "Creating pool '$pool'..."
6648                 create_pool=true
6649                 pool_add $pool &> /dev/null ||
6650                         error "pool_add failed"
6651                 echo "done."
6652
6653                 echo -n "Adding target to pool..."
6654                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6655                         error "pool_add_targets failed"
6656                 echo "done."
6657         fi
6658
6659         echo -n "Setting pool using -p option..."
6660         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6661                 error "migrate failed rc = $?"
6662         echo "done."
6663
6664         echo -n "Verifying test file is in pool after migrating..."
6665         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6666                 error "file was not migrated to pool $pool"
6667         echo "done."
6668
6669         echo -n "Removing test file from pool '$pool'..."
6670         # "lfs migrate $file" won't remove the file from the pool
6671         # until some striping information is changed.
6672         $LFS migrate -c 1 $file1 &> /dev/null ||
6673                 error "cannot remove from pool"
6674         [ "$($LFS getstripe -p $file1)" ] &&
6675                 error "pool still set"
6676         echo "done."
6677
6678         echo -n "Setting pool using --pool option..."
6679         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6680                 error "migrate failed rc = $?"
6681         echo "done."
6682
6683         # Clean up
6684         rm -f $file1
6685         if $create_pool; then
6686                 destroy_test_pools 2> /dev/null ||
6687                         error "destroy test pools failed"
6688         fi
6689 }
6690 run_test 56wb "check lfs_migrate pool support"
6691
6692 test_56wc() {
6693         local file1="$DIR/$tdir/file1"
6694         local parent_ssize
6695         local parent_scount
6696         local cur_ssize
6697         local cur_scount
6698         local orig_ssize
6699
6700         echo -n "Creating test dir..."
6701         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6702         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6703                 error "cannot set stripe by '-S 1M -c 1'"
6704         echo "done"
6705
6706         echo -n "Setting initial stripe for test file..."
6707         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6708                 error "cannot set stripe"
6709         cur_ssize=$($LFS getstripe -S "$file1")
6710         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6711         echo "done."
6712
6713         # File currently set to -S 512K -c 1
6714
6715         # Ensure -c and -S options are rejected when -R is set
6716         echo -n "Verifying incompatible options are detected..."
6717         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6718                 error "incompatible -c and -R options not detected"
6719         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6720                 error "incompatible -S and -R options not detected"
6721         echo "done."
6722
6723         # Ensure unrecognized options are passed through to 'lfs migrate'
6724         echo -n "Verifying -S option is passed through to lfs migrate..."
6725         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6726                 error "migration failed"
6727         cur_ssize=$($LFS getstripe -S "$file1")
6728         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6729         echo "done."
6730
6731         # File currently set to -S 1M -c 1
6732
6733         # Ensure long options are supported
6734         echo -n "Verifying long options supported..."
6735         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6736                 error "long option without argument not supported"
6737         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6738                 error "long option with argument not supported"
6739         cur_ssize=$($LFS getstripe -S "$file1")
6740         [ $cur_ssize -eq 524288 ] ||
6741                 error "migrate --stripe-size $cur_ssize != 524288"
6742         echo "done."
6743
6744         # File currently set to -S 512K -c 1
6745
6746         if [ "$OSTCOUNT" -gt 1 ]; then
6747                 echo -n "Verifying explicit stripe count can be set..."
6748                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6749                         error "migrate failed"
6750                 cur_scount=$($LFS getstripe -c "$file1")
6751                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6752                 echo "done."
6753         fi
6754
6755         # File currently set to -S 512K -c 1 or -S 512K -c 2
6756
6757         # Ensure parent striping is used if -R is set, and no stripe
6758         # count or size is specified
6759         echo -n "Setting stripe for parent directory..."
6760         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6761                 error "cannot set stripe '-S 2M -c 1'"
6762         echo "done."
6763
6764         echo -n "Verifying restripe option uses parent stripe settings..."
6765         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6766         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6767         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6768                 error "migrate failed"
6769         cur_ssize=$($LFS getstripe -S "$file1")
6770         [ $cur_ssize -eq $parent_ssize ] ||
6771                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6772         cur_scount=$($LFS getstripe -c "$file1")
6773         [ $cur_scount -eq $parent_scount ] ||
6774                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6775         echo "done."
6776
6777         # File currently set to -S 1M -c 1
6778
6779         # Ensure striping is preserved if -R is not set, and no stripe
6780         # count or size is specified
6781         echo -n "Verifying striping size preserved when not specified..."
6782         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6783         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6784                 error "cannot set stripe on parent directory"
6785         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6786                 error "migrate failed"
6787         cur_ssize=$($LFS getstripe -S "$file1")
6788         [ $cur_ssize -eq $orig_ssize ] ||
6789                 error "migrate by default $cur_ssize != $orig_ssize"
6790         echo "done."
6791
6792         # Ensure file name properly detected when final option has no argument
6793         echo -n "Verifying file name properly detected..."
6794         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6795                 error "file name interpreted as option argument"
6796         echo "done."
6797
6798         # Clean up
6799         rm -f "$file1"
6800 }
6801 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6802
6803 test_56wd() {
6804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6805
6806         local file1=$DIR/$tdir/file1
6807
6808         echo -n "Creating test dir..."
6809         test_mkdir $DIR/$tdir || error "cannot create dir"
6810         echo "done."
6811
6812         echo -n "Creating test file..."
6813         touch $file1
6814         echo "done."
6815
6816         # Ensure 'lfs migrate' will fail by using a non-existent option,
6817         # and make sure rsync is not called to recover
6818         echo -n "Make sure --no-rsync option works..."
6819         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6820                 grep -q 'refusing to fall back to rsync' ||
6821                 error "rsync was called with --no-rsync set"
6822         echo "done."
6823
6824         # Ensure rsync is called without trying 'lfs migrate' first
6825         echo -n "Make sure --rsync option works..."
6826         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6827                 grep -q 'falling back to rsync' &&
6828                 error "lfs migrate was called with --rsync set"
6829         echo "done."
6830
6831         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6832         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6833                 grep -q 'at the same time' ||
6834                 error "--rsync and --no-rsync accepted concurrently"
6835         echo "done."
6836
6837         # Clean up
6838         rm -f $file1
6839 }
6840 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6841
6842 test_56we() {
6843         local td=$DIR/$tdir
6844         local tf=$td/$tfile
6845
6846         test_mkdir $td || error "cannot create $td"
6847         touch $tf || error "cannot touch $tf"
6848
6849         echo -n "Make sure --non-direct|-D works..."
6850         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6851                 grep -q "lfs migrate --non-direct" ||
6852                 error "--non-direct option cannot work correctly"
6853         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6854                 grep -q "lfs migrate -D" ||
6855                 error "-D option cannot work correctly"
6856         echo "done."
6857 }
6858 run_test 56we "check lfs_migrate --non-direct|-D support"
6859
6860 test_56x() {
6861         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6862         check_swap_layouts_support
6863
6864         local dir=$DIR/$tdir
6865         local ref1=/etc/passwd
6866         local file1=$dir/file1
6867
6868         test_mkdir $dir || error "creating dir $dir"
6869         $LFS setstripe -c 2 $file1
6870         cp $ref1 $file1
6871         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6872         stripe=$($LFS getstripe -c $file1)
6873         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6874         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6875
6876         # clean up
6877         rm -f $file1
6878 }
6879 run_test 56x "lfs migration support"
6880
6881 test_56xa() {
6882         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6883         check_swap_layouts_support
6884
6885         local dir=$DIR/$tdir/$testnum
6886
6887         test_mkdir -p $dir
6888
6889         local ref1=/etc/passwd
6890         local file1=$dir/file1
6891
6892         $LFS setstripe -c 2 $file1
6893         cp $ref1 $file1
6894         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6895
6896         local stripe=$($LFS getstripe -c $file1)
6897
6898         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6899         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6900
6901         # clean up
6902         rm -f $file1
6903 }
6904 run_test 56xa "lfs migration --block support"
6905
6906 check_migrate_links() {
6907         local dir="$1"
6908         local file1="$dir/file1"
6909         local begin="$2"
6910         local count="$3"
6911         local runas="$4"
6912         local total_count=$(($begin + $count - 1))
6913         local symlink_count=10
6914         local uniq_count=10
6915
6916         if [ ! -f "$file1" ]; then
6917                 echo -n "creating initial file..."
6918                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6919                         error "cannot setstripe initial file"
6920                 echo "done"
6921
6922                 echo -n "creating symlinks..."
6923                 for s in $(seq 1 $symlink_count); do
6924                         ln -s "$file1" "$dir/slink$s" ||
6925                                 error "cannot create symlinks"
6926                 done
6927                 echo "done"
6928
6929                 echo -n "creating nonlinked files..."
6930                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6931                         error "cannot create nonlinked files"
6932                 echo "done"
6933         fi
6934
6935         # create hard links
6936         if [ ! -f "$dir/file$total_count" ]; then
6937                 echo -n "creating hard links $begin:$total_count..."
6938                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6939                         /dev/null || error "cannot create hard links"
6940                 echo "done"
6941         fi
6942
6943         echo -n "checking number of hard links listed in xattrs..."
6944         local fid=$($LFS getstripe -F "$file1")
6945         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6946
6947         echo "${#paths[*]}"
6948         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6949                         skip "hard link list has unexpected size, skipping test"
6950         fi
6951         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6952                         error "link names should exceed xattrs size"
6953         fi
6954
6955         echo -n "migrating files..."
6956         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6957         local rc=$?
6958         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6959         echo "done"
6960
6961         # make sure all links have been properly migrated
6962         echo -n "verifying files..."
6963         fid=$($LFS getstripe -F "$file1") ||
6964                 error "cannot get fid for file $file1"
6965         for i in $(seq 2 $total_count); do
6966                 local fid2=$($LFS getstripe -F $dir/file$i)
6967
6968                 [ "$fid2" == "$fid" ] ||
6969                         error "migrated hard link has mismatched FID"
6970         done
6971
6972         # make sure hard links were properly detected, and migration was
6973         # performed only once for the entire link set; nonlinked files should
6974         # also be migrated
6975         local actual=$(grep -c 'done' <<< "$migrate_out")
6976         local expected=$(($uniq_count + 1))
6977
6978         [ "$actual" -eq  "$expected" ] ||
6979                 error "hard links individually migrated ($actual != $expected)"
6980
6981         # make sure the correct number of hard links are present
6982         local hardlinks=$(stat -c '%h' "$file1")
6983
6984         [ $hardlinks -eq $total_count ] ||
6985                 error "num hard links $hardlinks != $total_count"
6986         echo "done"
6987
6988         return 0
6989 }
6990
6991 test_56xb() {
6992         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6993                 skip "Need MDS version at least 2.10.55"
6994
6995         local dir="$DIR/$tdir"
6996
6997         test_mkdir "$dir" || error "cannot create dir $dir"
6998
6999         echo "testing lfs migrate mode when all links fit within xattrs"
7000         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7001
7002         echo "testing rsync mode when all links fit within xattrs"
7003         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7004
7005         echo "testing lfs migrate mode when all links do not fit within xattrs"
7006         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7007
7008         echo "testing rsync mode when all links do not fit within xattrs"
7009         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7010
7011         chown -R $RUNAS_ID $dir
7012         echo "testing non-root lfs migrate mode when not all links are in xattr"
7013         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7014
7015         # clean up
7016         rm -rf $dir
7017 }
7018 run_test 56xb "lfs migration hard link support"
7019
7020 test_56xc() {
7021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7022
7023         local dir="$DIR/$tdir"
7024
7025         test_mkdir "$dir" || error "cannot create dir $dir"
7026
7027         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7028         echo -n "Setting initial stripe for 20MB test file..."
7029         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7030                 error "cannot setstripe 20MB file"
7031         echo "done"
7032         echo -n "Sizing 20MB test file..."
7033         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7034         echo "done"
7035         echo -n "Verifying small file autostripe count is 1..."
7036         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7037                 error "cannot migrate 20MB file"
7038         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7039                 error "cannot get stripe for $dir/20mb"
7040         [ $stripe_count -eq 1 ] ||
7041                 error "unexpected stripe count $stripe_count for 20MB file"
7042         rm -f "$dir/20mb"
7043         echo "done"
7044
7045         # Test 2: File is small enough to fit within the available space on
7046         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7047         # have at least an additional 1KB for each desired stripe for test 3
7048         echo -n "Setting stripe for 1GB test file..."
7049         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7050         echo "done"
7051         echo -n "Sizing 1GB test file..."
7052         # File size is 1GB + 3KB
7053         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7054         echo "done"
7055
7056         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7057         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7058         if (( avail > 524288 * OSTCOUNT )); then
7059                 echo -n "Migrating 1GB file..."
7060                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7061                         error "cannot migrate 1GB file"
7062                 echo "done"
7063                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7064                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7065                         error "cannot getstripe for 1GB file"
7066                 [ $stripe_count -eq 2 ] ||
7067                         error "unexpected stripe count $stripe_count != 2"
7068                 echo "done"
7069         fi
7070
7071         # Test 3: File is too large to fit within the available space on
7072         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7073         if [ $OSTCOUNT -ge 3 ]; then
7074                 # The required available space is calculated as
7075                 # file size (1GB + 3KB) / OST count (3).
7076                 local kb_per_ost=349526
7077
7078                 echo -n "Migrating 1GB file with limit..."
7079                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7080                         error "cannot migrate 1GB file with limit"
7081                 echo "done"
7082
7083                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7084                 echo -n "Verifying 1GB autostripe count with limited space..."
7085                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7086                         error "unexpected stripe count $stripe_count (min 3)"
7087                 echo "done"
7088         fi
7089
7090         # clean up
7091         rm -rf $dir
7092 }
7093 run_test 56xc "lfs migration autostripe"
7094
7095 test_56xd() {
7096         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7097
7098         local dir=$DIR/$tdir
7099         local f_mgrt=$dir/$tfile.mgrt
7100         local f_yaml=$dir/$tfile.yaml
7101         local f_copy=$dir/$tfile.copy
7102         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7103         local layout_copy="-c 2 -S 2M -i 1"
7104         local yamlfile=$dir/yamlfile
7105         local layout_before;
7106         local layout_after;
7107
7108         test_mkdir "$dir" || error "cannot create dir $dir"
7109         $LFS setstripe $layout_yaml $f_yaml ||
7110                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7111         $LFS getstripe --yaml $f_yaml > $yamlfile
7112         $LFS setstripe $layout_copy $f_copy ||
7113                 error "cannot setstripe $f_copy with layout $layout_copy"
7114         touch $f_mgrt
7115         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7116
7117         # 1. test option --yaml
7118         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7119                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7120         layout_before=$(get_layout_param $f_yaml)
7121         layout_after=$(get_layout_param $f_mgrt)
7122         [ "$layout_after" == "$layout_before" ] ||
7123                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7124
7125         # 2. test option --copy
7126         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7127                 error "cannot migrate $f_mgrt with --copy $f_copy"
7128         layout_before=$(get_layout_param $f_copy)
7129         layout_after=$(get_layout_param $f_mgrt)
7130         [ "$layout_after" == "$layout_before" ] ||
7131                 error "lfs_migrate --copy: $layout_after != $layout_before"
7132 }
7133 run_test 56xd "check lfs_migrate --yaml and --copy support"
7134
7135 test_56xe() {
7136         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7137
7138         local dir=$DIR/$tdir
7139         local f_comp=$dir/$tfile
7140         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7141         local layout_before=""
7142         local layout_after=""
7143
7144         test_mkdir "$dir" || error "cannot create dir $dir"
7145         $LFS setstripe $layout $f_comp ||
7146                 error "cannot setstripe $f_comp with layout $layout"
7147         layout_before=$(get_layout_param $f_comp)
7148         dd if=/dev/zero of=$f_comp bs=1M count=4
7149
7150         # 1. migrate a comp layout file by lfs_migrate
7151         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7152         layout_after=$(get_layout_param $f_comp)
7153         [ "$layout_before" == "$layout_after" ] ||
7154                 error "lfs_migrate: $layout_before != $layout_after"
7155
7156         # 2. migrate a comp layout file by lfs migrate
7157         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7158         layout_after=$(get_layout_param $f_comp)
7159         [ "$layout_before" == "$layout_after" ] ||
7160                 error "lfs migrate: $layout_before != $layout_after"
7161 }
7162 run_test 56xe "migrate a composite layout file"
7163
7164 test_56xf() {
7165         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7166
7167         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7168                 skip "Need server version at least 2.13.53"
7169
7170         local dir=$DIR/$tdir
7171         local f_comp=$dir/$tfile
7172         local layout="-E 1M -c1 -E -1 -c2"
7173         local fid_before=""
7174         local fid_after=""
7175
7176         test_mkdir "$dir" || error "cannot create dir $dir"
7177         $LFS setstripe $layout $f_comp ||
7178                 error "cannot setstripe $f_comp with layout $layout"
7179         fid_before=$($LFS getstripe --fid $f_comp)
7180         dd if=/dev/zero of=$f_comp bs=1M count=4
7181
7182         # 1. migrate a comp layout file to a comp layout
7183         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7184         fid_after=$($LFS getstripe --fid $f_comp)
7185         [ "$fid_before" == "$fid_after" ] ||
7186                 error "comp-to-comp migrate: $fid_before != $fid_after"
7187
7188         # 2. migrate a comp layout file to a plain layout
7189         $LFS migrate -c2 $f_comp ||
7190                 error "cannot migrate $f_comp by lfs migrate"
7191         fid_after=$($LFS getstripe --fid $f_comp)
7192         [ "$fid_before" == "$fid_after" ] ||
7193                 error "comp-to-plain migrate: $fid_before != $fid_after"
7194
7195         # 3. migrate a plain layout file to a comp layout
7196         $LFS migrate $layout $f_comp ||
7197                 error "cannot migrate $f_comp by lfs migrate"
7198         fid_after=$($LFS getstripe --fid $f_comp)
7199         [ "$fid_before" == "$fid_after" ] ||
7200                 error "plain-to-comp migrate: $fid_before != $fid_after"
7201 }
7202 run_test 56xf "FID is not lost during migration of a composite layout file"
7203
7204 test_56y() {
7205         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7206                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7207
7208         local res=""
7209         local dir=$DIR/$tdir
7210         local f1=$dir/file1
7211         local f2=$dir/file2
7212
7213         test_mkdir -p $dir || error "creating dir $dir"
7214         touch $f1 || error "creating std file $f1"
7215         $MULTIOP $f2 H2c || error "creating released file $f2"
7216
7217         # a directory can be raid0, so ask only for files
7218         res=$($LFS find $dir -L raid0 -type f | wc -l)
7219         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7220
7221         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7222         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7223
7224         # only files can be released, so no need to force file search
7225         res=$($LFS find $dir -L released)
7226         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7227
7228         res=$($LFS find $dir -type f \! -L released)
7229         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7230 }
7231 run_test 56y "lfs find -L raid0|released"
7232
7233 test_56z() { # LU-4824
7234         # This checks to make sure 'lfs find' continues after errors
7235         # There are two classes of errors that should be caught:
7236         # - If multiple paths are provided, all should be searched even if one
7237         #   errors out
7238         # - If errors are encountered during the search, it should not terminate
7239         #   early
7240         local dir=$DIR/$tdir
7241         local i
7242
7243         test_mkdir $dir
7244         for i in d{0..9}; do
7245                 test_mkdir $dir/$i
7246                 touch $dir/$i/$tfile
7247         done
7248         $LFS find $DIR/non_existent_dir $dir &&
7249                 error "$LFS find did not return an error"
7250         # Make a directory unsearchable. This should NOT be the last entry in
7251         # directory order.  Arbitrarily pick the 6th entry
7252         chmod 700 $($LFS find $dir -type d | sed '6!d')
7253
7254         $RUNAS $LFS find $DIR/non_existent $dir
7255         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7256
7257         # The user should be able to see 10 directories and 9 files
7258         (( count == 19 )) ||
7259                 error "$LFS find found $count != 19 entries after error"
7260 }
7261 run_test 56z "lfs find should continue after an error"
7262
7263 test_56aa() { # LU-5937
7264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7265
7266         local dir=$DIR/$tdir
7267
7268         mkdir $dir
7269         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7270
7271         createmany -o $dir/striped_dir/${tfile}- 1024
7272         local dirs=$($LFS find --size +8k $dir/)
7273
7274         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7275 }
7276 run_test 56aa "lfs find --size under striped dir"
7277
7278 test_56ab() { # LU-10705
7279         test_mkdir $DIR/$tdir
7280         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7281         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7282         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7283         # Flush writes to ensure valid blocks.  Need to be more thorough for
7284         # ZFS, since blocks are not allocated/returned to client immediately.
7285         sync_all_data
7286         wait_zfs_commit ost1 2
7287         cancel_lru_locks osc
7288         ls -ls $DIR/$tdir
7289
7290         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7291
7292         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7293
7294         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7295         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7296
7297         rm -f $DIR/$tdir/$tfile.[123]
7298 }
7299 run_test 56ab "lfs find --blocks"
7300
7301 test_56ba() {
7302         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7303                 skip "Need MDS version at least 2.10.50"
7304
7305         # Create composite files with one component
7306         local dir=$DIR/$tdir
7307
7308         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7309         # Create composite files with three components
7310         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7311         # Create non-composite files
7312         createmany -o $dir/${tfile}- 10
7313
7314         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7315
7316         [[ $nfiles == 10 ]] ||
7317                 error "lfs find -E 1M found $nfiles != 10 files"
7318
7319         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7320         [[ $nfiles == 25 ]] ||
7321                 error "lfs find ! -E 1M found $nfiles != 25 files"
7322
7323         # All files have a component that starts at 0
7324         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7325         [[ $nfiles == 35 ]] ||
7326                 error "lfs find --component-start 0 - $nfiles != 35 files"
7327
7328         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7329         [[ $nfiles == 15 ]] ||
7330                 error "lfs find --component-start 2M - $nfiles != 15 files"
7331
7332         # All files created here have a componenet that does not starts at 2M
7333         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7334         [[ $nfiles == 35 ]] ||
7335                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7336
7337         # Find files with a specified number of components
7338         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7339         [[ $nfiles == 15 ]] ||
7340                 error "lfs find --component-count 3 - $nfiles != 15 files"
7341
7342         # Remember non-composite files have a component count of zero
7343         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7344         [[ $nfiles == 10 ]] ||
7345                 error "lfs find --component-count 0 - $nfiles != 10 files"
7346
7347         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7348         [[ $nfiles == 20 ]] ||
7349                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7350
7351         # All files have a flag called "init"
7352         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7353         [[ $nfiles == 35 ]] ||
7354                 error "lfs find --component-flags init - $nfiles != 35 files"
7355
7356         # Multi-component files will have a component not initialized
7357         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7358         [[ $nfiles == 15 ]] ||
7359                 error "lfs find !--component-flags init - $nfiles != 15 files"
7360
7361         rm -rf $dir
7362
7363 }
7364 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7365
7366 test_56ca() {
7367         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7368                 skip "Need MDS version at least 2.10.57"
7369
7370         local td=$DIR/$tdir
7371         local tf=$td/$tfile
7372         local dir
7373         local nfiles
7374         local cmd
7375         local i
7376         local j
7377
7378         # create mirrored directories and mirrored files
7379         mkdir $td || error "mkdir $td failed"
7380         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7381         createmany -o $tf- 10 || error "create $tf- failed"
7382
7383         for i in $(seq 2); do
7384                 dir=$td/dir$i
7385                 mkdir $dir || error "mkdir $dir failed"
7386                 $LFS mirror create -N$((3 + i)) $dir ||
7387                         error "create mirrored dir $dir failed"
7388                 createmany -o $dir/$tfile- 10 ||
7389                         error "create $dir/$tfile- failed"
7390         done
7391
7392         # change the states of some mirrored files
7393         echo foo > $tf-6
7394         for i in $(seq 2); do
7395                 dir=$td/dir$i
7396                 for j in $(seq 4 9); do
7397                         echo foo > $dir/$tfile-$j
7398                 done
7399         done
7400
7401         # find mirrored files with specific mirror count
7402         cmd="$LFS find --mirror-count 3 --type f $td"
7403         nfiles=$($cmd | wc -l)
7404         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7405
7406         cmd="$LFS find ! --mirror-count 3 --type f $td"
7407         nfiles=$($cmd | wc -l)
7408         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7409
7410         cmd="$LFS find --mirror-count +2 --type f $td"
7411         nfiles=$($cmd | wc -l)
7412         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7413
7414         cmd="$LFS find --mirror-count -6 --type f $td"
7415         nfiles=$($cmd | wc -l)
7416         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7417
7418         # find mirrored files with specific file state
7419         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7420         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7421
7422         cmd="$LFS find --mirror-state=ro --type f $td"
7423         nfiles=$($cmd | wc -l)
7424         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7425
7426         cmd="$LFS find ! --mirror-state=ro --type f $td"
7427         nfiles=$($cmd | wc -l)
7428         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7429
7430         cmd="$LFS find --mirror-state=wp --type f $td"
7431         nfiles=$($cmd | wc -l)
7432         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7433
7434         cmd="$LFS find ! --mirror-state=sp --type f $td"
7435         nfiles=$($cmd | wc -l)
7436         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7437 }
7438 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7439
7440 test_57a() {
7441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7442         # note test will not do anything if MDS is not local
7443         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7444                 skip_env "ldiskfs only test"
7445         fi
7446         remote_mds_nodsh && skip "remote MDS with nodsh"
7447
7448         local MNTDEV="osd*.*MDT*.mntdev"
7449         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7450         [ -z "$DEV" ] && error "can't access $MNTDEV"
7451         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7452                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7453                         error "can't access $DEV"
7454                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7455                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7456                 rm $TMP/t57a.dump
7457         done
7458 }
7459 run_test 57a "verify MDS filesystem created with large inodes =="
7460
7461 test_57b() {
7462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7463         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7464                 skip_env "ldiskfs only test"
7465         fi
7466         remote_mds_nodsh && skip "remote MDS with nodsh"
7467
7468         local dir=$DIR/$tdir
7469         local filecount=100
7470         local file1=$dir/f1
7471         local fileN=$dir/f$filecount
7472
7473         rm -rf $dir || error "removing $dir"
7474         test_mkdir -c1 $dir
7475         local mdtidx=$($LFS getstripe -m $dir)
7476         local mdtname=MDT$(printf %04x $mdtidx)
7477         local facet=mds$((mdtidx + 1))
7478
7479         echo "mcreating $filecount files"
7480         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7481
7482         # verify that files do not have EAs yet
7483         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7484                 error "$file1 has an EA"
7485         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7486                 error "$fileN has an EA"
7487
7488         sync
7489         sleep 1
7490         df $dir  #make sure we get new statfs data
7491         local mdsfree=$(do_facet $facet \
7492                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7493         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7494         local file
7495
7496         echo "opening files to create objects/EAs"
7497         for file in $(seq -f $dir/f%g 1 $filecount); do
7498                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7499                         error "opening $file"
7500         done
7501
7502         # verify that files have EAs now
7503         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7504         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7505
7506         sleep 1  #make sure we get new statfs data
7507         df $dir
7508         local mdsfree2=$(do_facet $facet \
7509                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7510         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7511
7512         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7513                 if [ "$mdsfree" != "$mdsfree2" ]; then
7514                         error "MDC before $mdcfree != after $mdcfree2"
7515                 else
7516                         echo "MDC before $mdcfree != after $mdcfree2"
7517                         echo "unable to confirm if MDS has large inodes"
7518                 fi
7519         fi
7520         rm -rf $dir
7521 }
7522 run_test 57b "default LOV EAs are stored inside large inodes ==="
7523
7524 test_58() {
7525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7526         [ -z "$(which wiretest 2>/dev/null)" ] &&
7527                         skip_env "could not find wiretest"
7528
7529         wiretest
7530 }
7531 run_test 58 "verify cross-platform wire constants =============="
7532
7533 test_59() {
7534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7535
7536         echo "touch 130 files"
7537         createmany -o $DIR/f59- 130
7538         echo "rm 130 files"
7539         unlinkmany $DIR/f59- 130
7540         sync
7541         # wait for commitment of removal
7542         wait_delete_completed
7543 }
7544 run_test 59 "verify cancellation of llog records async ========="
7545
7546 TEST60_HEAD="test_60 run $RANDOM"
7547 test_60a() {
7548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7549         remote_mgs_nodsh && skip "remote MGS with nodsh"
7550         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7551                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7552                         skip_env "missing subtest run-llog.sh"
7553
7554         log "$TEST60_HEAD - from kernel mode"
7555         do_facet mgs "$LCTL dk > /dev/null"
7556         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7557         do_facet mgs $LCTL dk > $TMP/$tfile
7558
7559         # LU-6388: test llog_reader
7560         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7561         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7562         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7563                         skip_env "missing llog_reader"
7564         local fstype=$(facet_fstype mgs)
7565         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7566                 skip_env "Only for ldiskfs or zfs type mgs"
7567
7568         local mntpt=$(facet_mntpt mgs)
7569         local mgsdev=$(mgsdevname 1)
7570         local fid_list
7571         local fid
7572         local rec_list
7573         local rec
7574         local rec_type
7575         local obj_file
7576         local path
7577         local seq
7578         local oid
7579         local pass=true
7580
7581         #get fid and record list
7582         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7583                 tail -n 4))
7584         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7585                 tail -n 4))
7586         #remount mgs as ldiskfs or zfs type
7587         stop mgs || error "stop mgs failed"
7588         mount_fstype mgs || error "remount mgs failed"
7589         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7590                 fid=${fid_list[i]}
7591                 rec=${rec_list[i]}
7592                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7593                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7594                 oid=$((16#$oid))
7595
7596                 case $fstype in
7597                         ldiskfs )
7598                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7599                         zfs )
7600                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7601                 esac
7602                 echo "obj_file is $obj_file"
7603                 do_facet mgs $llog_reader $obj_file
7604
7605                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7606                         awk '{ print $3 }' | sed -e "s/^type=//g")
7607                 if [ $rec_type != $rec ]; then
7608                         echo "FAILED test_60a wrong record type $rec_type," \
7609                               "should be $rec"
7610                         pass=false
7611                         break
7612                 fi
7613
7614                 #check obj path if record type is LLOG_LOGID_MAGIC
7615                 if [ "$rec" == "1064553b" ]; then
7616                         path=$(do_facet mgs $llog_reader $obj_file |
7617                                 grep "path=" | awk '{ print $NF }' |
7618                                 sed -e "s/^path=//g")
7619                         if [ $obj_file != $mntpt/$path ]; then
7620                                 echo "FAILED test_60a wrong obj path" \
7621                                       "$montpt/$path, should be $obj_file"
7622                                 pass=false
7623                                 break
7624                         fi
7625                 fi
7626         done
7627         rm -f $TMP/$tfile
7628         #restart mgs before "error", otherwise it will block the next test
7629         stop mgs || error "stop mgs failed"
7630         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7631         $pass || error "test failed, see FAILED test_60a messages for specifics"
7632 }
7633 run_test 60a "llog_test run from kernel module and test llog_reader"
7634
7635 test_60b() { # bug 6411
7636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7637
7638         dmesg > $DIR/$tfile
7639         LLOG_COUNT=$(do_facet mgs dmesg |
7640                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7641                           /llog_[a-z]*.c:[0-9]/ {
7642                                 if (marker)
7643                                         from_marker++
7644                                 from_begin++
7645                           }
7646                           END {
7647                                 if (marker)
7648                                         print from_marker
7649                                 else
7650                                         print from_begin
7651                           }")
7652
7653         [[ $LLOG_COUNT -gt 120 ]] &&
7654                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7655 }
7656 run_test 60b "limit repeated messages from CERROR/CWARN"
7657
7658 test_60c() {
7659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7660
7661         echo "create 5000 files"
7662         createmany -o $DIR/f60c- 5000
7663 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7664         lctl set_param fail_loc=0x80000137
7665         unlinkmany $DIR/f60c- 5000
7666         lctl set_param fail_loc=0
7667 }
7668 run_test 60c "unlink file when mds full"
7669
7670 test_60d() {
7671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7672
7673         SAVEPRINTK=$(lctl get_param -n printk)
7674         # verify "lctl mark" is even working"
7675         MESSAGE="test message ID $RANDOM $$"
7676         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7677         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7678
7679         lctl set_param printk=0 || error "set lnet.printk failed"
7680         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7681         MESSAGE="new test message ID $RANDOM $$"
7682         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7683         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7684         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7685
7686         lctl set_param -n printk="$SAVEPRINTK"
7687 }
7688 run_test 60d "test printk console message masking"
7689
7690 test_60e() {
7691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7692         remote_mds_nodsh && skip "remote MDS with nodsh"
7693
7694         touch $DIR/$tfile
7695 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7696         do_facet mds1 lctl set_param fail_loc=0x15b
7697         rm $DIR/$tfile
7698 }
7699 run_test 60e "no space while new llog is being created"
7700
7701 test_60g() {
7702         local pid
7703         local i
7704
7705         test_mkdir -c $MDSCOUNT $DIR/$tdir
7706
7707         (
7708                 local index=0
7709                 while true; do
7710                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7711                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7712                                 2>/dev/null
7713                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7714                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7715                         index=$((index + 1))
7716                 done
7717         ) &
7718
7719         pid=$!
7720
7721         for i in {0..100}; do
7722                 # define OBD_FAIL_OSD_TXN_START    0x19a
7723                 local index=$((i % MDSCOUNT + 1))
7724
7725                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7726                         > /dev/null
7727                 sleep 0.01
7728         done
7729
7730         kill -9 $pid
7731
7732         for i in $(seq $MDSCOUNT); do
7733                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7734         done
7735
7736         mkdir $DIR/$tdir/new || error "mkdir failed"
7737         rmdir $DIR/$tdir/new || error "rmdir failed"
7738
7739         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7740                 -t namespace
7741         for i in $(seq $MDSCOUNT); do
7742                 wait_update_facet mds$i "$LCTL get_param -n \
7743                         mdd.$(facet_svc mds$i).lfsck_namespace |
7744                         awk '/^status/ { print \\\$2 }'" "completed"
7745         done
7746
7747         ls -R $DIR/$tdir || error "ls failed"
7748         rm -rf $DIR/$tdir || error "rmdir failed"
7749 }
7750 run_test 60g "transaction abort won't cause MDT hung"
7751
7752 test_60h() {
7753         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7754                 skip "Need MDS version at least 2.12.52"
7755         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7756
7757         local f
7758
7759         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7760         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7761         for fail_loc in 0x80000188 0x80000189; do
7762                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7763                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7764                         error "mkdir $dir-$fail_loc failed"
7765                 for i in {0..10}; do
7766                         # create may fail on missing stripe
7767                         echo $i > $DIR/$tdir-$fail_loc/$i
7768                 done
7769                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7770                         error "getdirstripe $tdir-$fail_loc failed"
7771                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7772                         error "migrate $tdir-$fail_loc failed"
7773                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7774                         error "getdirstripe $tdir-$fail_loc failed"
7775                 pushd $DIR/$tdir-$fail_loc
7776                 for f in *; do
7777                         echo $f | cmp $f - || error "$f data mismatch"
7778                 done
7779                 popd
7780                 rm -rf $DIR/$tdir-$fail_loc
7781         done
7782 }
7783 run_test 60h "striped directory with missing stripes can be accessed"
7784
7785 test_61a() {
7786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7787
7788         f="$DIR/f61"
7789         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7790         cancel_lru_locks osc
7791         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7792         sync
7793 }
7794 run_test 61a "mmap() writes don't make sync hang ================"
7795
7796 test_61b() {
7797         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7798 }
7799 run_test 61b "mmap() of unstriped file is successful"
7800
7801 # bug 2330 - insufficient obd_match error checking causes LBUG
7802 test_62() {
7803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7804
7805         f="$DIR/f62"
7806         echo foo > $f
7807         cancel_lru_locks osc
7808         lctl set_param fail_loc=0x405
7809         cat $f && error "cat succeeded, expect -EIO"
7810         lctl set_param fail_loc=0
7811 }
7812 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7813 # match every page all of the time.
7814 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7815
7816 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7817 # Though this test is irrelevant anymore, it helped to reveal some
7818 # other grant bugs (LU-4482), let's keep it.
7819 test_63a() {   # was test_63
7820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7821
7822         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7823
7824         for i in `seq 10` ; do
7825                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7826                 sleep 5
7827                 kill $!
7828                 sleep 1
7829         done
7830
7831         rm -f $DIR/f63 || true
7832 }
7833 run_test 63a "Verify oig_wait interruption does not crash ======="
7834
7835 # bug 2248 - async write errors didn't return to application on sync
7836 # bug 3677 - async write errors left page locked
7837 test_63b() {
7838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7839
7840         debugsave
7841         lctl set_param debug=-1
7842
7843         # ensure we have a grant to do async writes
7844         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7845         rm $DIR/$tfile
7846
7847         sync    # sync lest earlier test intercept the fail_loc
7848
7849         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7850         lctl set_param fail_loc=0x80000406
7851         $MULTIOP $DIR/$tfile Owy && \
7852                 error "sync didn't return ENOMEM"
7853         sync; sleep 2; sync     # do a real sync this time to flush page
7854         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7855                 error "locked page left in cache after async error" || true
7856         debugrestore
7857 }
7858 run_test 63b "async write errors should be returned to fsync ==="
7859
7860 test_64a () {
7861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7862
7863         lfs df $DIR
7864         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7865 }
7866 run_test 64a "verify filter grant calculations (in kernel) ====="
7867
7868 test_64b () {
7869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7870
7871         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7872 }
7873 run_test 64b "check out-of-space detection on client"
7874
7875 test_64c() {
7876         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7877 }
7878 run_test 64c "verify grant shrink"
7879
7880 import_param() {
7881         local tgt=$1
7882         local param=$2
7883
7884         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7885 }
7886
7887 # this does exactly what osc_request.c:osc_announce_cached() does in
7888 # order to calculate max amount of grants to ask from server
7889 want_grant() {
7890         local tgt=$1
7891
7892         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7893         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7894
7895         ((rpc_in_flight++));
7896         nrpages=$((nrpages * rpc_in_flight))
7897
7898         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7899
7900         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7901
7902         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7903         local undirty=$((nrpages * PAGE_SIZE))
7904
7905         local max_extent_pages
7906         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7907         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7908         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7909         local grant_extent_tax
7910         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7911
7912         undirty=$((undirty + nrextents * grant_extent_tax))
7913
7914         echo $undirty
7915 }
7916
7917 # this is size of unit for grant allocation. It should be equal to
7918 # what tgt_grant.c:tgt_grant_chunk() calculates
7919 grant_chunk() {
7920         local tgt=$1
7921         local max_brw_size
7922         local grant_extent_tax
7923
7924         max_brw_size=$(import_param $tgt max_brw_size)
7925
7926         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7927
7928         echo $(((max_brw_size + grant_extent_tax) * 2))
7929 }
7930
7931 test_64d() {
7932         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7933                 skip "OST < 2.10.55 doesn't limit grants enough"
7934
7935         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7936
7937         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7938                 skip "no grant_param connect flag"
7939
7940         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7941
7942         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7943         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7944
7945
7946         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7947         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7948
7949         $LFS setstripe $DIR/$tfile -i 0 -c 1
7950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7951         ddpid=$!
7952
7953         while kill -0 $ddpid; do
7954                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7955
7956                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7957                         kill $ddpid
7958                         error "cur_grant $cur_grant > $max_cur_granted"
7959                 fi
7960
7961                 sleep 1
7962         done
7963 }
7964 run_test 64d "check grant limit exceed"
7965
7966 check_grants() {
7967         local tgt=$1
7968         local expected=$2
7969         local msg=$3
7970         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7971
7972         ((cur_grants == expected)) ||
7973                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7974 }
7975
7976 round_up_p2() {
7977         echo $((($1 + $2 - 1) & ~($2 - 1)))
7978 }
7979
7980 test_64e() {
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7983                 skip "Need OSS version at least 2.11.56"
7984
7985         # Remount client to reset grant
7986         remount_client $MOUNT || error "failed to remount client"
7987         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7988
7989         local init_grants=$(import_param $osc_tgt initial_grant)
7990
7991         check_grants $osc_tgt $init_grants "init grants"
7992
7993         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7994         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7995         local gbs=$(import_param $osc_tgt grant_block_size)
7996
7997         # write random number of bytes from max_brw_size / 4 to max_brw_size
7998         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7999         # align for direct io
8000         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8001         # round to grant consumption unit
8002         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8003
8004         local grants=$((wb_round_up + extent_tax))
8005
8006         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8007
8008         # define OBD_FAIL_TGT_NO_GRANT 0x725
8009         # make the server not grant more back
8010         do_facet ost1 $LCTL set_param fail_loc=0x725
8011         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8012
8013         do_facet ost1 $LCTL set_param fail_loc=0
8014
8015         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8016
8017         rm -f $DIR/$tfile || error "rm failed"
8018
8019         # Remount client to reset grant
8020         remount_client $MOUNT || error "failed to remount client"
8021         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8022
8023         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8024
8025         # define OBD_FAIL_TGT_NO_GRANT 0x725
8026         # make the server not grant more back
8027         do_facet ost1 $LCTL set_param fail_loc=0x725
8028         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8029         do_facet ost1 $LCTL set_param fail_loc=0
8030
8031         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8032 }
8033 run_test 64e "check grant consumption (no grant allocation)"
8034
8035 test_64f() {
8036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8037
8038         # Remount client to reset grant
8039         remount_client $MOUNT || error "failed to remount client"
8040         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8041
8042         local init_grants=$(import_param $osc_tgt initial_grant)
8043         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8044         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8045         local gbs=$(import_param $osc_tgt grant_block_size)
8046         local chunk=$(grant_chunk $osc_tgt)
8047
8048         # write random number of bytes from max_brw_size / 4 to max_brw_size
8049         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8050         # align for direct io
8051         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8052         # round to grant consumption unit
8053         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8054
8055         local grants=$((wb_round_up + extent_tax))
8056
8057         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8058         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8059                 error "error writing to $DIR/$tfile"
8060
8061         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8062                 "direct io with grant allocation"
8063
8064         rm -f $DIR/$tfile || error "rm failed"
8065
8066         # Remount client to reset grant
8067         remount_client $MOUNT || error "failed to remount client"
8068         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8069
8070         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8071
8072         local cmd="oO_WRONLY:w${write_bytes}_yc"
8073
8074         $MULTIOP $DIR/$tfile $cmd &
8075         MULTIPID=$!
8076         sleep 1
8077
8078         check_grants $osc_tgt $((init_grants - grants)) \
8079                 "buffered io, not write rpc"
8080
8081         kill -USR1 $MULTIPID
8082         wait
8083
8084         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8085                 "buffered io, one RPC"
8086 }
8087 run_test 64f "check grant consumption (with grant allocation)"
8088
8089 # bug 1414 - set/get directories' stripe info
8090 test_65a() {
8091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8092
8093         test_mkdir $DIR/$tdir
8094         touch $DIR/$tdir/f1
8095         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8096 }
8097 run_test 65a "directory with no stripe info"
8098
8099 test_65b() {
8100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8101
8102         test_mkdir $DIR/$tdir
8103         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8104
8105         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8106                                                 error "setstripe"
8107         touch $DIR/$tdir/f2
8108         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8109 }
8110 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8111
8112 test_65c() {
8113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8114         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8115
8116         test_mkdir $DIR/$tdir
8117         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8118
8119         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8120                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8121         touch $DIR/$tdir/f3
8122         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8123 }
8124 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8125
8126 test_65d() {
8127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8128
8129         test_mkdir $DIR/$tdir
8130         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8131         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8132
8133         if [[ $STRIPECOUNT -le 0 ]]; then
8134                 sc=1
8135         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8136                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8137                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8138         else
8139                 sc=$(($STRIPECOUNT - 1))
8140         fi
8141         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8142         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8143         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8144                 error "lverify failed"
8145 }
8146 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8147
8148 test_65e() {
8149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8150
8151         test_mkdir $DIR/$tdir
8152
8153         $LFS setstripe $DIR/$tdir || error "setstripe"
8154         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8155                                         error "no stripe info failed"
8156         touch $DIR/$tdir/f6
8157         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8158 }
8159 run_test 65e "directory setstripe defaults"
8160
8161 test_65f() {
8162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8163
8164         test_mkdir $DIR/${tdir}f
8165         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8166                 error "setstripe succeeded" || true
8167 }
8168 run_test 65f "dir setstripe permission (should return error) ==="
8169
8170 test_65g() {
8171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8172
8173         test_mkdir $DIR/$tdir
8174         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8175
8176         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8177                 error "setstripe -S failed"
8178         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8179         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8180                 error "delete default stripe failed"
8181 }
8182 run_test 65g "directory setstripe -d"
8183
8184 test_65h() {
8185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8186
8187         test_mkdir $DIR/$tdir
8188         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8189
8190         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8191                 error "setstripe -S failed"
8192         test_mkdir $DIR/$tdir/dd1
8193         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8194                 error "stripe info inherit failed"
8195 }
8196 run_test 65h "directory stripe info inherit ===================="
8197
8198 test_65i() {
8199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8200
8201         save_layout_restore_at_exit $MOUNT
8202
8203         # bug6367: set non-default striping on root directory
8204         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8205
8206         # bug12836: getstripe on -1 default directory striping
8207         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8208
8209         # bug12836: getstripe -v on -1 default directory striping
8210         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8211
8212         # bug12836: new find on -1 default directory striping
8213         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8214 }
8215 run_test 65i "various tests to set root directory striping"
8216
8217 test_65j() { # bug6367
8218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8219
8220         sync; sleep 1
8221
8222         # if we aren't already remounting for each test, do so for this test
8223         if [ "$I_MOUNTED" = "yes" ]; then
8224                 cleanup || error "failed to unmount"
8225                 setup
8226         fi
8227
8228         save_layout_restore_at_exit $MOUNT
8229
8230         $LFS setstripe -d $MOUNT || error "setstripe failed"
8231 }
8232 run_test 65j "set default striping on root directory (bug 6367)="
8233
8234 cleanup_65k() {
8235         rm -rf $DIR/$tdir
8236         wait_delete_completed
8237         do_facet $SINGLEMDS "lctl set_param -n \
8238                 osp.$ost*MDT0000.max_create_count=$max_count"
8239         do_facet $SINGLEMDS "lctl set_param -n \
8240                 osp.$ost*MDT0000.create_count=$count"
8241         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8242         echo $INACTIVE_OSC "is Activate"
8243
8244         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8245 }
8246
8247 test_65k() { # bug11679
8248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8249         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8250         remote_mds_nodsh && skip "remote MDS with nodsh"
8251
8252         local disable_precreate=true
8253         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8254                 disable_precreate=false
8255
8256         echo "Check OST status: "
8257         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8258                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8259
8260         for OSC in $MDS_OSCS; do
8261                 echo $OSC "is active"
8262                 do_facet $SINGLEMDS lctl --device %$OSC activate
8263         done
8264
8265         for INACTIVE_OSC in $MDS_OSCS; do
8266                 local ost=$(osc_to_ost $INACTIVE_OSC)
8267                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8268                                lov.*md*.target_obd |
8269                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8270
8271                 mkdir -p $DIR/$tdir
8272                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8273                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8274
8275                 echo "Deactivate: " $INACTIVE_OSC
8276                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8277
8278                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8279                               osp.$ost*MDT0000.create_count")
8280                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8281                                   osp.$ost*MDT0000.max_create_count")
8282                 $disable_precreate &&
8283                         do_facet $SINGLEMDS "lctl set_param -n \
8284                                 osp.$ost*MDT0000.max_create_count=0"
8285
8286                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8287                         [ -f $DIR/$tdir/$idx ] && continue
8288                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8289                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8290                                 { cleanup_65k;
8291                                   error "setstripe $idx should succeed"; }
8292                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8293                 done
8294                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8295                 rmdir $DIR/$tdir
8296
8297                 do_facet $SINGLEMDS "lctl set_param -n \
8298                         osp.$ost*MDT0000.max_create_count=$max_count"
8299                 do_facet $SINGLEMDS "lctl set_param -n \
8300                         osp.$ost*MDT0000.create_count=$count"
8301                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8302                 echo $INACTIVE_OSC "is Activate"
8303
8304                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8305         done
8306 }
8307 run_test 65k "validate manual striping works properly with deactivated OSCs"
8308
8309 test_65l() { # bug 12836
8310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8311
8312         test_mkdir -p $DIR/$tdir/test_dir
8313         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8314         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8315 }
8316 run_test 65l "lfs find on -1 stripe dir ========================"
8317
8318 test_65m() {
8319         local layout=$(save_layout $MOUNT)
8320         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8321                 restore_layout $MOUNT $layout
8322                 error "setstripe should fail by non-root users"
8323         }
8324         true
8325 }
8326 run_test 65m "normal user can't set filesystem default stripe"
8327
8328 test_65n() {
8329         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8330         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8331                 skip "Need MDS version at least 2.12.50"
8332         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8333
8334         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8335         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8336         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8337
8338         local root_layout=$(save_layout $MOUNT)
8339         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8340
8341         # new subdirectory under root directory should not inherit
8342         # the default layout from root
8343         local dir1=$MOUNT/$tdir-1
8344         mkdir $dir1 || error "mkdir $dir1 failed"
8345         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8346                 error "$dir1 shouldn't have LOV EA"
8347
8348         # delete the default layout on root directory
8349         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8350
8351         local dir2=$MOUNT/$tdir-2
8352         mkdir $dir2 || error "mkdir $dir2 failed"
8353         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8354                 error "$dir2 shouldn't have LOV EA"
8355
8356         # set a new striping pattern on root directory
8357         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8358         local new_def_stripe_size=$((def_stripe_size * 2))
8359         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8360                 error "set stripe size on $MOUNT failed"
8361
8362         # new file created in $dir2 should inherit the new stripe size from
8363         # the filesystem default
8364         local file2=$dir2/$tfile-2
8365         touch $file2 || error "touch $file2 failed"
8366
8367         local file2_stripe_size=$($LFS getstripe -S $file2)
8368         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8369                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8370
8371         local dir3=$MOUNT/$tdir-3
8372         mkdir $dir3 || error "mkdir $dir3 failed"
8373         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8374         # the root layout, which is the actual default layout that will be used
8375         # when new files are created in $dir3.
8376         local dir3_layout=$(get_layout_param $dir3)
8377         local root_dir_layout=$(get_layout_param $MOUNT)
8378         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8379                 error "$dir3 should show the default layout from $MOUNT"
8380
8381         # set OST pool on root directory
8382         local pool=$TESTNAME
8383         pool_add $pool || error "add $pool failed"
8384         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8385                 error "add targets to $pool failed"
8386
8387         $LFS setstripe -p $pool $MOUNT ||
8388                 error "set OST pool on $MOUNT failed"
8389
8390         # new file created in $dir3 should inherit the pool from
8391         # the filesystem default
8392         local file3=$dir3/$tfile-3
8393         touch $file3 || error "touch $file3 failed"
8394
8395         local file3_pool=$($LFS getstripe -p $file3)
8396         [[ "$file3_pool" = "$pool" ]] ||
8397                 error "$file3 didn't inherit OST pool $pool"
8398
8399         local dir4=$MOUNT/$tdir-4
8400         mkdir $dir4 || error "mkdir $dir4 failed"
8401         local dir4_layout=$(get_layout_param $dir4)
8402         root_dir_layout=$(get_layout_param $MOUNT)
8403         echo "$LFS getstripe -d $dir4"
8404         $LFS getstripe -d $dir4
8405         echo "$LFS getstripe -d $MOUNT"
8406         $LFS getstripe -d $MOUNT
8407         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8408                 error "$dir4 should show the default layout from $MOUNT"
8409
8410         # new file created in $dir4 should inherit the pool from
8411         # the filesystem default
8412         local file4=$dir4/$tfile-4
8413         touch $file4 || error "touch $file4 failed"
8414
8415         local file4_pool=$($LFS getstripe -p $file4)
8416         [[ "$file4_pool" = "$pool" ]] ||
8417                 error "$file4 didn't inherit OST pool $pool"
8418
8419         # new subdirectory under non-root directory should inherit
8420         # the default layout from its parent directory
8421         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8422                 error "set directory layout on $dir4 failed"
8423
8424         local dir5=$dir4/$tdir-5
8425         mkdir $dir5 || error "mkdir $dir5 failed"
8426
8427         dir4_layout=$(get_layout_param $dir4)
8428         local dir5_layout=$(get_layout_param $dir5)
8429         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8430                 error "$dir5 should inherit the default layout from $dir4"
8431
8432         # though subdir under ROOT doesn't inherit default layout, but
8433         # its sub dir/file should be created with default layout.
8434         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8435         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8436                 skip "Need MDS version at least 2.12.59"
8437
8438         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8439         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8440         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8441
8442         if [ $default_lmv_hash == "none" ]; then
8443                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8444         else
8445                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8446                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8447         fi
8448
8449         $LFS setdirstripe -D -c 2 $MOUNT ||
8450                 error "setdirstripe -D -c 2 failed"
8451         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8452         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8453         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8454 }
8455 run_test 65n "don't inherit default layout from root for new subdirectories"
8456
8457 # bug 2543 - update blocks count on client
8458 test_66() {
8459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8460
8461         COUNT=${COUNT:-8}
8462         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8463         sync; sync_all_data; sync; sync_all_data
8464         cancel_lru_locks osc
8465         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8466         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8467 }
8468 run_test 66 "update inode blocks count on client ==============="
8469
8470 meminfo() {
8471         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8472 }
8473
8474 swap_used() {
8475         swapon -s | awk '($1 == "'$1'") { print $4 }'
8476 }
8477
8478 # bug5265, obdfilter oa2dentry return -ENOENT
8479 # #define OBD_FAIL_SRV_ENOENT 0x217
8480 test_69() {
8481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8482         remote_ost_nodsh && skip "remote OST with nodsh"
8483
8484         f="$DIR/$tfile"
8485         $LFS setstripe -c 1 -i 0 $f
8486
8487         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8488
8489         do_facet ost1 lctl set_param fail_loc=0x217
8490         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8491         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8492
8493         do_facet ost1 lctl set_param fail_loc=0
8494         $DIRECTIO write $f 0 2 || error "write error"
8495
8496         cancel_lru_locks osc
8497         $DIRECTIO read $f 0 1 || error "read error"
8498
8499         do_facet ost1 lctl set_param fail_loc=0x217
8500         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8501
8502         do_facet ost1 lctl set_param fail_loc=0
8503         rm -f $f
8504 }
8505 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8506
8507 test_71() {
8508         test_mkdir $DIR/$tdir
8509         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8510         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8511 }
8512 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8513
8514 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8516         [ "$RUNAS_ID" = "$UID" ] &&
8517                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8518         # Check that testing environment is properly set up. Skip if not
8519         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8520                 skip_env "User $RUNAS_ID does not exist - skipping"
8521
8522         touch $DIR/$tfile
8523         chmod 777 $DIR/$tfile
8524         chmod ug+s $DIR/$tfile
8525         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8526                 error "$RUNAS dd $DIR/$tfile failed"
8527         # See if we are still setuid/sgid
8528         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8529                 error "S/gid is not dropped on write"
8530         # Now test that MDS is updated too
8531         cancel_lru_locks mdc
8532         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8533                 error "S/gid is not dropped on MDS"
8534         rm -f $DIR/$tfile
8535 }
8536 run_test 72a "Test that remove suid works properly (bug5695) ===="
8537
8538 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8539         local perm
8540
8541         [ "$RUNAS_ID" = "$UID" ] &&
8542                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8543         [ "$RUNAS_ID" -eq 0 ] &&
8544                 skip_env "RUNAS_ID = 0 -- skipping"
8545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8546         # Check that testing environment is properly set up. Skip if not
8547         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8548                 skip_env "User $RUNAS_ID does not exist - skipping"
8549
8550         touch $DIR/${tfile}-f{g,u}
8551         test_mkdir $DIR/${tfile}-dg
8552         test_mkdir $DIR/${tfile}-du
8553         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8554         chmod g+s $DIR/${tfile}-{f,d}g
8555         chmod u+s $DIR/${tfile}-{f,d}u
8556         for perm in 777 2777 4777; do
8557                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8558                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8559                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8560                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8561         done
8562         true
8563 }
8564 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8565
8566 # bug 3462 - multiple simultaneous MDC requests
8567 test_73() {
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569
8570         test_mkdir $DIR/d73-1
8571         test_mkdir $DIR/d73-2
8572         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8573         pid1=$!
8574
8575         lctl set_param fail_loc=0x80000129
8576         $MULTIOP $DIR/d73-1/f73-2 Oc &
8577         sleep 1
8578         lctl set_param fail_loc=0
8579
8580         $MULTIOP $DIR/d73-2/f73-3 Oc &
8581         pid3=$!
8582
8583         kill -USR1 $pid1
8584         wait $pid1 || return 1
8585
8586         sleep 25
8587
8588         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8589         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8590         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8591
8592         rm -rf $DIR/d73-*
8593 }
8594 run_test 73 "multiple MDC requests (should not deadlock)"
8595
8596 test_74a() { # bug 6149, 6184
8597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8598
8599         touch $DIR/f74a
8600         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8601         #
8602         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8603         # will spin in a tight reconnection loop
8604         $LCTL set_param fail_loc=0x8000030e
8605         # get any lock that won't be difficult - lookup works.
8606         ls $DIR/f74a
8607         $LCTL set_param fail_loc=0
8608         rm -f $DIR/f74a
8609         true
8610 }
8611 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8612
8613 test_74b() { # bug 13310
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8617         #
8618         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8619         # will spin in a tight reconnection loop
8620         $LCTL set_param fail_loc=0x8000030e
8621         # get a "difficult" lock
8622         touch $DIR/f74b
8623         $LCTL set_param fail_loc=0
8624         rm -f $DIR/f74b
8625         true
8626 }
8627 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8628
8629 test_74c() {
8630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8631
8632         #define OBD_FAIL_LDLM_NEW_LOCK
8633         $LCTL set_param fail_loc=0x319
8634         touch $DIR/$tfile && error "touch successful"
8635         $LCTL set_param fail_loc=0
8636         true
8637 }
8638 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8639
8640 slab_lic=/sys/kernel/slab/lustre_inode_cache
8641 num_objects() {
8642         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8643         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8644                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8645 }
8646
8647 test_76a() { # Now for b=20433, added originally in b=1443
8648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8649
8650         cancel_lru_locks osc
8651         # there may be some slab objects cached per core
8652         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8653         local before=$(num_objects)
8654         local count=$((512 * cpus))
8655         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8656         local margin=$((count / 10))
8657         if [[ -f $slab_lic/aliases ]]; then
8658                 local aliases=$(cat $slab_lic/aliases)
8659                 (( aliases > 0 )) && margin=$((margin * aliases))
8660         fi
8661
8662         echo "before slab objects: $before"
8663         for i in $(seq $count); do
8664                 touch $DIR/$tfile
8665                 rm -f $DIR/$tfile
8666         done
8667         cancel_lru_locks osc
8668         local after=$(num_objects)
8669         echo "created: $count, after slab objects: $after"
8670         # shared slab counts are not very accurate, allow significant margin
8671         # the main goal is that the cache growth is not permanently > $count
8672         while (( after > before + margin )); do
8673                 sleep 1
8674                 after=$(num_objects)
8675                 wait=$((wait + 1))
8676                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8677                 if (( wait > 60 )); then
8678                         error "inode slab grew from $before+$margin to $after"
8679                 fi
8680         done
8681 }
8682 run_test 76a "confirm clients recycle inodes properly ===="
8683
8684 test_76b() {
8685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8686         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8687
8688         local count=512
8689         local before=$(num_objects)
8690
8691         for i in $(seq $count); do
8692                 mkdir $DIR/$tdir
8693                 rmdir $DIR/$tdir
8694         done
8695
8696         local after=$(num_objects)
8697         local wait=0
8698
8699         while (( after > before )); do
8700                 sleep 1
8701                 after=$(num_objects)
8702                 wait=$((wait + 1))
8703                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8704                 if (( wait > 60 )); then
8705                         error "inode slab grew from $before to $after"
8706                 fi
8707         done
8708
8709         echo "slab objects before: $before, after: $after"
8710 }
8711 run_test 76b "confirm clients recycle directory inodes properly ===="
8712
8713 export ORIG_CSUM=""
8714 set_checksums()
8715 {
8716         # Note: in sptlrpc modes which enable its own bulk checksum, the
8717         # original crc32_le bulk checksum will be automatically disabled,
8718         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8719         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8720         # In this case set_checksums() will not be no-op, because sptlrpc
8721         # bulk checksum will be enabled all through the test.
8722
8723         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8724         lctl set_param -n osc.*.checksums $1
8725         return 0
8726 }
8727
8728 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8729                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8730 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8731                              tr -d [] | head -n1)}
8732 set_checksum_type()
8733 {
8734         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8735         rc=$?
8736         log "set checksum type to $1, rc = $rc"
8737         return $rc
8738 }
8739
8740 get_osc_checksum_type()
8741 {
8742         # arugment 1: OST name, like OST0000
8743         ost=$1
8744         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8745                         sed 's/.*\[\(.*\)\].*/\1/g')
8746         rc=$?
8747         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8748         echo $checksum_type
8749 }
8750
8751 F77_TMP=$TMP/f77-temp
8752 F77SZ=8
8753 setup_f77() {
8754         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8755                 error "error writing to $F77_TMP"
8756 }
8757
8758 test_77a() { # bug 10889
8759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8760         $GSS && skip_env "could not run with gss"
8761
8762         [ ! -f $F77_TMP ] && setup_f77
8763         set_checksums 1
8764         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8765         set_checksums 0
8766         rm -f $DIR/$tfile
8767 }
8768 run_test 77a "normal checksum read/write operation"
8769
8770 test_77b() { # bug 10889
8771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8772         $GSS && skip_env "could not run with gss"
8773
8774         [ ! -f $F77_TMP ] && setup_f77
8775         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8776         $LCTL set_param fail_loc=0x80000409
8777         set_checksums 1
8778
8779         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8780                 error "dd error: $?"
8781         $LCTL set_param fail_loc=0
8782
8783         for algo in $CKSUM_TYPES; do
8784                 cancel_lru_locks osc
8785                 set_checksum_type $algo
8786                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8787                 $LCTL set_param fail_loc=0x80000408
8788                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8789                 $LCTL set_param fail_loc=0
8790         done
8791         set_checksums 0
8792         set_checksum_type $ORIG_CSUM_TYPE
8793         rm -f $DIR/$tfile
8794 }
8795 run_test 77b "checksum error on client write, read"
8796
8797 cleanup_77c() {
8798         trap 0
8799         set_checksums 0
8800         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8801         $check_ost &&
8802                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8803         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8804         $check_ost && [ -n "$ost_file_prefix" ] &&
8805                 do_facet ost1 rm -f ${ost_file_prefix}\*
8806 }
8807
8808 test_77c() {
8809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8810         $GSS && skip_env "could not run with gss"
8811         remote_ost_nodsh && skip "remote OST with nodsh"
8812
8813         local bad1
8814         local osc_file_prefix
8815         local osc_file
8816         local check_ost=false
8817         local ost_file_prefix
8818         local ost_file
8819         local orig_cksum
8820         local dump_cksum
8821         local fid
8822
8823         # ensure corruption will occur on first OSS/OST
8824         $LFS setstripe -i 0 $DIR/$tfile
8825
8826         [ ! -f $F77_TMP ] && setup_f77
8827         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8828                 error "dd write error: $?"
8829         fid=$($LFS path2fid $DIR/$tfile)
8830
8831         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8832         then
8833                 check_ost=true
8834                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8835                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8836         else
8837                 echo "OSS do not support bulk pages dump upon error"
8838         fi
8839
8840         osc_file_prefix=$($LCTL get_param -n debug_path)
8841         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8842
8843         trap cleanup_77c EXIT
8844
8845         set_checksums 1
8846         # enable bulk pages dump upon error on Client
8847         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8848         # enable bulk pages dump upon error on OSS
8849         $check_ost &&
8850                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8851
8852         # flush Client cache to allow next read to reach OSS
8853         cancel_lru_locks osc
8854
8855         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8856         $LCTL set_param fail_loc=0x80000408
8857         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8858         $LCTL set_param fail_loc=0
8859
8860         rm -f $DIR/$tfile
8861
8862         # check cksum dump on Client
8863         osc_file=$(ls ${osc_file_prefix}*)
8864         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8865         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8866         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8867         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8868         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8869                      cksum)
8870         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8871         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8872                 error "dump content does not match on Client"
8873
8874         $check_ost || skip "No need to check cksum dump on OSS"
8875
8876         # check cksum dump on OSS
8877         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8878         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8879         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8880         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8881         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8882                 error "dump content does not match on OSS"
8883
8884         cleanup_77c
8885 }
8886 run_test 77c "checksum error on client read with debug"
8887
8888 test_77d() { # bug 10889
8889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8890         $GSS && skip_env "could not run with gss"
8891
8892         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8893         $LCTL set_param fail_loc=0x80000409
8894         set_checksums 1
8895         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8896                 error "direct write: rc=$?"
8897         $LCTL set_param fail_loc=0
8898         set_checksums 0
8899
8900         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8901         $LCTL set_param fail_loc=0x80000408
8902         set_checksums 1
8903         cancel_lru_locks osc
8904         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8905                 error "direct read: rc=$?"
8906         $LCTL set_param fail_loc=0
8907         set_checksums 0
8908 }
8909 run_test 77d "checksum error on OST direct write, read"
8910
8911 test_77f() { # bug 10889
8912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8913         $GSS && skip_env "could not run with gss"
8914
8915         set_checksums 1
8916         for algo in $CKSUM_TYPES; do
8917                 cancel_lru_locks osc
8918                 set_checksum_type $algo
8919                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8920                 $LCTL set_param fail_loc=0x409
8921                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8922                         error "direct write succeeded"
8923                 $LCTL set_param fail_loc=0
8924         done
8925         set_checksum_type $ORIG_CSUM_TYPE
8926         set_checksums 0
8927 }
8928 run_test 77f "repeat checksum error on write (expect error)"
8929
8930 test_77g() { # bug 10889
8931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8932         $GSS && skip_env "could not run with gss"
8933         remote_ost_nodsh && skip "remote OST with nodsh"
8934
8935         [ ! -f $F77_TMP ] && setup_f77
8936
8937         local file=$DIR/$tfile
8938         stack_trap "rm -f $file" EXIT
8939
8940         $LFS setstripe -c 1 -i 0 $file
8941         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8942         do_facet ost1 lctl set_param fail_loc=0x8000021a
8943         set_checksums 1
8944         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8945                 error "write error: rc=$?"
8946         do_facet ost1 lctl set_param fail_loc=0
8947         set_checksums 0
8948
8949         cancel_lru_locks osc
8950         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8951         do_facet ost1 lctl set_param fail_loc=0x8000021b
8952         set_checksums 1
8953         cmp $F77_TMP $file || error "file compare failed"
8954         do_facet ost1 lctl set_param fail_loc=0
8955         set_checksums 0
8956 }
8957 run_test 77g "checksum error on OST write, read"
8958
8959 test_77k() { # LU-10906
8960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8961         $GSS && skip_env "could not run with gss"
8962
8963         local cksum_param="osc.$FSNAME*.checksums"
8964         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8965         local checksum
8966         local i
8967
8968         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8969         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8970         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8971
8972         for i in 0 1; do
8973                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8974                         error "failed to set checksum=$i on MGS"
8975                 wait_update $HOSTNAME "$get_checksum" $i
8976                 #remount
8977                 echo "remount client, checksum should be $i"
8978                 remount_client $MOUNT || error "failed to remount client"
8979                 checksum=$(eval $get_checksum)
8980                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8981         done
8982         # remove persistent param to avoid races with checksum mountopt below
8983         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8984                 error "failed to delete checksum on MGS"
8985
8986         for opt in "checksum" "nochecksum"; do
8987                 #remount with mount option
8988                 echo "remount client with option $opt, checksum should be $i"
8989                 umount_client $MOUNT || error "failed to umount client"
8990                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8991                         error "failed to mount client with option '$opt'"
8992                 checksum=$(eval $get_checksum)
8993                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8994                 i=$((i - 1))
8995         done
8996
8997         remount_client $MOUNT || error "failed to remount client"
8998 }
8999 run_test 77k "enable/disable checksum correctly"
9000
9001 test_77l() {
9002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9003         $GSS && skip_env "could not run with gss"
9004
9005         set_checksums 1
9006         stack_trap "set_checksums $ORIG_CSUM" EXIT
9007         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9008
9009         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9010
9011         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9012         for algo in $CKSUM_TYPES; do
9013                 set_checksum_type $algo || error "fail to set checksum type $algo"
9014                 osc_algo=$(get_osc_checksum_type OST0000)
9015                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9016
9017                 # no locks, no reqs to let the connection idle
9018                 cancel_lru_locks osc
9019                 lru_resize_disable osc
9020                 wait_osc_import_state client ost1 IDLE
9021
9022                 # ensure ost1 is connected
9023                 stat $DIR/$tfile >/dev/null || error "can't stat"
9024                 wait_osc_import_state client ost1 FULL
9025
9026                 osc_algo=$(get_osc_checksum_type OST0000)
9027                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9028         done
9029         return 0
9030 }
9031 run_test 77l "preferred checksum type is remembered after reconnected"
9032
9033 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9034 rm -f $F77_TMP
9035 unset F77_TMP
9036
9037 cleanup_test_78() {
9038         trap 0
9039         rm -f $DIR/$tfile
9040 }
9041
9042 test_78() { # bug 10901
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044         remote_ost || skip_env "local OST"
9045
9046         NSEQ=5
9047         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9048         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9049         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9050         echo "MemTotal: $MEMTOTAL"
9051
9052         # reserve 256MB of memory for the kernel and other running processes,
9053         # and then take 1/2 of the remaining memory for the read/write buffers.
9054         if [ $MEMTOTAL -gt 512 ] ;then
9055                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9056         else
9057                 # for those poor memory-starved high-end clusters...
9058                 MEMTOTAL=$((MEMTOTAL / 2))
9059         fi
9060         echo "Mem to use for directio: $MEMTOTAL"
9061
9062         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9063         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9064         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9065         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9066                 head -n1)
9067         echo "Smallest OST: $SMALLESTOST"
9068         [[ $SMALLESTOST -lt 10240 ]] &&
9069                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9070
9071         trap cleanup_test_78 EXIT
9072
9073         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9074                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9075
9076         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9077         echo "File size: $F78SIZE"
9078         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9079         for i in $(seq 1 $NSEQ); do
9080                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9081                 echo directIO rdwr round $i of $NSEQ
9082                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9083         done
9084
9085         cleanup_test_78
9086 }
9087 run_test 78 "handle large O_DIRECT writes correctly ============"
9088
9089 test_79() { # bug 12743
9090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9091
9092         wait_delete_completed
9093
9094         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9095         BKFREE=$(calc_osc_kbytes kbytesfree)
9096         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9097
9098         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9099         DFTOTAL=`echo $STRING | cut -d, -f1`
9100         DFUSED=`echo $STRING  | cut -d, -f2`
9101         DFAVAIL=`echo $STRING | cut -d, -f3`
9102         DFFREE=$(($DFTOTAL - $DFUSED))
9103
9104         ALLOWANCE=$((64 * $OSTCOUNT))
9105
9106         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9107            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9108                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9109         fi
9110         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9111            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9112                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9113         fi
9114         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9115            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9116                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9117         fi
9118 }
9119 run_test 79 "df report consistency check ======================="
9120
9121 test_80() { # bug 10718
9122         remote_ost_nodsh && skip "remote OST with nodsh"
9123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9124
9125         # relax strong synchronous semantics for slow backends like ZFS
9126         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9127                 local soc="obdfilter.*.sync_lock_cancel"
9128                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9129
9130                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9131                 if [ -z "$save" ]; then
9132                         soc="obdfilter.*.sync_on_lock_cancel"
9133                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9134                 fi
9135
9136                 if [ "$save" != "never" ]; then
9137                         local hosts=$(comma_list $(osts_nodes))
9138
9139                         do_nodes $hosts $LCTL set_param $soc=never
9140                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9141                 fi
9142         fi
9143
9144         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9145         sync; sleep 1; sync
9146         local before=$(date +%s)
9147         cancel_lru_locks osc
9148         local after=$(date +%s)
9149         local diff=$((after - before))
9150         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9151
9152         rm -f $DIR/$tfile
9153 }
9154 run_test 80 "Page eviction is equally fast at high offsets too"
9155
9156 test_81a() { # LU-456
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158         remote_ost_nodsh && skip "remote OST with nodsh"
9159
9160         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9161         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9162         do_facet ost1 lctl set_param fail_loc=0x80000228
9163
9164         # write should trigger a retry and success
9165         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9167         RC=$?
9168         if [ $RC -ne 0 ] ; then
9169                 error "write should success, but failed for $RC"
9170         fi
9171 }
9172 run_test 81a "OST should retry write when get -ENOSPC ==============="
9173
9174 test_81b() { # LU-456
9175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9176         remote_ost_nodsh && skip "remote OST with nodsh"
9177
9178         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9179         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9180         do_facet ost1 lctl set_param fail_loc=0x228
9181
9182         # write should retry several times and return -ENOSPC finally
9183         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9184         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9185         RC=$?
9186         ENOSPC=28
9187         if [ $RC -ne $ENOSPC ] ; then
9188                 error "dd should fail for -ENOSPC, but succeed."
9189         fi
9190 }
9191 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9192
9193 test_99() {
9194         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9195
9196         test_mkdir $DIR/$tdir.cvsroot
9197         chown $RUNAS_ID $DIR/$tdir.cvsroot
9198
9199         cd $TMP
9200         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9201
9202         cd /etc/init.d
9203         # some versions of cvs import exit(1) when asked to import links or
9204         # files they can't read.  ignore those files.
9205         local toignore=$(find . -type l -printf '-I %f\n' -o \
9206                          ! -perm /4 -printf '-I %f\n')
9207         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9208                 $tdir.reposname vtag rtag
9209
9210         cd $DIR
9211         test_mkdir $DIR/$tdir.reposname
9212         chown $RUNAS_ID $DIR/$tdir.reposname
9213         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9214
9215         cd $DIR/$tdir.reposname
9216         $RUNAS touch foo99
9217         $RUNAS cvs add -m 'addmsg' foo99
9218         $RUNAS cvs update
9219         $RUNAS cvs commit -m 'nomsg' foo99
9220         rm -fr $DIR/$tdir.cvsroot
9221 }
9222 run_test 99 "cvs strange file/directory operations"
9223
9224 test_100() {
9225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9226         [[ "$NETTYPE" =~ tcp ]] ||
9227                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9228         remote_ost_nodsh && skip "remote OST with nodsh"
9229         remote_mds_nodsh && skip "remote MDS with nodsh"
9230         remote_servers ||
9231                 skip "useless for local single node setup"
9232
9233         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9234                 [ "$PROT" != "tcp" ] && continue
9235                 RPORT=$(echo $REMOTE | cut -d: -f2)
9236                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9237
9238                 rc=0
9239                 LPORT=`echo $LOCAL | cut -d: -f2`
9240                 if [ $LPORT -ge 1024 ]; then
9241                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9242                         netstat -tna
9243                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9244                 fi
9245         done
9246         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9247 }
9248 run_test 100 "check local port using privileged port ==========="
9249
9250 function get_named_value()
9251 {
9252     local tag
9253
9254     tag=$1
9255     while read ;do
9256         line=$REPLY
9257         case $line in
9258         $tag*)
9259             echo $line | sed "s/^$tag[ ]*//"
9260             break
9261             ;;
9262         esac
9263     done
9264 }
9265
9266 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9267                    awk '/^max_cached_mb/ { print $2 }')
9268
9269 cleanup_101a() {
9270         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9271         trap 0
9272 }
9273
9274 test_101a() {
9275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9276
9277         local s
9278         local discard
9279         local nreads=10000
9280         local cache_limit=32
9281
9282         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9283         trap cleanup_101a EXIT
9284         $LCTL set_param -n llite.*.read_ahead_stats 0
9285         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9286
9287         #
9288         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9289         #
9290         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9291         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9292
9293         discard=0
9294         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9295                 get_named_value 'read but discarded' | cut -d" " -f1); do
9296                         discard=$(($discard + $s))
9297         done
9298         cleanup_101a
9299
9300         $LCTL get_param osc.*-osc*.rpc_stats
9301         $LCTL get_param llite.*.read_ahead_stats
9302
9303         # Discard is generally zero, but sometimes a few random reads line up
9304         # and trigger larger readahead, which is wasted & leads to discards.
9305         if [[ $(($discard)) -gt $nreads ]]; then
9306                 error "too many ($discard) discarded pages"
9307         fi
9308         rm -f $DIR/$tfile || true
9309 }
9310 run_test 101a "check read-ahead for random reads"
9311
9312 setup_test101bc() {
9313         test_mkdir $DIR/$tdir
9314         local ssize=$1
9315         local FILE_LENGTH=$2
9316         STRIPE_OFFSET=0
9317
9318         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9319
9320         local list=$(comma_list $(osts_nodes))
9321         set_osd_param $list '' read_cache_enable 0
9322         set_osd_param $list '' writethrough_cache_enable 0
9323
9324         trap cleanup_test101bc EXIT
9325         # prepare the read-ahead file
9326         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9327
9328         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9329                                 count=$FILE_SIZE_MB 2> /dev/null
9330
9331 }
9332
9333 cleanup_test101bc() {
9334         trap 0
9335         rm -rf $DIR/$tdir
9336         rm -f $DIR/$tfile
9337
9338         local list=$(comma_list $(osts_nodes))
9339         set_osd_param $list '' read_cache_enable 1
9340         set_osd_param $list '' writethrough_cache_enable 1
9341 }
9342
9343 calc_total() {
9344         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9345 }
9346
9347 ra_check_101() {
9348         local READ_SIZE=$1
9349         local STRIPE_SIZE=$2
9350         local FILE_LENGTH=$3
9351         local RA_INC=1048576
9352         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9353         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9354                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9355         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9356                         get_named_value 'read but discarded' |
9357                         cut -d" " -f1 | calc_total)
9358         if [[ $DISCARD -gt $discard_limit ]]; then
9359                 $LCTL get_param llite.*.read_ahead_stats
9360                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9361         else
9362                 echo "Read-ahead success for size ${READ_SIZE}"
9363         fi
9364 }
9365
9366 test_101b() {
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9369
9370         local STRIPE_SIZE=1048576
9371         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9372
9373         if [ $SLOW == "yes" ]; then
9374                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9375         else
9376                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9377         fi
9378
9379         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9380
9381         # prepare the read-ahead file
9382         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9383         cancel_lru_locks osc
9384         for BIDX in 2 4 8 16 32 64 128 256
9385         do
9386                 local BSIZE=$((BIDX*4096))
9387                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9388                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9389                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9390                 $LCTL set_param -n llite.*.read_ahead_stats 0
9391                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9392                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9393                 cancel_lru_locks osc
9394                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9395         done
9396         cleanup_test101bc
9397         true
9398 }
9399 run_test 101b "check stride-io mode read-ahead ================="
9400
9401 test_101c() {
9402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9403
9404         local STRIPE_SIZE=1048576
9405         local FILE_LENGTH=$((STRIPE_SIZE*100))
9406         local nreads=10000
9407         local rsize=65536
9408         local osc_rpc_stats
9409
9410         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9411
9412         cancel_lru_locks osc
9413         $LCTL set_param osc.*.rpc_stats 0
9414         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9415         $LCTL get_param osc.*.rpc_stats
9416         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9417                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9418                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9419                 local size
9420
9421                 if [ $lines -le 20 ]; then
9422                         echo "continue debug"
9423                         continue
9424                 fi
9425                 for size in 1 2 4 8; do
9426                         local rpc=$(echo "$stats" |
9427                                     awk '($1 == "'$size':") {print $2; exit; }')
9428                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9429                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9430                 done
9431                 echo "$osc_rpc_stats check passed!"
9432         done
9433         cleanup_test101bc
9434         true
9435 }
9436 run_test 101c "check stripe_size aligned read-ahead ================="
9437
9438 test_101d() {
9439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9440
9441         local file=$DIR/$tfile
9442         local sz_MB=${FILESIZE_101d:-80}
9443         local ra_MB=${READAHEAD_MB:-40}
9444
9445         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9446         [ $free_MB -lt $sz_MB ] &&
9447                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9448
9449         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9450         $LFS setstripe -c -1 $file || error "setstripe failed"
9451
9452         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9453         echo Cancel LRU locks on lustre client to flush the client cache
9454         cancel_lru_locks osc
9455
9456         echo Disable read-ahead
9457         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9458         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9459         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9460         $LCTL get_param -n llite.*.max_read_ahead_mb
9461
9462         echo "Reading the test file $file with read-ahead disabled"
9463         local sz_KB=$((sz_MB * 1024 / 4))
9464         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9465         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9466         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9467                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9468
9469         echo "Cancel LRU locks on lustre client to flush the client cache"
9470         cancel_lru_locks osc
9471         echo Enable read-ahead with ${ra_MB}MB
9472         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9473
9474         echo "Reading the test file $file with read-ahead enabled"
9475         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9476                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9477
9478         echo "read-ahead disabled time read $raOFF"
9479         echo "read-ahead enabled time read $raON"
9480
9481         rm -f $file
9482         wait_delete_completed
9483
9484         # use awk for this check instead of bash because it handles decimals
9485         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9486                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9487 }
9488 run_test 101d "file read with and without read-ahead enabled"
9489
9490 test_101e() {
9491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9492
9493         local file=$DIR/$tfile
9494         local size_KB=500  #KB
9495         local count=100
9496         local bsize=1024
9497
9498         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9499         local need_KB=$((count * size_KB))
9500         [[ $free_KB -le $need_KB ]] &&
9501                 skip_env "Need free space $need_KB, have $free_KB"
9502
9503         echo "Creating $count ${size_KB}K test files"
9504         for ((i = 0; i < $count; i++)); do
9505                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9506         done
9507
9508         echo "Cancel LRU locks on lustre client to flush the client cache"
9509         cancel_lru_locks $OSC
9510
9511         echo "Reset readahead stats"
9512         $LCTL set_param -n llite.*.read_ahead_stats 0
9513
9514         for ((i = 0; i < $count; i++)); do
9515                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9516         done
9517
9518         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9519                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9520
9521         for ((i = 0; i < $count; i++)); do
9522                 rm -rf $file.$i 2>/dev/null
9523         done
9524
9525         #10000 means 20% reads are missing in readahead
9526         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9527 }
9528 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9529
9530 test_101f() {
9531         which iozone || skip_env "no iozone installed"
9532
9533         local old_debug=$($LCTL get_param debug)
9534         old_debug=${old_debug#*=}
9535         $LCTL set_param debug="reada mmap"
9536
9537         # create a test file
9538         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9539
9540         echo Cancel LRU locks on lustre client to flush the client cache
9541         cancel_lru_locks osc
9542
9543         echo Reset readahead stats
9544         $LCTL set_param -n llite.*.read_ahead_stats 0
9545
9546         echo mmap read the file with small block size
9547         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9548                 > /dev/null 2>&1
9549
9550         echo checking missing pages
9551         $LCTL get_param llite.*.read_ahead_stats
9552         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9553                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9554
9555         $LCTL set_param debug="$old_debug"
9556         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9557         rm -f $DIR/$tfile
9558 }
9559 run_test 101f "check mmap read performance"
9560
9561 test_101g_brw_size_test() {
9562         local mb=$1
9563         local pages=$((mb * 1048576 / PAGE_SIZE))
9564         local file=$DIR/$tfile
9565
9566         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9567                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9568         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9569                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9570                         return 2
9571         done
9572
9573         stack_trap "rm -f $file" EXIT
9574         $LCTL set_param -n osc.*.rpc_stats=0
9575
9576         # 10 RPCs should be enough for the test
9577         local count=10
9578         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9579                 { error "dd write ${mb} MB blocks failed"; return 3; }
9580         cancel_lru_locks osc
9581         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9582                 { error "dd write ${mb} MB blocks failed"; return 4; }
9583
9584         # calculate number of full-sized read and write RPCs
9585         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9586                 sed -n '/pages per rpc/,/^$/p' |
9587                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9588                 END { print reads,writes }'))
9589         # allow one extra full-sized read RPC for async readahead
9590         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9591                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9592         [[ ${rpcs[1]} == $count ]] ||
9593                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9594 }
9595
9596 test_101g() {
9597         remote_ost_nodsh && skip "remote OST with nodsh"
9598
9599         local rpcs
9600         local osts=$(get_facets OST)
9601         local list=$(comma_list $(osts_nodes))
9602         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9603         local brw_size="obdfilter.*.brw_size"
9604
9605         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9606
9607         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9608
9609         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9610                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9611                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9612            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9613                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9614                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9615
9616                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9617                         suffix="M"
9618
9619                 if [[ $orig_mb -lt 16 ]]; then
9620                         save_lustre_params $osts "$brw_size" > $p
9621                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9622                                 error "set 16MB RPC size failed"
9623
9624                         echo "remount client to enable new RPC size"
9625                         remount_client $MOUNT || error "remount_client failed"
9626                 fi
9627
9628                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9629                 # should be able to set brw_size=12, but no rpc_stats for that
9630                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9631         fi
9632
9633         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9634
9635         if [[ $orig_mb -lt 16 ]]; then
9636                 restore_lustre_params < $p
9637                 remount_client $MOUNT || error "remount_client restore failed"
9638         fi
9639
9640         rm -f $p $DIR/$tfile
9641 }
9642 run_test 101g "Big bulk(4/16 MiB) readahead"
9643
9644 test_101h() {
9645         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9646
9647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9648                 error "dd 70M file failed"
9649         echo Cancel LRU locks on lustre client to flush the client cache
9650         cancel_lru_locks osc
9651
9652         echo "Reset readahead stats"
9653         $LCTL set_param -n llite.*.read_ahead_stats 0
9654
9655         echo "Read 10M of data but cross 64M bundary"
9656         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9657         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9658                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9659         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9660         rm -f $p $DIR/$tfile
9661 }
9662 run_test 101h "Readahead should cover current read window"
9663
9664 test_101i() {
9665         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9666                 error "dd 10M file failed"
9667
9668         local max_per_file_mb=$($LCTL get_param -n \
9669                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9670         cancel_lru_locks osc
9671         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9672         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9673                 error "set max_read_ahead_per_file_mb to 1 failed"
9674
9675         echo "Reset readahead stats"
9676         $LCTL set_param llite.*.read_ahead_stats=0
9677
9678         dd if=$DIR/$tfile of=/dev/null bs=2M
9679
9680         $LCTL get_param llite.*.read_ahead_stats
9681         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9682                      awk '/misses/ { print $2 }')
9683         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9684         rm -f $DIR/$tfile
9685 }
9686 run_test 101i "allow current readahead to exceed reservation"
9687
9688 test_101j() {
9689         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9690                 error "setstripe $DIR/$tfile failed"
9691         local file_size=$((1048576 * 16))
9692         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9693         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9694
9695         echo Disable read-ahead
9696         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9697
9698         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9699         for blk in $PAGE_SIZE 1048576 $file_size; do
9700                 cancel_lru_locks osc
9701                 echo "Reset readahead stats"
9702                 $LCTL set_param -n llite.*.read_ahead_stats=0
9703                 local count=$(($file_size / $blk))
9704                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9705                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9706                              get_named_value 'failed to fast read' |
9707                              cut -d" " -f1 | calc_total)
9708                 $LCTL get_param -n llite.*.read_ahead_stats
9709                 [ $miss -eq $count ] || error "expected $count got $miss"
9710         done
9711
9712         rm -f $p $DIR/$tfile
9713 }
9714 run_test 101j "A complete read block should be submitted when no RA"
9715
9716 setup_test102() {
9717         test_mkdir $DIR/$tdir
9718         chown $RUNAS_ID $DIR/$tdir
9719         STRIPE_SIZE=65536
9720         STRIPE_OFFSET=1
9721         STRIPE_COUNT=$OSTCOUNT
9722         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9723
9724         trap cleanup_test102 EXIT
9725         cd $DIR
9726         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9727         cd $DIR/$tdir
9728         for num in 1 2 3 4; do
9729                 for count in $(seq 1 $STRIPE_COUNT); do
9730                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9731                                 local size=`expr $STRIPE_SIZE \* $num`
9732                                 local file=file"$num-$idx-$count"
9733                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9734                         done
9735                 done
9736         done
9737
9738         cd $DIR
9739         $1 tar cf $TMP/f102.tar $tdir --xattrs
9740 }
9741
9742 cleanup_test102() {
9743         trap 0
9744         rm -f $TMP/f102.tar
9745         rm -rf $DIR/d0.sanity/d102
9746 }
9747
9748 test_102a() {
9749         [ "$UID" != 0 ] && skip "must run as root"
9750         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9751                 skip_env "must have user_xattr"
9752
9753         [ -z "$(which setfattr 2>/dev/null)" ] &&
9754                 skip_env "could not find setfattr"
9755
9756         local testfile=$DIR/$tfile
9757
9758         touch $testfile
9759         echo "set/get xattr..."
9760         setfattr -n trusted.name1 -v value1 $testfile ||
9761                 error "setfattr -n trusted.name1=value1 $testfile failed"
9762         getfattr -n trusted.name1 $testfile 2> /dev/null |
9763           grep "trusted.name1=.value1" ||
9764                 error "$testfile missing trusted.name1=value1"
9765
9766         setfattr -n user.author1 -v author1 $testfile ||
9767                 error "setfattr -n user.author1=author1 $testfile failed"
9768         getfattr -n user.author1 $testfile 2> /dev/null |
9769           grep "user.author1=.author1" ||
9770                 error "$testfile missing trusted.author1=author1"
9771
9772         echo "listxattr..."
9773         setfattr -n trusted.name2 -v value2 $testfile ||
9774                 error "$testfile unable to set trusted.name2"
9775         setfattr -n trusted.name3 -v value3 $testfile ||
9776                 error "$testfile unable to set trusted.name3"
9777         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9778             grep "trusted.name" | wc -l) -eq 3 ] ||
9779                 error "$testfile missing 3 trusted.name xattrs"
9780
9781         setfattr -n user.author2 -v author2 $testfile ||
9782                 error "$testfile unable to set user.author2"
9783         setfattr -n user.author3 -v author3 $testfile ||
9784                 error "$testfile unable to set user.author3"
9785         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9786             grep "user.author" | wc -l) -eq 3 ] ||
9787                 error "$testfile missing 3 user.author xattrs"
9788
9789         echo "remove xattr..."
9790         setfattr -x trusted.name1 $testfile ||
9791                 error "$testfile error deleting trusted.name1"
9792         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9793                 error "$testfile did not delete trusted.name1 xattr"
9794
9795         setfattr -x user.author1 $testfile ||
9796                 error "$testfile error deleting user.author1"
9797         echo "set lustre special xattr ..."
9798         $LFS setstripe -c1 $testfile
9799         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9800                 awk -F "=" '/trusted.lov/ { print $2 }' )
9801         setfattr -n "trusted.lov" -v $lovea $testfile ||
9802                 error "$testfile doesn't ignore setting trusted.lov again"
9803         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9804                 error "$testfile allow setting invalid trusted.lov"
9805         rm -f $testfile
9806 }
9807 run_test 102a "user xattr test =================================="
9808
9809 check_102b_layout() {
9810         local layout="$*"
9811         local testfile=$DIR/$tfile
9812
9813         echo "test layout '$layout'"
9814         $LFS setstripe $layout $testfile || error "setstripe failed"
9815         $LFS getstripe -y $testfile
9816
9817         echo "get/set/list trusted.lov xattr ..." # b=10930
9818         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9819         [[ "$value" =~ "trusted.lov" ]] ||
9820                 error "can't get trusted.lov from $testfile"
9821         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9822                 error "getstripe failed"
9823
9824         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9825
9826         value=$(cut -d= -f2 <<<$value)
9827         # LU-13168: truncated xattr should fail if short lov_user_md header
9828         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9829                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9830         for len in $lens; do
9831                 echo "setfattr $len $testfile.2"
9832                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9833                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9834         done
9835         local stripe_size=$($LFS getstripe -S $testfile.2)
9836         local stripe_count=$($LFS getstripe -c $testfile.2)
9837         [[ $stripe_size -eq 65536 ]] ||
9838                 error "stripe size $stripe_size != 65536"
9839         [[ $stripe_count -eq $stripe_count_orig ]] ||
9840                 error "stripe count $stripe_count != $stripe_count_orig"
9841         rm $testfile $testfile.2
9842 }
9843
9844 test_102b() {
9845         [ -z "$(which setfattr 2>/dev/null)" ] &&
9846                 skip_env "could not find setfattr"
9847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9848
9849         # check plain layout
9850         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9851
9852         # and also check composite layout
9853         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9854
9855 }
9856 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9857
9858 test_102c() {
9859         [ -z "$(which setfattr 2>/dev/null)" ] &&
9860                 skip_env "could not find setfattr"
9861         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9862
9863         # b10930: get/set/list lustre.lov xattr
9864         echo "get/set/list lustre.lov xattr ..."
9865         test_mkdir $DIR/$tdir
9866         chown $RUNAS_ID $DIR/$tdir
9867         local testfile=$DIR/$tdir/$tfile
9868         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9869                 error "setstripe failed"
9870         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9871                 error "getstripe failed"
9872         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9873         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9874
9875         local testfile2=${testfile}2
9876         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9877                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9878
9879         $RUNAS $MCREATE $testfile2
9880         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9881         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9882         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9883         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9884         [ $stripe_count -eq $STRIPECOUNT ] ||
9885                 error "stripe count $stripe_count != $STRIPECOUNT"
9886 }
9887 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9888
9889 compare_stripe_info1() {
9890         local stripe_index_all_zero=true
9891
9892         for num in 1 2 3 4; do
9893                 for count in $(seq 1 $STRIPE_COUNT); do
9894                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9895                                 local size=$((STRIPE_SIZE * num))
9896                                 local file=file"$num-$offset-$count"
9897                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9898                                 [[ $stripe_size -ne $size ]] &&
9899                                     error "$file: size $stripe_size != $size"
9900                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9901                                 # allow fewer stripes to be created, ORI-601
9902                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9903                                     error "$file: count $stripe_count != $count"
9904                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9905                                 [[ $stripe_index -ne 0 ]] &&
9906                                         stripe_index_all_zero=false
9907                         done
9908                 done
9909         done
9910         $stripe_index_all_zero &&
9911                 error "all files are being extracted starting from OST index 0"
9912         return 0
9913 }
9914
9915 have_xattrs_include() {
9916         tar --help | grep -q xattrs-include &&
9917                 echo --xattrs-include="lustre.*"
9918 }
9919
9920 test_102d() {
9921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9923
9924         XINC=$(have_xattrs_include)
9925         setup_test102
9926         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9927         cd $DIR/$tdir/$tdir
9928         compare_stripe_info1
9929 }
9930 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9931
9932 test_102f() {
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9935
9936         XINC=$(have_xattrs_include)
9937         setup_test102
9938         test_mkdir $DIR/$tdir.restore
9939         cd $DIR
9940         tar cf - --xattrs $tdir | tar xf - \
9941                 -C $DIR/$tdir.restore --xattrs $XINC
9942         cd $DIR/$tdir.restore/$tdir
9943         compare_stripe_info1
9944 }
9945 run_test 102f "tar copy files, not keep osts"
9946
9947 grow_xattr() {
9948         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9949                 skip "must have user_xattr"
9950         [ -z "$(which setfattr 2>/dev/null)" ] &&
9951                 skip_env "could not find setfattr"
9952         [ -z "$(which getfattr 2>/dev/null)" ] &&
9953                 skip_env "could not find getfattr"
9954
9955         local xsize=${1:-1024}  # in bytes
9956         local file=$DIR/$tfile
9957         local value="$(generate_string $xsize)"
9958         local xbig=trusted.big
9959         local toobig=$2
9960
9961         touch $file
9962         log "save $xbig on $file"
9963         if [ -z "$toobig" ]
9964         then
9965                 setfattr -n $xbig -v $value $file ||
9966                         error "saving $xbig on $file failed"
9967         else
9968                 setfattr -n $xbig -v $value $file &&
9969                         error "saving $xbig on $file succeeded"
9970                 return 0
9971         fi
9972
9973         local orig=$(get_xattr_value $xbig $file)
9974         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9975
9976         local xsml=trusted.sml
9977         log "save $xsml on $file"
9978         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9979
9980         local new=$(get_xattr_value $xbig $file)
9981         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9982
9983         log "grow $xsml on $file"
9984         setfattr -n $xsml -v "$value" $file ||
9985                 error "growing $xsml on $file failed"
9986
9987         new=$(get_xattr_value $xbig $file)
9988         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9989         log "$xbig still valid after growing $xsml"
9990
9991         rm -f $file
9992 }
9993
9994 test_102h() { # bug 15777
9995         grow_xattr 1024
9996 }
9997 run_test 102h "grow xattr from inside inode to external block"
9998
9999 test_102ha() {
10000         large_xattr_enabled || skip_env "ea_inode feature disabled"
10001
10002         echo "setting xattr of max xattr size: $(max_xattr_size)"
10003         grow_xattr $(max_xattr_size)
10004
10005         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10006         echo "This should fail:"
10007         grow_xattr $(($(max_xattr_size) + 10)) 1
10008 }
10009 run_test 102ha "grow xattr from inside inode to external inode"
10010
10011 test_102i() { # bug 17038
10012         [ -z "$(which getfattr 2>/dev/null)" ] &&
10013                 skip "could not find getfattr"
10014
10015         touch $DIR/$tfile
10016         ln -s $DIR/$tfile $DIR/${tfile}link
10017         getfattr -n trusted.lov $DIR/$tfile ||
10018                 error "lgetxattr on $DIR/$tfile failed"
10019         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10020                 grep -i "no such attr" ||
10021                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10022         rm -f $DIR/$tfile $DIR/${tfile}link
10023 }
10024 run_test 102i "lgetxattr test on symbolic link ============"
10025
10026 test_102j() {
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10029
10030         XINC=$(have_xattrs_include)
10031         setup_test102 "$RUNAS"
10032         chown $RUNAS_ID $DIR/$tdir
10033         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10034         cd $DIR/$tdir/$tdir
10035         compare_stripe_info1 "$RUNAS"
10036 }
10037 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10038
10039 test_102k() {
10040         [ -z "$(which setfattr 2>/dev/null)" ] &&
10041                 skip "could not find setfattr"
10042
10043         touch $DIR/$tfile
10044         # b22187 just check that does not crash for regular file.
10045         setfattr -n trusted.lov $DIR/$tfile
10046         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10047         local test_kdir=$DIR/$tdir
10048         test_mkdir $test_kdir
10049         local default_size=$($LFS getstripe -S $test_kdir)
10050         local default_count=$($LFS getstripe -c $test_kdir)
10051         local default_offset=$($LFS getstripe -i $test_kdir)
10052         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10053                 error 'dir setstripe failed'
10054         setfattr -n trusted.lov $test_kdir
10055         local stripe_size=$($LFS getstripe -S $test_kdir)
10056         local stripe_count=$($LFS getstripe -c $test_kdir)
10057         local stripe_offset=$($LFS getstripe -i $test_kdir)
10058         [ $stripe_size -eq $default_size ] ||
10059                 error "stripe size $stripe_size != $default_size"
10060         [ $stripe_count -eq $default_count ] ||
10061                 error "stripe count $stripe_count != $default_count"
10062         [ $stripe_offset -eq $default_offset ] ||
10063                 error "stripe offset $stripe_offset != $default_offset"
10064         rm -rf $DIR/$tfile $test_kdir
10065 }
10066 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10067
10068 test_102l() {
10069         [ -z "$(which getfattr 2>/dev/null)" ] &&
10070                 skip "could not find getfattr"
10071
10072         # LU-532 trusted. xattr is invisible to non-root
10073         local testfile=$DIR/$tfile
10074
10075         touch $testfile
10076
10077         echo "listxattr as user..."
10078         chown $RUNAS_ID $testfile
10079         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10080             grep -q "trusted" &&
10081                 error "$testfile trusted xattrs are user visible"
10082
10083         return 0;
10084 }
10085 run_test 102l "listxattr size test =================================="
10086
10087 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10088         local path=$DIR/$tfile
10089         touch $path
10090
10091         listxattr_size_check $path || error "listattr_size_check $path failed"
10092 }
10093 run_test 102m "Ensure listxattr fails on small bufffer ========"
10094
10095 cleanup_test102
10096
10097 getxattr() { # getxattr path name
10098         # Return the base64 encoding of the value of xattr name on path.
10099         local path=$1
10100         local name=$2
10101
10102         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10103         # file: $path
10104         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10105         #
10106         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10107
10108         getfattr --absolute-names --encoding=base64 --name=$name $path |
10109                 awk -F= -v name=$name '$1 == name {
10110                         print substr($0, index($0, "=") + 1);
10111         }'
10112 }
10113
10114 test_102n() { # LU-4101 mdt: protect internal xattrs
10115         [ -z "$(which setfattr 2>/dev/null)" ] &&
10116                 skip "could not find setfattr"
10117         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10118         then
10119                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10120         fi
10121
10122         local file0=$DIR/$tfile.0
10123         local file1=$DIR/$tfile.1
10124         local xattr0=$TMP/$tfile.0
10125         local xattr1=$TMP/$tfile.1
10126         local namelist="lov lma lmv link fid version som hsm"
10127         local name
10128         local value
10129
10130         rm -rf $file0 $file1 $xattr0 $xattr1
10131         touch $file0 $file1
10132
10133         # Get 'before' xattrs of $file1.
10134         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10135
10136         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10137                 namelist+=" lfsck_namespace"
10138         for name in $namelist; do
10139                 # Try to copy xattr from $file0 to $file1.
10140                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10141
10142                 setfattr --name=trusted.$name --value="$value" $file1 ||
10143                         error "setxattr 'trusted.$name' failed"
10144
10145                 # Try to set a garbage xattr.
10146                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10147
10148                 if [[ x$name == "xlov" ]]; then
10149                         setfattr --name=trusted.lov --value="$value" $file1 &&
10150                         error "setxattr invalid 'trusted.lov' success"
10151                 else
10152                         setfattr --name=trusted.$name --value="$value" $file1 ||
10153                                 error "setxattr invalid 'trusted.$name' failed"
10154                 fi
10155
10156                 # Try to remove the xattr from $file1. We don't care if this
10157                 # appears to succeed or fail, we just don't want there to be
10158                 # any changes or crashes.
10159                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10160         done
10161
10162         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10163         then
10164                 name="lfsck_ns"
10165                 # Try to copy xattr from $file0 to $file1.
10166                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10167
10168                 setfattr --name=trusted.$name --value="$value" $file1 ||
10169                         error "setxattr 'trusted.$name' failed"
10170
10171                 # Try to set a garbage xattr.
10172                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10173
10174                 setfattr --name=trusted.$name --value="$value" $file1 ||
10175                         error "setxattr 'trusted.$name' failed"
10176
10177                 # Try to remove the xattr from $file1. We don't care if this
10178                 # appears to succeed or fail, we just don't want there to be
10179                 # any changes or crashes.
10180                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10181         fi
10182
10183         # Get 'after' xattrs of file1.
10184         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10185
10186         if ! diff $xattr0 $xattr1; then
10187                 error "before and after xattrs of '$file1' differ"
10188         fi
10189
10190         rm -rf $file0 $file1 $xattr0 $xattr1
10191
10192         return 0
10193 }
10194 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10195
10196 test_102p() { # LU-4703 setxattr did not check ownership
10197         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10198                 skip "MDS needs to be at least 2.5.56"
10199
10200         local testfile=$DIR/$tfile
10201
10202         touch $testfile
10203
10204         echo "setfacl as user..."
10205         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10206         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10207
10208         echo "setfattr as user..."
10209         setfacl -m "u:$RUNAS_ID:---" $testfile
10210         $RUNAS setfattr -x system.posix_acl_access $testfile
10211         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10212 }
10213 run_test 102p "check setxattr(2) correctly fails without permission"
10214
10215 test_102q() {
10216         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10217                 skip "MDS needs to be at least 2.6.92"
10218
10219         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10220 }
10221 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10222
10223 test_102r() {
10224         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10225                 skip "MDS needs to be at least 2.6.93"
10226
10227         touch $DIR/$tfile || error "touch"
10228         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10229         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10230         rm $DIR/$tfile || error "rm"
10231
10232         #normal directory
10233         mkdir -p $DIR/$tdir || error "mkdir"
10234         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10235         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10236         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10237                 error "$testfile error deleting user.author1"
10238         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10239                 grep "user.$(basename $tdir)" &&
10240                 error "$tdir did not delete user.$(basename $tdir)"
10241         rmdir $DIR/$tdir || error "rmdir"
10242
10243         #striped directory
10244         test_mkdir $DIR/$tdir
10245         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10246         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10247         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10248                 error "$testfile error deleting user.author1"
10249         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10250                 grep "user.$(basename $tdir)" &&
10251                 error "$tdir did not delete user.$(basename $tdir)"
10252         rmdir $DIR/$tdir || error "rm striped dir"
10253 }
10254 run_test 102r "set EAs with empty values"
10255
10256 test_102s() {
10257         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10258                 skip "MDS needs to be at least 2.11.52"
10259
10260         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10261
10262         save_lustre_params client "llite.*.xattr_cache" > $save
10263
10264         for cache in 0 1; do
10265                 lctl set_param llite.*.xattr_cache=$cache
10266
10267                 rm -f $DIR/$tfile
10268                 touch $DIR/$tfile || error "touch"
10269                 for prefix in lustre security system trusted user; do
10270                         # Note getxattr() may fail with 'Operation not
10271                         # supported' or 'No such attribute' depending
10272                         # on prefix and cache.
10273                         getfattr -n $prefix.n102s $DIR/$tfile &&
10274                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10275                 done
10276         done
10277
10278         restore_lustre_params < $save
10279 }
10280 run_test 102s "getting nonexistent xattrs should fail"
10281
10282 test_102t() {
10283         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10284                 skip "MDS needs to be at least 2.11.52"
10285
10286         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10287
10288         save_lustre_params client "llite.*.xattr_cache" > $save
10289
10290         for cache in 0 1; do
10291                 lctl set_param llite.*.xattr_cache=$cache
10292
10293                 for buf_size in 0 256; do
10294                         rm -f $DIR/$tfile
10295                         touch $DIR/$tfile || error "touch"
10296                         setfattr -n user.multiop $DIR/$tfile
10297                         $MULTIOP $DIR/$tfile oa$buf_size ||
10298                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10299                 done
10300         done
10301
10302         restore_lustre_params < $save
10303 }
10304 run_test 102t "zero length xattr values handled correctly"
10305
10306 run_acl_subtest()
10307 {
10308     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10309     return $?
10310 }
10311
10312 test_103a() {
10313         [ "$UID" != 0 ] && skip "must run as root"
10314         $GSS && skip_env "could not run under gss"
10315         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10316                 skip_env "must have acl enabled"
10317         [ -z "$(which setfacl 2>/dev/null)" ] &&
10318                 skip_env "could not find setfacl"
10319         remote_mds_nodsh && skip "remote MDS with nodsh"
10320
10321         gpasswd -a daemon bin                           # LU-5641
10322         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10323
10324         declare -a identity_old
10325
10326         for num in $(seq $MDSCOUNT); do
10327                 switch_identity $num true || identity_old[$num]=$?
10328         done
10329
10330         SAVE_UMASK=$(umask)
10331         umask 0022
10332         mkdir -p $DIR/$tdir
10333         cd $DIR/$tdir
10334
10335         echo "performing cp ..."
10336         run_acl_subtest cp || error "run_acl_subtest cp failed"
10337         echo "performing getfacl-noacl..."
10338         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10339         echo "performing misc..."
10340         run_acl_subtest misc || error  "misc test failed"
10341         echo "performing permissions..."
10342         run_acl_subtest permissions || error "permissions failed"
10343         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10344         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10345                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10346                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10347         then
10348                 echo "performing permissions xattr..."
10349                 run_acl_subtest permissions_xattr ||
10350                         error "permissions_xattr failed"
10351         fi
10352         echo "performing setfacl..."
10353         run_acl_subtest setfacl || error  "setfacl test failed"
10354
10355         # inheritance test got from HP
10356         echo "performing inheritance..."
10357         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10358         chmod +x make-tree || error "chmod +x failed"
10359         run_acl_subtest inheritance || error "inheritance test failed"
10360         rm -f make-tree
10361
10362         echo "LU-974 ignore umask when acl is enabled..."
10363         run_acl_subtest 974 || error "LU-974 umask test failed"
10364         if [ $MDSCOUNT -ge 2 ]; then
10365                 run_acl_subtest 974_remote ||
10366                         error "LU-974 umask test failed under remote dir"
10367         fi
10368
10369         echo "LU-2561 newly created file is same size as directory..."
10370         if [ "$mds1_FSTYPE" != "zfs" ]; then
10371                 run_acl_subtest 2561 || error "LU-2561 test failed"
10372         else
10373                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10374         fi
10375
10376         run_acl_subtest 4924 || error "LU-4924 test failed"
10377
10378         cd $SAVE_PWD
10379         umask $SAVE_UMASK
10380
10381         for num in $(seq $MDSCOUNT); do
10382                 if [ "${identity_old[$num]}" = 1 ]; then
10383                         switch_identity $num false || identity_old[$num]=$?
10384                 fi
10385         done
10386 }
10387 run_test 103a "acl test"
10388
10389 test_103b() {
10390         declare -a pids
10391         local U
10392
10393         for U in {0..511}; do
10394                 {
10395                 local O=$(printf "%04o" $U)
10396
10397                 umask $(printf "%04o" $((511 ^ $O)))
10398                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10399                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10400
10401                 (( $S == ($O & 0666) )) ||
10402                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10403
10404                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10405                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10406                 (( $S == ($O & 0666) )) ||
10407                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10408
10409                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10410                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10411                 (( $S == ($O & 0666) )) ||
10412                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10413                 rm -f $DIR/$tfile.[smp]$0
10414                 } &
10415                 local pid=$!
10416
10417                 # limit the concurrently running threads to 64. LU-11878
10418                 local idx=$((U % 64))
10419                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10420                 pids[idx]=$pid
10421         done
10422         wait
10423 }
10424 run_test 103b "umask lfs setstripe"
10425
10426 test_103c() {
10427         mkdir -p $DIR/$tdir
10428         cp -rp $DIR/$tdir $DIR/$tdir.bak
10429
10430         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10431                 error "$DIR/$tdir shouldn't contain default ACL"
10432         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10433                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10434         true
10435 }
10436 run_test 103c "'cp -rp' won't set empty acl"
10437
10438 test_104a() {
10439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10440
10441         touch $DIR/$tfile
10442         lfs df || error "lfs df failed"
10443         lfs df -ih || error "lfs df -ih failed"
10444         lfs df -h $DIR || error "lfs df -h $DIR failed"
10445         lfs df -i $DIR || error "lfs df -i $DIR failed"
10446         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10447         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10448
10449         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10450         lctl --device %$OSC deactivate
10451         lfs df || error "lfs df with deactivated OSC failed"
10452         lctl --device %$OSC activate
10453         # wait the osc back to normal
10454         wait_osc_import_ready client ost
10455
10456         lfs df || error "lfs df with reactivated OSC failed"
10457         rm -f $DIR/$tfile
10458 }
10459 run_test 104a "lfs df [-ih] [path] test ========================="
10460
10461 test_104b() {
10462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10463         [ $RUNAS_ID -eq $UID ] &&
10464                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10465
10466         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10467                         grep "Permission denied" | wc -l)))
10468         if [ $denied_cnt -ne 0 ]; then
10469                 error "lfs check servers test failed"
10470         fi
10471 }
10472 run_test 104b "$RUNAS lfs check servers test ===================="
10473
10474 test_105a() {
10475         # doesn't work on 2.4 kernels
10476         touch $DIR/$tfile
10477         if $(flock_is_enabled); then
10478                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10479         else
10480                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10481         fi
10482         rm -f $DIR/$tfile
10483 }
10484 run_test 105a "flock when mounted without -o flock test ========"
10485
10486 test_105b() {
10487         touch $DIR/$tfile
10488         if $(flock_is_enabled); then
10489                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10490         else
10491                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10492         fi
10493         rm -f $DIR/$tfile
10494 }
10495 run_test 105b "fcntl when mounted without -o flock test ========"
10496
10497 test_105c() {
10498         touch $DIR/$tfile
10499         if $(flock_is_enabled); then
10500                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10501         else
10502                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10503         fi
10504         rm -f $DIR/$tfile
10505 }
10506 run_test 105c "lockf when mounted without -o flock test"
10507
10508 test_105d() { # bug 15924
10509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10510
10511         test_mkdir $DIR/$tdir
10512         flock_is_enabled || skip_env "mount w/o flock enabled"
10513         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10514         $LCTL set_param fail_loc=0x80000315
10515         flocks_test 2 $DIR/$tdir
10516 }
10517 run_test 105d "flock race (should not freeze) ========"
10518
10519 test_105e() { # bug 22660 && 22040
10520         flock_is_enabled || skip_env "mount w/o flock enabled"
10521
10522         touch $DIR/$tfile
10523         flocks_test 3 $DIR/$tfile
10524 }
10525 run_test 105e "Two conflicting flocks from same process"
10526
10527 test_106() { #bug 10921
10528         test_mkdir $DIR/$tdir
10529         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10530         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10531 }
10532 run_test 106 "attempt exec of dir followed by chown of that dir"
10533
10534 test_107() {
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536
10537         CDIR=`pwd`
10538         local file=core
10539
10540         cd $DIR
10541         rm -f $file
10542
10543         local save_pattern=$(sysctl -n kernel.core_pattern)
10544         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10545         sysctl -w kernel.core_pattern=$file
10546         sysctl -w kernel.core_uses_pid=0
10547
10548         ulimit -c unlimited
10549         sleep 60 &
10550         SLEEPPID=$!
10551
10552         sleep 1
10553
10554         kill -s 11 $SLEEPPID
10555         wait $SLEEPPID
10556         if [ -e $file ]; then
10557                 size=`stat -c%s $file`
10558                 [ $size -eq 0 ] && error "Fail to create core file $file"
10559         else
10560                 error "Fail to create core file $file"
10561         fi
10562         rm -f $file
10563         sysctl -w kernel.core_pattern=$save_pattern
10564         sysctl -w kernel.core_uses_pid=$save_uses_pid
10565         cd $CDIR
10566 }
10567 run_test 107 "Coredump on SIG"
10568
10569 test_110() {
10570         test_mkdir $DIR/$tdir
10571         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10572         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10573                 error "mkdir with 256 char should fail, but did not"
10574         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10575                 error "create with 255 char failed"
10576         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10577                 error "create with 256 char should fail, but did not"
10578
10579         ls -l $DIR/$tdir
10580         rm -rf $DIR/$tdir
10581 }
10582 run_test 110 "filename length checking"
10583
10584 #
10585 # Purpose: To verify dynamic thread (OSS) creation.
10586 #
10587 test_115() {
10588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10589         remote_ost_nodsh && skip "remote OST with nodsh"
10590
10591         # Lustre does not stop service threads once they are started.
10592         # Reset number of running threads to default.
10593         stopall
10594         setupall
10595
10596         local OSTIO_pre
10597         local save_params="$TMP/sanity-$TESTNAME.parameters"
10598
10599         # Get ll_ost_io count before I/O
10600         OSTIO_pre=$(do_facet ost1 \
10601                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10602         # Exit if lustre is not running (ll_ost_io not running).
10603         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10604
10605         echo "Starting with $OSTIO_pre threads"
10606         local thread_max=$((OSTIO_pre * 2))
10607         local rpc_in_flight=$((thread_max * 2))
10608         # Number of I/O Process proposed to be started.
10609         local nfiles
10610         local facets=$(get_facets OST)
10611
10612         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10613         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10614
10615         # Set in_flight to $rpc_in_flight
10616         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10617                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10618         nfiles=${rpc_in_flight}
10619         # Set ost thread_max to $thread_max
10620         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10621
10622         # 5 Minutes should be sufficient for max number of OSS
10623         # threads(thread_max) to be created.
10624         local timeout=300
10625
10626         # Start I/O.
10627         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10628         test_mkdir $DIR/$tdir
10629         for i in $(seq $nfiles); do
10630                 local file=$DIR/$tdir/${tfile}-$i
10631                 $LFS setstripe -c -1 -i 0 $file
10632                 ($WTL $file $timeout)&
10633         done
10634
10635         # I/O Started - Wait for thread_started to reach thread_max or report
10636         # error if thread_started is more than thread_max.
10637         echo "Waiting for thread_started to reach thread_max"
10638         local thread_started=0
10639         local end_time=$((SECONDS + timeout))
10640
10641         while [ $SECONDS -le $end_time ] ; do
10642                 echo -n "."
10643                 # Get ost i/o thread_started count.
10644                 thread_started=$(do_facet ost1 \
10645                         "$LCTL get_param \
10646                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10647                 # Break out if thread_started is equal/greater than thread_max
10648                 if [[ $thread_started -ge $thread_max ]]; then
10649                         echo ll_ost_io thread_started $thread_started, \
10650                                 equal/greater than thread_max $thread_max
10651                         break
10652                 fi
10653                 sleep 1
10654         done
10655
10656         # Cleanup - We have the numbers, Kill i/o jobs if running.
10657         jobcount=($(jobs -p))
10658         for i in $(seq 0 $((${#jobcount[@]}-1)))
10659         do
10660                 kill -9 ${jobcount[$i]}
10661                 if [ $? -ne 0 ] ; then
10662                         echo Warning: \
10663                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10664                 fi
10665         done
10666
10667         # Cleanup files left by WTL binary.
10668         for i in $(seq $nfiles); do
10669                 local file=$DIR/$tdir/${tfile}-$i
10670                 rm -rf $file
10671                 if [ $? -ne 0 ] ; then
10672                         echo "Warning: Failed to delete file $file"
10673                 fi
10674         done
10675
10676         restore_lustre_params <$save_params
10677         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10678
10679         # Error out if no new thread has started or Thread started is greater
10680         # than thread max.
10681         if [[ $thread_started -le $OSTIO_pre ||
10682                         $thread_started -gt $thread_max ]]; then
10683                 error "ll_ost_io: thread_started $thread_started" \
10684                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10685                       "No new thread started or thread started greater " \
10686                       "than thread_max."
10687         fi
10688 }
10689 run_test 115 "verify dynamic thread creation===================="
10690
10691 free_min_max () {
10692         wait_delete_completed
10693         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10694         echo "OST kbytes available: ${AVAIL[@]}"
10695         MAXV=${AVAIL[0]}
10696         MAXI=0
10697         MINV=${AVAIL[0]}
10698         MINI=0
10699         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10700                 #echo OST $i: ${AVAIL[i]}kb
10701                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10702                         MAXV=${AVAIL[i]}
10703                         MAXI=$i
10704                 fi
10705                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10706                         MINV=${AVAIL[i]}
10707                         MINI=$i
10708                 fi
10709         done
10710         echo "Min free space: OST $MINI: $MINV"
10711         echo "Max free space: OST $MAXI: $MAXV"
10712 }
10713
10714 test_116a() { # was previously test_116()
10715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10716         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10717         remote_mds_nodsh && skip "remote MDS with nodsh"
10718
10719         echo -n "Free space priority "
10720         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10721                 head -n1
10722         declare -a AVAIL
10723         free_min_max
10724
10725         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10726         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10727         trap simple_cleanup_common EXIT
10728
10729         # Check if we need to generate uneven OSTs
10730         test_mkdir -p $DIR/$tdir/OST${MINI}
10731         local FILL=$((MINV / 4))
10732         local DIFF=$((MAXV - MINV))
10733         local DIFF2=$((DIFF * 100 / MINV))
10734
10735         local threshold=$(do_facet $SINGLEMDS \
10736                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10737         threshold=${threshold%%%}
10738         echo -n "Check for uneven OSTs: "
10739         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10740
10741         if [[ $DIFF2 -gt $threshold ]]; then
10742                 echo "ok"
10743                 echo "Don't need to fill OST$MINI"
10744         else
10745                 # generate uneven OSTs. Write 2% over the QOS threshold value
10746                 echo "no"
10747                 DIFF=$((threshold - DIFF2 + 2))
10748                 DIFF2=$((MINV * DIFF / 100))
10749                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10750                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10751                         error "setstripe failed"
10752                 DIFF=$((DIFF2 / 2048))
10753                 i=0
10754                 while [ $i -lt $DIFF ]; do
10755                         i=$((i + 1))
10756                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10757                                 bs=2M count=1 2>/dev/null
10758                         echo -n .
10759                 done
10760                 echo .
10761                 sync
10762                 sleep_maxage
10763                 free_min_max
10764         fi
10765
10766         DIFF=$((MAXV - MINV))
10767         DIFF2=$((DIFF * 100 / MINV))
10768         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10769         if [ $DIFF2 -gt $threshold ]; then
10770                 echo "ok"
10771         else
10772                 echo "failed - QOS mode won't be used"
10773                 simple_cleanup_common
10774                 skip "QOS imbalance criteria not met"
10775         fi
10776
10777         MINI1=$MINI
10778         MINV1=$MINV
10779         MAXI1=$MAXI
10780         MAXV1=$MAXV
10781
10782         # now fill using QOS
10783         $LFS setstripe -c 1 $DIR/$tdir
10784         FILL=$((FILL / 200))
10785         if [ $FILL -gt 600 ]; then
10786                 FILL=600
10787         fi
10788         echo "writing $FILL files to QOS-assigned OSTs"
10789         i=0
10790         while [ $i -lt $FILL ]; do
10791                 i=$((i + 1))
10792                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10793                         count=1 2>/dev/null
10794                 echo -n .
10795         done
10796         echo "wrote $i 200k files"
10797         sync
10798         sleep_maxage
10799
10800         echo "Note: free space may not be updated, so measurements might be off"
10801         free_min_max
10802         DIFF2=$((MAXV - MINV))
10803         echo "free space delta: orig $DIFF final $DIFF2"
10804         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10805         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10806         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10807         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10808         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10809         if [[ $DIFF -gt 0 ]]; then
10810                 FILL=$((DIFF2 * 100 / DIFF - 100))
10811                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10812         fi
10813
10814         # Figure out which files were written where
10815         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10816                awk '/'$MINI1': / {print $2; exit}')
10817         echo $UUID
10818         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10819         echo "$MINC files created on smaller OST $MINI1"
10820         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10821                awk '/'$MAXI1': / {print $2; exit}')
10822         echo $UUID
10823         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10824         echo "$MAXC files created on larger OST $MAXI1"
10825         if [[ $MINC -gt 0 ]]; then
10826                 FILL=$((MAXC * 100 / MINC - 100))
10827                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10828         fi
10829         [[ $MAXC -gt $MINC ]] ||
10830                 error_ignore LU-9 "stripe QOS didn't balance free space"
10831         simple_cleanup_common
10832 }
10833 run_test 116a "stripe QOS: free space balance ==================="
10834
10835 test_116b() { # LU-2093
10836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10837         remote_mds_nodsh && skip "remote MDS with nodsh"
10838
10839 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10840         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10841                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10842         [ -z "$old_rr" ] && skip "no QOS"
10843         do_facet $SINGLEMDS lctl set_param \
10844                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10845         mkdir -p $DIR/$tdir
10846         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10847         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10848         do_facet $SINGLEMDS lctl set_param fail_loc=0
10849         rm -rf $DIR/$tdir
10850         do_facet $SINGLEMDS lctl set_param \
10851                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10852 }
10853 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10854
10855 test_117() # bug 10891
10856 {
10857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10858
10859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10860         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10861         lctl set_param fail_loc=0x21e
10862         > $DIR/$tfile || error "truncate failed"
10863         lctl set_param fail_loc=0
10864         echo "Truncate succeeded."
10865         rm -f $DIR/$tfile
10866 }
10867 run_test 117 "verify osd extend =========="
10868
10869 NO_SLOW_RESENDCOUNT=4
10870 export OLD_RESENDCOUNT=""
10871 set_resend_count () {
10872         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10873         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10874         lctl set_param -n $PROC_RESENDCOUNT $1
10875         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10876 }
10877
10878 # for reduce test_118* time (b=14842)
10879 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10880
10881 # Reset async IO behavior after error case
10882 reset_async() {
10883         FILE=$DIR/reset_async
10884
10885         # Ensure all OSCs are cleared
10886         $LFS setstripe -c -1 $FILE
10887         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10888         sync
10889         rm $FILE
10890 }
10891
10892 test_118a() #bug 11710
10893 {
10894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10895
10896         reset_async
10897
10898         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10899         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10900         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10901
10902         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10903                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10904                 return 1;
10905         fi
10906         rm -f $DIR/$tfile
10907 }
10908 run_test 118a "verify O_SYNC works =========="
10909
10910 test_118b()
10911 {
10912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10913         remote_ost_nodsh && skip "remote OST with nodsh"
10914
10915         reset_async
10916
10917         #define OBD_FAIL_SRV_ENOENT 0x217
10918         set_nodes_failloc "$(osts_nodes)" 0x217
10919         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10920         RC=$?
10921         set_nodes_failloc "$(osts_nodes)" 0
10922         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10923         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10924                     grep -c writeback)
10925
10926         if [[ $RC -eq 0 ]]; then
10927                 error "Must return error due to dropped pages, rc=$RC"
10928                 return 1;
10929         fi
10930
10931         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10932                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10933                 return 1;
10934         fi
10935
10936         echo "Dirty pages not leaked on ENOENT"
10937
10938         # Due to the above error the OSC will issue all RPCs syncronously
10939         # until a subsequent RPC completes successfully without error.
10940         $MULTIOP $DIR/$tfile Ow4096yc
10941         rm -f $DIR/$tfile
10942
10943         return 0
10944 }
10945 run_test 118b "Reclaim dirty pages on fatal error =========="
10946
10947 test_118c()
10948 {
10949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10950
10951         # for 118c, restore the original resend count, LU-1940
10952         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10953                                 set_resend_count $OLD_RESENDCOUNT
10954         remote_ost_nodsh && skip "remote OST with nodsh"
10955
10956         reset_async
10957
10958         #define OBD_FAIL_OST_EROFS               0x216
10959         set_nodes_failloc "$(osts_nodes)" 0x216
10960
10961         # multiop should block due to fsync until pages are written
10962         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10963         MULTIPID=$!
10964         sleep 1
10965
10966         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10967                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10968         fi
10969
10970         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10971                     grep -c writeback)
10972         if [[ $WRITEBACK -eq 0 ]]; then
10973                 error "No page in writeback, writeback=$WRITEBACK"
10974         fi
10975
10976         set_nodes_failloc "$(osts_nodes)" 0
10977         wait $MULTIPID
10978         RC=$?
10979         if [[ $RC -ne 0 ]]; then
10980                 error "Multiop fsync failed, rc=$RC"
10981         fi
10982
10983         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10984         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10985                     grep -c writeback)
10986         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10987                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10988         fi
10989
10990         rm -f $DIR/$tfile
10991         echo "Dirty pages flushed via fsync on EROFS"
10992         return 0
10993 }
10994 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10995
10996 # continue to use small resend count to reduce test_118* time (b=14842)
10997 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10998
10999 test_118d()
11000 {
11001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11002         remote_ost_nodsh && skip "remote OST with nodsh"
11003
11004         reset_async
11005
11006         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11007         set_nodes_failloc "$(osts_nodes)" 0x214
11008         # multiop should block due to fsync until pages are written
11009         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11010         MULTIPID=$!
11011         sleep 1
11012
11013         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11014                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11015         fi
11016
11017         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11018                     grep -c writeback)
11019         if [[ $WRITEBACK -eq 0 ]]; then
11020                 error "No page in writeback, writeback=$WRITEBACK"
11021         fi
11022
11023         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11024         set_nodes_failloc "$(osts_nodes)" 0
11025
11026         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11027         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11028                     grep -c writeback)
11029         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11030                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11031         fi
11032
11033         rm -f $DIR/$tfile
11034         echo "Dirty pages gaurenteed flushed via fsync"
11035         return 0
11036 }
11037 run_test 118d "Fsync validation inject a delay of the bulk =========="
11038
11039 test_118f() {
11040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11041
11042         reset_async
11043
11044         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11045         lctl set_param fail_loc=0x8000040a
11046
11047         # Should simulate EINVAL error which is fatal
11048         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11049         RC=$?
11050         if [[ $RC -eq 0 ]]; then
11051                 error "Must return error due to dropped pages, rc=$RC"
11052         fi
11053
11054         lctl set_param fail_loc=0x0
11055
11056         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11057         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11058         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11059                     grep -c writeback)
11060         if [[ $LOCKED -ne 0 ]]; then
11061                 error "Locked pages remain in cache, locked=$LOCKED"
11062         fi
11063
11064         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11065                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11066         fi
11067
11068         rm -f $DIR/$tfile
11069         echo "No pages locked after fsync"
11070
11071         reset_async
11072         return 0
11073 }
11074 run_test 118f "Simulate unrecoverable OSC side error =========="
11075
11076 test_118g() {
11077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11078
11079         reset_async
11080
11081         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11082         lctl set_param fail_loc=0x406
11083
11084         # simulate local -ENOMEM
11085         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11086         RC=$?
11087
11088         lctl set_param fail_loc=0
11089         if [[ $RC -eq 0 ]]; then
11090                 error "Must return error due to dropped pages, rc=$RC"
11091         fi
11092
11093         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11094         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11095         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11096                         grep -c writeback)
11097         if [[ $LOCKED -ne 0 ]]; then
11098                 error "Locked pages remain in cache, locked=$LOCKED"
11099         fi
11100
11101         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11102                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11103         fi
11104
11105         rm -f $DIR/$tfile
11106         echo "No pages locked after fsync"
11107
11108         reset_async
11109         return 0
11110 }
11111 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11112
11113 test_118h() {
11114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11115         remote_ost_nodsh && skip "remote OST with nodsh"
11116
11117         reset_async
11118
11119         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11120         set_nodes_failloc "$(osts_nodes)" 0x20e
11121         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11122         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11123         RC=$?
11124
11125         set_nodes_failloc "$(osts_nodes)" 0
11126         if [[ $RC -eq 0 ]]; then
11127                 error "Must return error due to dropped pages, rc=$RC"
11128         fi
11129
11130         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11131         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11132         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11133                     grep -c writeback)
11134         if [[ $LOCKED -ne 0 ]]; then
11135                 error "Locked pages remain in cache, locked=$LOCKED"
11136         fi
11137
11138         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11139                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11140         fi
11141
11142         rm -f $DIR/$tfile
11143         echo "No pages locked after fsync"
11144
11145         return 0
11146 }
11147 run_test 118h "Verify timeout in handling recoverables errors  =========="
11148
11149 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11150
11151 test_118i() {
11152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11153         remote_ost_nodsh && skip "remote OST with nodsh"
11154
11155         reset_async
11156
11157         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11158         set_nodes_failloc "$(osts_nodes)" 0x20e
11159
11160         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11161         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11162         PID=$!
11163         sleep 5
11164         set_nodes_failloc "$(osts_nodes)" 0
11165
11166         wait $PID
11167         RC=$?
11168         if [[ $RC -ne 0 ]]; then
11169                 error "got error, but should be not, rc=$RC"
11170         fi
11171
11172         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11173         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11174         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11175         if [[ $LOCKED -ne 0 ]]; then
11176                 error "Locked pages remain in cache, locked=$LOCKED"
11177         fi
11178
11179         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11180                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11181         fi
11182
11183         rm -f $DIR/$tfile
11184         echo "No pages locked after fsync"
11185
11186         return 0
11187 }
11188 run_test 118i "Fix error before timeout in recoverable error  =========="
11189
11190 [ "$SLOW" = "no" ] && set_resend_count 4
11191
11192 test_118j() {
11193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11194         remote_ost_nodsh && skip "remote OST with nodsh"
11195
11196         reset_async
11197
11198         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11199         set_nodes_failloc "$(osts_nodes)" 0x220
11200
11201         # return -EIO from OST
11202         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11203         RC=$?
11204         set_nodes_failloc "$(osts_nodes)" 0x0
11205         if [[ $RC -eq 0 ]]; then
11206                 error "Must return error due to dropped pages, rc=$RC"
11207         fi
11208
11209         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11210         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11211         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11212         if [[ $LOCKED -ne 0 ]]; then
11213                 error "Locked pages remain in cache, locked=$LOCKED"
11214         fi
11215
11216         # in recoverable error on OST we want resend and stay until it finished
11217         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11218                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11219         fi
11220
11221         rm -f $DIR/$tfile
11222         echo "No pages locked after fsync"
11223
11224         return 0
11225 }
11226 run_test 118j "Simulate unrecoverable OST side error =========="
11227
11228 test_118k()
11229 {
11230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11231         remote_ost_nodsh && skip "remote OSTs with nodsh"
11232
11233         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11234         set_nodes_failloc "$(osts_nodes)" 0x20e
11235         test_mkdir $DIR/$tdir
11236
11237         for ((i=0;i<10;i++)); do
11238                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11239                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11240                 SLEEPPID=$!
11241                 sleep 0.500s
11242                 kill $SLEEPPID
11243                 wait $SLEEPPID
11244         done
11245
11246         set_nodes_failloc "$(osts_nodes)" 0
11247         rm -rf $DIR/$tdir
11248 }
11249 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11250
11251 test_118l() # LU-646
11252 {
11253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11254
11255         test_mkdir $DIR/$tdir
11256         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11257         rm -rf $DIR/$tdir
11258 }
11259 run_test 118l "fsync dir"
11260
11261 test_118m() # LU-3066
11262 {
11263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11264
11265         test_mkdir $DIR/$tdir
11266         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11267         rm -rf $DIR/$tdir
11268 }
11269 run_test 118m "fdatasync dir ========="
11270
11271 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11272
11273 test_118n()
11274 {
11275         local begin
11276         local end
11277
11278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11279         remote_ost_nodsh && skip "remote OSTs with nodsh"
11280
11281         # Sleep to avoid a cached response.
11282         #define OBD_STATFS_CACHE_SECONDS 1
11283         sleep 2
11284
11285         # Inject a 10 second delay in the OST_STATFS handler.
11286         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11287         set_nodes_failloc "$(osts_nodes)" 0x242
11288
11289         begin=$SECONDS
11290         stat --file-system $MOUNT > /dev/null
11291         end=$SECONDS
11292
11293         set_nodes_failloc "$(osts_nodes)" 0
11294
11295         if ((end - begin > 20)); then
11296             error "statfs took $((end - begin)) seconds, expected 10"
11297         fi
11298 }
11299 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11300
11301 test_119a() # bug 11737
11302 {
11303         BSIZE=$((512 * 1024))
11304         directio write $DIR/$tfile 0 1 $BSIZE
11305         # We ask to read two blocks, which is more than a file size.
11306         # directio will indicate an error when requested and actual
11307         # sizes aren't equeal (a normal situation in this case) and
11308         # print actual read amount.
11309         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11310         if [ "$NOB" != "$BSIZE" ]; then
11311                 error "read $NOB bytes instead of $BSIZE"
11312         fi
11313         rm -f $DIR/$tfile
11314 }
11315 run_test 119a "Short directIO read must return actual read amount"
11316
11317 test_119b() # bug 11737
11318 {
11319         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11320
11321         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11322         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11323         sync
11324         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11325                 error "direct read failed"
11326         rm -f $DIR/$tfile
11327 }
11328 run_test 119b "Sparse directIO read must return actual read amount"
11329
11330 test_119c() # bug 13099
11331 {
11332         BSIZE=1048576
11333         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11334         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11335         rm -f $DIR/$tfile
11336 }
11337 run_test 119c "Testing for direct read hitting hole"
11338
11339 test_119d() # bug 15950
11340 {
11341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11342
11343         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11344         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11345         BSIZE=1048576
11346         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11347         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11348         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11349         lctl set_param fail_loc=0x40d
11350         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11351         pid_dio=$!
11352         sleep 1
11353         cat $DIR/$tfile > /dev/null &
11354         lctl set_param fail_loc=0
11355         pid_reads=$!
11356         wait $pid_dio
11357         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11358         sleep 2
11359         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11360         error "the read rpcs have not completed in 2s"
11361         rm -f $DIR/$tfile
11362         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11363 }
11364 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11365
11366 test_120a() {
11367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11368         remote_mds_nodsh && skip "remote MDS with nodsh"
11369         test_mkdir -i0 -c1 $DIR/$tdir
11370         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11371                 skip_env "no early lock cancel on server"
11372
11373         lru_resize_disable mdc
11374         lru_resize_disable osc
11375         cancel_lru_locks mdc
11376         # asynchronous object destroy at MDT could cause bl ast to client
11377         cancel_lru_locks osc
11378
11379         stat $DIR/$tdir > /dev/null
11380         can1=$(do_facet mds1 \
11381                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11382                awk '/ldlm_cancel/ {print $2}')
11383         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11384                awk '/ldlm_bl_callback/ {print $2}')
11385         test_mkdir -i0 -c1 $DIR/$tdir/d1
11386         can2=$(do_facet mds1 \
11387                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11388                awk '/ldlm_cancel/ {print $2}')
11389         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11390                awk '/ldlm_bl_callback/ {print $2}')
11391         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11392         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11393         lru_resize_enable mdc
11394         lru_resize_enable osc
11395 }
11396 run_test 120a "Early Lock Cancel: mkdir test"
11397
11398 test_120b() {
11399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11400         remote_mds_nodsh && skip "remote MDS with nodsh"
11401         test_mkdir $DIR/$tdir
11402         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11403                 skip_env "no early lock cancel on server"
11404
11405         lru_resize_disable mdc
11406         lru_resize_disable osc
11407         cancel_lru_locks mdc
11408         stat $DIR/$tdir > /dev/null
11409         can1=$(do_facet $SINGLEMDS \
11410                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11411                awk '/ldlm_cancel/ {print $2}')
11412         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11413                awk '/ldlm_bl_callback/ {print $2}')
11414         touch $DIR/$tdir/f1
11415         can2=$(do_facet $SINGLEMDS \
11416                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11417                awk '/ldlm_cancel/ {print $2}')
11418         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11419                awk '/ldlm_bl_callback/ {print $2}')
11420         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11421         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11422         lru_resize_enable mdc
11423         lru_resize_enable osc
11424 }
11425 run_test 120b "Early Lock Cancel: create test"
11426
11427 test_120c() {
11428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11429         remote_mds_nodsh && skip "remote MDS with nodsh"
11430         test_mkdir -i0 -c1 $DIR/$tdir
11431         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11432                 skip "no early lock cancel on server"
11433
11434         lru_resize_disable mdc
11435         lru_resize_disable osc
11436         test_mkdir -i0 -c1 $DIR/$tdir/d1
11437         test_mkdir -i0 -c1 $DIR/$tdir/d2
11438         touch $DIR/$tdir/d1/f1
11439         cancel_lru_locks mdc
11440         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /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         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
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 120c "Early Lock Cancel: link test"
11458
11459 test_120d() {
11460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11461         remote_mds_nodsh && skip "remote MDS with nodsh"
11462         test_mkdir -i0 -c1 $DIR/$tdir
11463         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11464                 skip_env "no early lock cancel on server"
11465
11466         lru_resize_disable mdc
11467         lru_resize_disable osc
11468         touch $DIR/$tdir
11469         cancel_lru_locks mdc
11470         stat $DIR/$tdir > /dev/null
11471         can1=$(do_facet mds1 \
11472                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11473                awk '/ldlm_cancel/ {print $2}')
11474         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11475                awk '/ldlm_bl_callback/ {print $2}')
11476         chmod a+x $DIR/$tdir
11477         can2=$(do_facet mds1 \
11478                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11479                awk '/ldlm_cancel/ {print $2}')
11480         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11481                awk '/ldlm_bl_callback/ {print $2}')
11482         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11483         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11484         lru_resize_enable mdc
11485         lru_resize_enable osc
11486 }
11487 run_test 120d "Early Lock Cancel: setattr test"
11488
11489 test_120e() {
11490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11491         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11492                 skip_env "no early lock cancel on server"
11493         remote_mds_nodsh && skip "remote MDS with nodsh"
11494
11495         local dlmtrace_set=false
11496
11497         test_mkdir -i0 -c1 $DIR/$tdir
11498         lru_resize_disable mdc
11499         lru_resize_disable osc
11500         ! $LCTL get_param debug | grep -q dlmtrace &&
11501                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11502         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11503         cancel_lru_locks mdc
11504         cancel_lru_locks osc
11505         dd if=$DIR/$tdir/f1 of=/dev/null
11506         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11507         # XXX client can not do early lock cancel of OST lock
11508         # during unlink (LU-4206), so cancel osc lock now.
11509         sleep 2
11510         cancel_lru_locks osc
11511         can1=$(do_facet mds1 \
11512                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11513                awk '/ldlm_cancel/ {print $2}')
11514         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11515                awk '/ldlm_bl_callback/ {print $2}')
11516         unlink $DIR/$tdir/f1
11517         sleep 5
11518         can2=$(do_facet mds1 \
11519                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11520                awk '/ldlm_cancel/ {print $2}')
11521         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11522                awk '/ldlm_bl_callback/ {print $2}')
11523         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11524                 $LCTL dk $TMP/cancel.debug.txt
11525         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11526                 $LCTL dk $TMP/blocking.debug.txt
11527         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11528         lru_resize_enable mdc
11529         lru_resize_enable osc
11530 }
11531 run_test 120e "Early Lock Cancel: unlink test"
11532
11533 test_120f() {
11534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11535         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11536                 skip_env "no early lock cancel on server"
11537         remote_mds_nodsh && skip "remote MDS with nodsh"
11538
11539         test_mkdir -i0 -c1 $DIR/$tdir
11540         lru_resize_disable mdc
11541         lru_resize_disable osc
11542         test_mkdir -i0 -c1 $DIR/$tdir/d1
11543         test_mkdir -i0 -c1 $DIR/$tdir/d2
11544         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11545         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11546         cancel_lru_locks mdc
11547         cancel_lru_locks osc
11548         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11549         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11550         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11551         # XXX client can not do early lock cancel of OST lock
11552         # during rename (LU-4206), so cancel osc lock now.
11553         sleep 2
11554         cancel_lru_locks osc
11555         can1=$(do_facet mds1 \
11556                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11557                awk '/ldlm_cancel/ {print $2}')
11558         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11559                awk '/ldlm_bl_callback/ {print $2}')
11560         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11561         sleep 5
11562         can2=$(do_facet mds1 \
11563                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11564                awk '/ldlm_cancel/ {print $2}')
11565         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11566                awk '/ldlm_bl_callback/ {print $2}')
11567         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11568         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11569         lru_resize_enable mdc
11570         lru_resize_enable osc
11571 }
11572 run_test 120f "Early Lock Cancel: rename test"
11573
11574 test_120g() {
11575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11576         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11577                 skip_env "no early lock cancel on server"
11578         remote_mds_nodsh && skip "remote MDS with nodsh"
11579
11580         lru_resize_disable mdc
11581         lru_resize_disable osc
11582         count=10000
11583         echo create $count files
11584         test_mkdir $DIR/$tdir
11585         cancel_lru_locks mdc
11586         cancel_lru_locks osc
11587         t0=$(date +%s)
11588
11589         can0=$(do_facet $SINGLEMDS \
11590                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11591                awk '/ldlm_cancel/ {print $2}')
11592         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11593                awk '/ldlm_bl_callback/ {print $2}')
11594         createmany -o $DIR/$tdir/f $count
11595         sync
11596         can1=$(do_facet $SINGLEMDS \
11597                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11598                awk '/ldlm_cancel/ {print $2}')
11599         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11600                awk '/ldlm_bl_callback/ {print $2}')
11601         t1=$(date +%s)
11602         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11603         echo rm $count files
11604         rm -r $DIR/$tdir
11605         sync
11606         can2=$(do_facet $SINGLEMDS \
11607                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11608                awk '/ldlm_cancel/ {print $2}')
11609         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11610                awk '/ldlm_bl_callback/ {print $2}')
11611         t2=$(date +%s)
11612         echo total: $count removes in $((t2-t1))
11613         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11614         sleep 2
11615         # wait for commitment of removal
11616         lru_resize_enable mdc
11617         lru_resize_enable osc
11618 }
11619 run_test 120g "Early Lock Cancel: performance test"
11620
11621 test_121() { #bug #10589
11622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11623
11624         rm -rf $DIR/$tfile
11625         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11626 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11627         lctl set_param fail_loc=0x310
11628         cancel_lru_locks osc > /dev/null
11629         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11630         lctl set_param fail_loc=0
11631         [[ $reads -eq $writes ]] ||
11632                 error "read $reads blocks, must be $writes blocks"
11633 }
11634 run_test 121 "read cancel race ========="
11635
11636 test_123a_base() { # was test 123, statahead(bug 11401)
11637         local lsx="$1"
11638
11639         SLOWOK=0
11640         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11641                 log "testing UP system. Performance may be lower than expected."
11642                 SLOWOK=1
11643         fi
11644
11645         rm -rf $DIR/$tdir
11646         test_mkdir $DIR/$tdir
11647         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11648         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11649         MULT=10
11650         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11651                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11652
11653                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11654                 lctl set_param -n llite.*.statahead_max 0
11655                 lctl get_param llite.*.statahead_max
11656                 cancel_lru_locks mdc
11657                 cancel_lru_locks osc
11658                 stime=$(date +%s)
11659                 time $lsx $DIR/$tdir | wc -l
11660                 etime=$(date +%s)
11661                 delta=$((etime - stime))
11662                 log "$lsx $i files without statahead: $delta sec"
11663                 lctl set_param llite.*.statahead_max=$max
11664
11665                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11666                         grep "statahead wrong:" | awk '{print $3}')
11667                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11668                 cancel_lru_locks mdc
11669                 cancel_lru_locks osc
11670                 stime=$(date +%s)
11671                 time $lsx $DIR/$tdir | wc -l
11672                 etime=$(date +%s)
11673                 delta_sa=$((etime - stime))
11674                 log "$lsx $i files with statahead: $delta_sa sec"
11675                 lctl get_param -n llite.*.statahead_stats
11676                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11677                         grep "statahead wrong:" | awk '{print $3}')
11678
11679                 [[ $swrong -lt $ewrong ]] &&
11680                         log "statahead was stopped, maybe too many locks held!"
11681                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11682
11683                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11684                         max=$(lctl get_param -n llite.*.statahead_max |
11685                                 head -n 1)
11686                         lctl set_param -n llite.*.statahead_max 0
11687                         lctl get_param llite.*.statahead_max
11688                         cancel_lru_locks mdc
11689                         cancel_lru_locks osc
11690                         stime=$(date +%s)
11691                         time $lsx $DIR/$tdir | wc -l
11692                         etime=$(date +%s)
11693                         delta=$((etime - stime))
11694                         log "$lsx $i files again without statahead: $delta sec"
11695                         lctl set_param llite.*.statahead_max=$max
11696                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11697                                 if [  $SLOWOK -eq 0 ]; then
11698                                         error "$lsx $i files is slower with statahead!"
11699                                 else
11700                                         log "$lsx $i files is slower with statahead!"
11701                                 fi
11702                                 break
11703                         fi
11704                 fi
11705
11706                 [ $delta -gt 20 ] && break
11707                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11708                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11709         done
11710         log "$lsx done"
11711
11712         stime=$(date +%s)
11713         rm -r $DIR/$tdir
11714         sync
11715         etime=$(date +%s)
11716         delta=$((etime - stime))
11717         log "rm -r $DIR/$tdir/: $delta seconds"
11718         log "rm done"
11719         lctl get_param -n llite.*.statahead_stats
11720 }
11721
11722 test_123aa() {
11723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11724
11725         test_123a_base "ls -l"
11726 }
11727 run_test 123aa "verify statahead work"
11728
11729 test_123ab() {
11730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11731
11732         statx_supported || skip_env "Test must be statx() syscall supported"
11733
11734         test_123a_base "$STATX -l"
11735 }
11736 run_test 123ab "verify statahead work by using statx"
11737
11738 test_123ac() {
11739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11740
11741         statx_supported || skip_env "Test must be statx() syscall supported"
11742
11743         local rpcs_before
11744         local rpcs_after
11745         local agl_before
11746         local agl_after
11747
11748         cancel_lru_locks $OSC
11749         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11750         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11751                 awk '/agl.total:/ {print $3}')
11752         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11753         test_123a_base "$STATX --cached=always -D"
11754         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11755                 awk '/agl.total:/ {print $3}')
11756         [ $agl_before -eq $agl_after ] ||
11757                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11758         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11759         [ $rpcs_after -eq $rpcs_before ] ||
11760                 error "$STATX should not send glimpse RPCs to $OSC"
11761 }
11762 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11763
11764 test_123b () { # statahead(bug 15027)
11765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11766
11767         test_mkdir $DIR/$tdir
11768         createmany -o $DIR/$tdir/$tfile-%d 1000
11769
11770         cancel_lru_locks mdc
11771         cancel_lru_locks osc
11772
11773 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11774         lctl set_param fail_loc=0x80000803
11775         ls -lR $DIR/$tdir > /dev/null
11776         log "ls done"
11777         lctl set_param fail_loc=0x0
11778         lctl get_param -n llite.*.statahead_stats
11779         rm -r $DIR/$tdir
11780         sync
11781
11782 }
11783 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11784
11785 test_123c() {
11786         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11787
11788         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11789         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11790         touch $DIR/$tdir.1/{1..3}
11791         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11792
11793         remount_client $MOUNT
11794
11795         $MULTIOP $DIR/$tdir.0 Q
11796
11797         # let statahead to complete
11798         ls -l $DIR/$tdir.0 > /dev/null
11799
11800         testid=$(echo $TESTNAME | tr '_' ' ')
11801         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11802                 error "statahead warning" || true
11803 }
11804 run_test 123c "Can not initialize inode warning on DNE statahead"
11805
11806 test_124a() {
11807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11808         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11809                 skip_env "no lru resize on server"
11810
11811         local NR=2000
11812
11813         test_mkdir $DIR/$tdir
11814
11815         log "create $NR files at $DIR/$tdir"
11816         createmany -o $DIR/$tdir/f $NR ||
11817                 error "failed to create $NR files in $DIR/$tdir"
11818
11819         cancel_lru_locks mdc
11820         ls -l $DIR/$tdir > /dev/null
11821
11822         local NSDIR=""
11823         local LRU_SIZE=0
11824         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11825                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11826                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11827                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11828                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11829                         log "NSDIR=$NSDIR"
11830                         log "NS=$(basename $NSDIR)"
11831                         break
11832                 fi
11833         done
11834
11835         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11836                 skip "Not enough cached locks created!"
11837         fi
11838         log "LRU=$LRU_SIZE"
11839
11840         local SLEEP=30
11841
11842         # We know that lru resize allows one client to hold $LIMIT locks
11843         # for 10h. After that locks begin to be killed by client.
11844         local MAX_HRS=10
11845         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11846         log "LIMIT=$LIMIT"
11847         if [ $LIMIT -lt $LRU_SIZE ]; then
11848                 skip "Limit is too small $LIMIT"
11849         fi
11850
11851         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11852         # killing locks. Some time was spent for creating locks. This means
11853         # that up to the moment of sleep finish we must have killed some of
11854         # them (10-100 locks). This depends on how fast ther were created.
11855         # Many of them were touched in almost the same moment and thus will
11856         # be killed in groups.
11857         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11858
11859         # Use $LRU_SIZE_B here to take into account real number of locks
11860         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11861         local LRU_SIZE_B=$LRU_SIZE
11862         log "LVF=$LVF"
11863         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11864         log "OLD_LVF=$OLD_LVF"
11865         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11866
11867         # Let's make sure that we really have some margin. Client checks
11868         # cached locks every 10 sec.
11869         SLEEP=$((SLEEP+20))
11870         log "Sleep ${SLEEP} sec"
11871         local SEC=0
11872         while ((SEC<$SLEEP)); do
11873                 echo -n "..."
11874                 sleep 5
11875                 SEC=$((SEC+5))
11876                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11877                 echo -n "$LRU_SIZE"
11878         done
11879         echo ""
11880         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11881         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11882
11883         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11884                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11885                 unlinkmany $DIR/$tdir/f $NR
11886                 return
11887         }
11888
11889         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11890         log "unlink $NR files at $DIR/$tdir"
11891         unlinkmany $DIR/$tdir/f $NR
11892 }
11893 run_test 124a "lru resize ======================================="
11894
11895 get_max_pool_limit()
11896 {
11897         local limit=$($LCTL get_param \
11898                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11899         local max=0
11900         for l in $limit; do
11901                 if [[ $l -gt $max ]]; then
11902                         max=$l
11903                 fi
11904         done
11905         echo $max
11906 }
11907
11908 test_124b() {
11909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11910         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11911                 skip_env "no lru resize on server"
11912
11913         LIMIT=$(get_max_pool_limit)
11914
11915         NR=$(($(default_lru_size)*20))
11916         if [[ $NR -gt $LIMIT ]]; then
11917                 log "Limit lock number by $LIMIT locks"
11918                 NR=$LIMIT
11919         fi
11920
11921         IFree=$(mdsrate_inodes_available)
11922         if [ $IFree -lt $NR ]; then
11923                 log "Limit lock number by $IFree inodes"
11924                 NR=$IFree
11925         fi
11926
11927         lru_resize_disable mdc
11928         test_mkdir -p $DIR/$tdir/disable_lru_resize
11929
11930         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11931         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11932         cancel_lru_locks mdc
11933         stime=`date +%s`
11934         PID=""
11935         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11936         PID="$PID $!"
11937         sleep 2
11938         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11939         PID="$PID $!"
11940         sleep 2
11941         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11942         PID="$PID $!"
11943         wait $PID
11944         etime=`date +%s`
11945         nolruresize_delta=$((etime-stime))
11946         log "ls -la time: $nolruresize_delta seconds"
11947         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11948         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11949
11950         lru_resize_enable mdc
11951         test_mkdir -p $DIR/$tdir/enable_lru_resize
11952
11953         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11954         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11955         cancel_lru_locks mdc
11956         stime=`date +%s`
11957         PID=""
11958         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11959         PID="$PID $!"
11960         sleep 2
11961         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11962         PID="$PID $!"
11963         sleep 2
11964         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11965         PID="$PID $!"
11966         wait $PID
11967         etime=`date +%s`
11968         lruresize_delta=$((etime-stime))
11969         log "ls -la time: $lruresize_delta seconds"
11970         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11971
11972         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11973                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11974         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11975                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11976         else
11977                 log "lru resize performs the same with no lru resize"
11978         fi
11979         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11980 }
11981 run_test 124b "lru resize (performance test) ======================="
11982
11983 test_124c() {
11984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11985         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11986                 skip_env "no lru resize on server"
11987
11988         # cache ununsed locks on client
11989         local nr=100
11990         cancel_lru_locks mdc
11991         test_mkdir $DIR/$tdir
11992         createmany -o $DIR/$tdir/f $nr ||
11993                 error "failed to create $nr files in $DIR/$tdir"
11994         ls -l $DIR/$tdir > /dev/null
11995
11996         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11997         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11998         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11999         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12000         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12001
12002         # set lru_max_age to 1 sec
12003         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12004         echo "sleep $((recalc_p * 2)) seconds..."
12005         sleep $((recalc_p * 2))
12006
12007         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12008         # restore lru_max_age
12009         $LCTL set_param -n $nsdir.lru_max_age $max_age
12010         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12011         unlinkmany $DIR/$tdir/f $nr
12012 }
12013 run_test 124c "LRUR cancel very aged locks"
12014
12015 test_124d() {
12016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12017         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12018                 skip_env "no lru resize on server"
12019
12020         # cache ununsed locks on client
12021         local nr=100
12022
12023         lru_resize_disable mdc
12024         stack_trap "lru_resize_enable mdc" EXIT
12025
12026         cancel_lru_locks mdc
12027
12028         # asynchronous object destroy at MDT could cause bl ast to client
12029         test_mkdir $DIR/$tdir
12030         createmany -o $DIR/$tdir/f $nr ||
12031                 error "failed to create $nr files in $DIR/$tdir"
12032         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12033
12034         ls -l $DIR/$tdir > /dev/null
12035
12036         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12037         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12038         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12039         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12040
12041         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12042
12043         # set lru_max_age to 1 sec
12044         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12045         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12046
12047         echo "sleep $((recalc_p * 2)) seconds..."
12048         sleep $((recalc_p * 2))
12049
12050         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12051
12052         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12053 }
12054 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12055
12056 test_125() { # 13358
12057         $LCTL get_param -n llite.*.client_type | grep -q local ||
12058                 skip "must run as local client"
12059         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12060                 skip_env "must have acl enabled"
12061         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12062
12063         test_mkdir $DIR/$tdir
12064         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12065         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12066         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12067 }
12068 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12069
12070 test_126() { # bug 12829/13455
12071         $GSS && skip_env "must run as gss disabled"
12072         $LCTL get_param -n llite.*.client_type | grep -q local ||
12073                 skip "must run as local client"
12074         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12075
12076         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12077         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12078         rm -f $DIR/$tfile
12079         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12080 }
12081 run_test 126 "check that the fsgid provided by the client is taken into account"
12082
12083 test_127a() { # bug 15521
12084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12085         local name count samp unit min max sum sumsq
12086
12087         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12088         echo "stats before reset"
12089         $LCTL get_param osc.*.stats
12090         $LCTL set_param osc.*.stats=0
12091         local fsize=$((2048 * 1024))
12092
12093         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12094         cancel_lru_locks osc
12095         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12096
12097         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12098         stack_trap "rm -f $TMP/$tfile.tmp"
12099         while read name count samp unit min max sum sumsq; do
12100                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12101                 [ ! $min ] && error "Missing min value for $name proc entry"
12102                 eval $name=$count || error "Wrong proc format"
12103
12104                 case $name in
12105                 read_bytes|write_bytes)
12106                         [[ "$unit" =~ "bytes" ]] ||
12107                                 error "unit is not 'bytes': $unit"
12108                         (( $min >= 4096 )) || error "min is too small: $min"
12109                         (( $min <= $fsize )) || error "min is too big: $min"
12110                         (( $max >= 4096 )) || error "max is too small: $max"
12111                         (( $max <= $fsize )) || error "max is too big: $max"
12112                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12113                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12114                                 error "sumsquare is too small: $sumsq"
12115                         (( $sumsq <= $fsize * $fsize )) ||
12116                                 error "sumsquare is too big: $sumsq"
12117                         ;;
12118                 ost_read|ost_write)
12119                         [[ "$unit" =~ "usec" ]] ||
12120                                 error "unit is not 'usec': $unit"
12121                         ;;
12122                 *)      ;;
12123                 esac
12124         done < $DIR/$tfile.tmp
12125
12126         #check that we actually got some stats
12127         [ "$read_bytes" ] || error "Missing read_bytes stats"
12128         [ "$write_bytes" ] || error "Missing write_bytes stats"
12129         [ "$read_bytes" != 0 ] || error "no read done"
12130         [ "$write_bytes" != 0 ] || error "no write done"
12131 }
12132 run_test 127a "verify the client stats are sane"
12133
12134 test_127b() { # bug LU-333
12135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12136         local name count samp unit min max sum sumsq
12137
12138         echo "stats before reset"
12139         $LCTL get_param llite.*.stats
12140         $LCTL set_param llite.*.stats=0
12141
12142         # perform 2 reads and writes so MAX is different from SUM.
12143         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12144         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12145         cancel_lru_locks osc
12146         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12147         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12148
12149         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12150         stack_trap "rm -f $TMP/$tfile.tmp"
12151         while read name count samp unit min max sum sumsq; do
12152                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12153                 eval $name=$count || error "Wrong proc format"
12154
12155                 case $name in
12156                 read_bytes|write_bytes)
12157                         [[ "$unit" =~ "bytes" ]] ||
12158                                 error "unit is not 'bytes': $unit"
12159                         (( $count == 2 )) || error "count is not 2: $count"
12160                         (( $min == $PAGE_SIZE )) ||
12161                                 error "min is not $PAGE_SIZE: $min"
12162                         (( $max == $PAGE_SIZE )) ||
12163                                 error "max is not $PAGE_SIZE: $max"
12164                         (( $sum == $PAGE_SIZE * 2 )) ||
12165                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12166                         ;;
12167                 read|write)
12168                         [[ "$unit" =~ "usec" ]] ||
12169                                 error "unit is not 'usec': $unit"
12170                         ;;
12171                 *)      ;;
12172                 esac
12173         done < $TMP/$tfile.tmp
12174
12175         #check that we actually got some stats
12176         [ "$read_bytes" ] || error "Missing read_bytes stats"
12177         [ "$write_bytes" ] || error "Missing write_bytes stats"
12178         [ "$read_bytes" != 0 ] || error "no read done"
12179         [ "$write_bytes" != 0 ] || error "no write done"
12180 }
12181 run_test 127b "verify the llite client stats are sane"
12182
12183 test_127c() { # LU-12394
12184         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12185         local size
12186         local bsize
12187         local reads
12188         local writes
12189         local count
12190
12191         $LCTL set_param llite.*.extents_stats=1
12192         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12193
12194         # Use two stripes so there is enough space in default config
12195         $LFS setstripe -c 2 $DIR/$tfile
12196
12197         # Extent stats start at 0-4K and go in power of two buckets
12198         # LL_HIST_START = 12 --> 2^12 = 4K
12199         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12200         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12201         # small configs
12202         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12203                 do
12204                 # Write and read, 2x each, second time at a non-zero offset
12205                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12206                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12207                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12208                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12209                 rm -f $DIR/$tfile
12210         done
12211
12212         $LCTL get_param llite.*.extents_stats
12213
12214         count=2
12215         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12216                 do
12217                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12218                                 grep -m 1 $bsize)
12219                 reads=$(echo $bucket | awk '{print $5}')
12220                 writes=$(echo $bucket | awk '{print $9}')
12221                 [ "$reads" -eq $count ] ||
12222                         error "$reads reads in < $bsize bucket, expect $count"
12223                 [ "$writes" -eq $count ] ||
12224                         error "$writes writes in < $bsize bucket, expect $count"
12225         done
12226
12227         # Test mmap write and read
12228         $LCTL set_param llite.*.extents_stats=c
12229         size=512
12230         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12231         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12232         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12233
12234         $LCTL get_param llite.*.extents_stats
12235
12236         count=$(((size*1024) / PAGE_SIZE))
12237
12238         bsize=$((2 * PAGE_SIZE / 1024))K
12239
12240         bucket=$($LCTL get_param -n llite.*.extents_stats |
12241                         grep -m 1 $bsize)
12242         reads=$(echo $bucket | awk '{print $5}')
12243         writes=$(echo $bucket | awk '{print $9}')
12244         # mmap writes fault in the page first, creating an additonal read
12245         [ "$reads" -eq $((2 * count)) ] ||
12246                 error "$reads reads in < $bsize bucket, expect $count"
12247         [ "$writes" -eq $count ] ||
12248                 error "$writes writes in < $bsize bucket, expect $count"
12249 }
12250 run_test 127c "test llite extent stats with regular & mmap i/o"
12251
12252 test_128() { # bug 15212
12253         touch $DIR/$tfile
12254         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12255                 find $DIR/$tfile
12256                 find $DIR/$tfile
12257         EOF
12258
12259         result=$(grep error $TMP/$tfile.log)
12260         rm -f $DIR/$tfile $TMP/$tfile.log
12261         [ -z "$result" ] ||
12262                 error "consecutive find's under interactive lfs failed"
12263 }
12264 run_test 128 "interactive lfs for 2 consecutive find's"
12265
12266 set_dir_limits () {
12267         local mntdev
12268         local canondev
12269         local node
12270
12271         local ldproc=/proc/fs/ldiskfs
12272         local facets=$(get_facets MDS)
12273
12274         for facet in ${facets//,/ }; do
12275                 canondev=$(ldiskfs_canon \
12276                            *.$(convert_facet2label $facet).mntdev $facet)
12277                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12278                         ldproc=/sys/fs/ldiskfs
12279                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12280                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12281         done
12282 }
12283
12284 check_mds_dmesg() {
12285         local facets=$(get_facets MDS)
12286         for facet in ${facets//,/ }; do
12287                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12288         done
12289         return 1
12290 }
12291
12292 test_129() {
12293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12294         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12295                 skip "Need MDS version with at least 2.5.56"
12296         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12297                 skip_env "ldiskfs only test"
12298         fi
12299         remote_mds_nodsh && skip "remote MDS with nodsh"
12300
12301         local ENOSPC=28
12302         local has_warning=false
12303
12304         rm -rf $DIR/$tdir
12305         mkdir -p $DIR/$tdir
12306
12307         # block size of mds1
12308         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12309         set_dir_limits $maxsize $((maxsize * 6 / 8))
12310         stack_trap "set_dir_limits 0 0"
12311         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12312         local dirsize=$(stat -c%s "$DIR/$tdir")
12313         local nfiles=0
12314         while (( $dirsize <= $maxsize )); do
12315                 $MCREATE $DIR/$tdir/file_base_$nfiles
12316                 rc=$?
12317                 # check two errors:
12318                 # ENOSPC for ext4 max_dir_size, which has been used since
12319                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12320                 if (( rc == ENOSPC )); then
12321                         set_dir_limits 0 0
12322                         echo "rc=$rc returned as expected after $nfiles files"
12323
12324                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12325                                 error "create failed w/o dir size limit"
12326
12327                         # messages may be rate limited if test is run repeatedly
12328                         check_mds_dmesg '"is approaching max"' ||
12329                                 echo "warning message should be output"
12330                         check_mds_dmesg '"has reached max"' ||
12331                                 echo "reached message should be output"
12332
12333                         dirsize=$(stat -c%s "$DIR/$tdir")
12334
12335                         [[ $dirsize -ge $maxsize ]] && return 0
12336                         error "dirsize $dirsize < $maxsize after $nfiles files"
12337                 elif (( rc != 0 )); then
12338                         break
12339                 fi
12340                 nfiles=$((nfiles + 1))
12341                 dirsize=$(stat -c%s "$DIR/$tdir")
12342         done
12343
12344         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12345 }
12346 run_test 129 "test directory size limit ========================"
12347
12348 OLDIFS="$IFS"
12349 cleanup_130() {
12350         trap 0
12351         IFS="$OLDIFS"
12352 }
12353
12354 test_130a() {
12355         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12356         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12357
12358         trap cleanup_130 EXIT RETURN
12359
12360         local fm_file=$DIR/$tfile
12361         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12362         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12363                 error "dd failed for $fm_file"
12364
12365         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12366         filefrag -ves $fm_file
12367         RC=$?
12368         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12369                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12370         [ $RC != 0 ] && error "filefrag $fm_file failed"
12371
12372         filefrag_op=$(filefrag -ve -k $fm_file |
12373                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12374         lun=$($LFS getstripe -i $fm_file)
12375
12376         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12377         IFS=$'\n'
12378         tot_len=0
12379         for line in $filefrag_op
12380         do
12381                 frag_lun=`echo $line | cut -d: -f5`
12382                 ext_len=`echo $line | cut -d: -f4`
12383                 if (( $frag_lun != $lun )); then
12384                         cleanup_130
12385                         error "FIEMAP on 1-stripe file($fm_file) failed"
12386                         return
12387                 fi
12388                 (( tot_len += ext_len ))
12389         done
12390
12391         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12392                 cleanup_130
12393                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12394                 return
12395         fi
12396
12397         cleanup_130
12398
12399         echo "FIEMAP on single striped file succeeded"
12400 }
12401 run_test 130a "FIEMAP (1-stripe file)"
12402
12403 test_130b() {
12404         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12405
12406         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12407         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12408
12409         trap cleanup_130 EXIT RETURN
12410
12411         local fm_file=$DIR/$tfile
12412         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12413                         error "setstripe on $fm_file"
12414         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12415                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12416
12417         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12418                 error "dd failed on $fm_file"
12419
12420         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12421         filefrag_op=$(filefrag -ve -k $fm_file |
12422                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12423
12424         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12425                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12426
12427         IFS=$'\n'
12428         tot_len=0
12429         num_luns=1
12430         for line in $filefrag_op
12431         do
12432                 frag_lun=$(echo $line | cut -d: -f5 |
12433                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12434                 ext_len=$(echo $line | cut -d: -f4)
12435                 if (( $frag_lun != $last_lun )); then
12436                         if (( tot_len != 1024 )); then
12437                                 cleanup_130
12438                                 error "FIEMAP on $fm_file failed; returned " \
12439                                 "len $tot_len for OST $last_lun instead of 1024"
12440                                 return
12441                         else
12442                                 (( num_luns += 1 ))
12443                                 tot_len=0
12444                         fi
12445                 fi
12446                 (( tot_len += ext_len ))
12447                 last_lun=$frag_lun
12448         done
12449         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12450                 cleanup_130
12451                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12452                         "luns or wrong len for OST $last_lun"
12453                 return
12454         fi
12455
12456         cleanup_130
12457
12458         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12459 }
12460 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12461
12462 test_130c() {
12463         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12464
12465         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12466         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12467
12468         trap cleanup_130 EXIT RETURN
12469
12470         local fm_file=$DIR/$tfile
12471         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12472         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12473                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12474
12475         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12476                         error "dd failed on $fm_file"
12477
12478         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12479         filefrag_op=$(filefrag -ve -k $fm_file |
12480                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12481
12482         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12483                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12484
12485         IFS=$'\n'
12486         tot_len=0
12487         num_luns=1
12488         for line in $filefrag_op
12489         do
12490                 frag_lun=$(echo $line | cut -d: -f5 |
12491                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12492                 ext_len=$(echo $line | cut -d: -f4)
12493                 if (( $frag_lun != $last_lun )); then
12494                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12495                         if (( logical != 512 )); then
12496                                 cleanup_130
12497                                 error "FIEMAP on $fm_file failed; returned " \
12498                                 "logical start for lun $logical instead of 512"
12499                                 return
12500                         fi
12501                         if (( tot_len != 512 )); then
12502                                 cleanup_130
12503                                 error "FIEMAP on $fm_file failed; returned " \
12504                                 "len $tot_len for OST $last_lun instead of 1024"
12505                                 return
12506                         else
12507                                 (( num_luns += 1 ))
12508                                 tot_len=0
12509                         fi
12510                 fi
12511                 (( tot_len += ext_len ))
12512                 last_lun=$frag_lun
12513         done
12514         if (( num_luns != 2 || tot_len != 512 )); then
12515                 cleanup_130
12516                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12517                         "luns or wrong len for OST $last_lun"
12518                 return
12519         fi
12520
12521         cleanup_130
12522
12523         echo "FIEMAP on 2-stripe file with hole succeeded"
12524 }
12525 run_test 130c "FIEMAP (2-stripe file with hole)"
12526
12527 test_130d() {
12528         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12529
12530         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12531         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12532
12533         trap cleanup_130 EXIT RETURN
12534
12535         local fm_file=$DIR/$tfile
12536         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12537                         error "setstripe on $fm_file"
12538         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12539                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12540
12541         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12542         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12543                 error "dd failed on $fm_file"
12544
12545         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12546         filefrag_op=$(filefrag -ve -k $fm_file |
12547                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12548
12549         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12550                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12551
12552         IFS=$'\n'
12553         tot_len=0
12554         num_luns=1
12555         for line in $filefrag_op
12556         do
12557                 frag_lun=$(echo $line | cut -d: -f5 |
12558                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12559                 ext_len=$(echo $line | cut -d: -f4)
12560                 if (( $frag_lun != $last_lun )); then
12561                         if (( tot_len != 1024 )); then
12562                                 cleanup_130
12563                                 error "FIEMAP on $fm_file failed; returned " \
12564                                 "len $tot_len for OST $last_lun instead of 1024"
12565                                 return
12566                         else
12567                                 (( num_luns += 1 ))
12568                                 tot_len=0
12569                         fi
12570                 fi
12571                 (( tot_len += ext_len ))
12572                 last_lun=$frag_lun
12573         done
12574         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12575                 cleanup_130
12576                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12577                         "luns or wrong len for OST $last_lun"
12578                 return
12579         fi
12580
12581         cleanup_130
12582
12583         echo "FIEMAP on N-stripe file succeeded"
12584 }
12585 run_test 130d "FIEMAP (N-stripe file)"
12586
12587 test_130e() {
12588         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12589
12590         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12591         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12592
12593         trap cleanup_130 EXIT RETURN
12594
12595         local fm_file=$DIR/$tfile
12596         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12597         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12598                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12599
12600         NUM_BLKS=512
12601         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12602         for ((i = 0; i < $NUM_BLKS; i++))
12603         do
12604                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12605         done
12606
12607         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12608         filefrag_op=$(filefrag -ve -k $fm_file |
12609                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12610
12611         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12612                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12613
12614         IFS=$'\n'
12615         tot_len=0
12616         num_luns=1
12617         for line in $filefrag_op
12618         do
12619                 frag_lun=$(echo $line | cut -d: -f5 |
12620                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12621                 ext_len=$(echo $line | cut -d: -f4)
12622                 if (( $frag_lun != $last_lun )); then
12623                         if (( tot_len != $EXPECTED_LEN )); then
12624                                 cleanup_130
12625                                 error "FIEMAP on $fm_file failed; returned " \
12626                                 "len $tot_len for OST $last_lun instead " \
12627                                 "of $EXPECTED_LEN"
12628                                 return
12629                         else
12630                                 (( num_luns += 1 ))
12631                                 tot_len=0
12632                         fi
12633                 fi
12634                 (( tot_len += ext_len ))
12635                 last_lun=$frag_lun
12636         done
12637         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12638                 cleanup_130
12639                 error "FIEMAP on $fm_file failed; returned wrong number " \
12640                         "of luns or wrong len for OST $last_lun"
12641                 return
12642         fi
12643
12644         cleanup_130
12645
12646         echo "FIEMAP with continuation calls succeeded"
12647 }
12648 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12649
12650 test_130f() {
12651         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12652         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12653
12654         local fm_file=$DIR/$tfile
12655         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12656                 error "multiop create with lov_delay_create on $fm_file"
12657
12658         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12659         filefrag_extents=$(filefrag -vek $fm_file |
12660                            awk '/extents? found/ { print $2 }')
12661         if [[ "$filefrag_extents" != "0" ]]; then
12662                 error "FIEMAP on $fm_file failed; " \
12663                       "returned $filefrag_extents expected 0"
12664         fi
12665
12666         rm -f $fm_file
12667 }
12668 run_test 130f "FIEMAP (unstriped file)"
12669
12670 # Test for writev/readv
12671 test_131a() {
12672         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12673                 error "writev test failed"
12674         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12675                 error "readv failed"
12676         rm -f $DIR/$tfile
12677 }
12678 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12679
12680 test_131b() {
12681         local fsize=$((524288 + 1048576 + 1572864))
12682         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12683                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12684                         error "append writev test failed"
12685
12686         ((fsize += 1572864 + 1048576))
12687         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12688                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12689                         error "append writev test failed"
12690         rm -f $DIR/$tfile
12691 }
12692 run_test 131b "test append writev"
12693
12694 test_131c() {
12695         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12696         error "NOT PASS"
12697 }
12698 run_test 131c "test read/write on file w/o objects"
12699
12700 test_131d() {
12701         rwv -f $DIR/$tfile -w -n 1 1572864
12702         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12703         if [ "$NOB" != 1572864 ]; then
12704                 error "Short read filed: read $NOB bytes instead of 1572864"
12705         fi
12706         rm -f $DIR/$tfile
12707 }
12708 run_test 131d "test short read"
12709
12710 test_131e() {
12711         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12712         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12713         error "read hitting hole failed"
12714         rm -f $DIR/$tfile
12715 }
12716 run_test 131e "test read hitting hole"
12717
12718 check_stats() {
12719         local facet=$1
12720         local op=$2
12721         local want=${3:-0}
12722         local res
12723
12724         case $facet in
12725         mds*) res=$(do_facet $facet \
12726                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12727                  ;;
12728         ost*) res=$(do_facet $facet \
12729                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12730                  ;;
12731         *) error "Wrong facet '$facet'" ;;
12732         esac
12733         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12734         # if the argument $3 is zero, it means any stat increment is ok.
12735         if [[ $want -gt 0 ]]; then
12736                 local count=$(echo $res | awk '{ print $2 }')
12737                 [[ $count -ne $want ]] &&
12738                         error "The $op counter on $facet is $count, not $want"
12739         fi
12740 }
12741
12742 test_133a() {
12743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12744         remote_ost_nodsh && skip "remote OST with nodsh"
12745         remote_mds_nodsh && skip "remote MDS with nodsh"
12746         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12747                 skip_env "MDS doesn't support rename stats"
12748
12749         local testdir=$DIR/${tdir}/stats_testdir
12750
12751         mkdir -p $DIR/${tdir}
12752
12753         # clear stats.
12754         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12755         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12756
12757         # verify mdt stats first.
12758         mkdir ${testdir} || error "mkdir failed"
12759         check_stats $SINGLEMDS "mkdir" 1
12760         touch ${testdir}/${tfile} || error "touch failed"
12761         check_stats $SINGLEMDS "open" 1
12762         check_stats $SINGLEMDS "close" 1
12763         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12764                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12765                 check_stats $SINGLEMDS "mknod" 2
12766         }
12767         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12768         check_stats $SINGLEMDS "unlink" 1
12769         rm -f ${testdir}/${tfile} || error "file remove failed"
12770         check_stats $SINGLEMDS "unlink" 2
12771
12772         # remove working dir and check mdt stats again.
12773         rmdir ${testdir} || error "rmdir failed"
12774         check_stats $SINGLEMDS "rmdir" 1
12775
12776         local testdir1=$DIR/${tdir}/stats_testdir1
12777         mkdir -p ${testdir}
12778         mkdir -p ${testdir1}
12779         touch ${testdir1}/test1
12780         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12781         check_stats $SINGLEMDS "crossdir_rename" 1
12782
12783         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12784         check_stats $SINGLEMDS "samedir_rename" 1
12785
12786         rm -rf $DIR/${tdir}
12787 }
12788 run_test 133a "Verifying MDT stats ========================================"
12789
12790 test_133b() {
12791         local res
12792
12793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12794         remote_ost_nodsh && skip "remote OST with nodsh"
12795         remote_mds_nodsh && skip "remote MDS with nodsh"
12796
12797         local testdir=$DIR/${tdir}/stats_testdir
12798
12799         mkdir -p ${testdir} || error "mkdir failed"
12800         touch ${testdir}/${tfile} || error "touch failed"
12801         cancel_lru_locks mdc
12802
12803         # clear stats.
12804         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12805         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12806
12807         # extra mdt stats verification.
12808         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12809         check_stats $SINGLEMDS "setattr" 1
12810         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12811         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12812         then            # LU-1740
12813                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12814                 check_stats $SINGLEMDS "getattr" 1
12815         fi
12816         rm -rf $DIR/${tdir}
12817
12818         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12819         # so the check below is not reliable
12820         [ $MDSCOUNT -eq 1 ] || return 0
12821
12822         # Sleep to avoid a cached response.
12823         #define OBD_STATFS_CACHE_SECONDS 1
12824         sleep 2
12825         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12826         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12827         $LFS df || error "lfs failed"
12828         check_stats $SINGLEMDS "statfs" 1
12829
12830         # check aggregated statfs (LU-10018)
12831         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12832                 return 0
12833         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12834                 return 0
12835         sleep 2
12836         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12837         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12838         df $DIR
12839         check_stats $SINGLEMDS "statfs" 1
12840
12841         # We want to check that the client didn't send OST_STATFS to
12842         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12843         # extra care is needed here.
12844         if remote_mds; then
12845                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12846                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12847
12848                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12849                 [ "$res" ] && error "OST got STATFS"
12850         fi
12851
12852         return 0
12853 }
12854 run_test 133b "Verifying extra MDT stats =================================="
12855
12856 test_133c() {
12857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12858         remote_ost_nodsh && skip "remote OST with nodsh"
12859         remote_mds_nodsh && skip "remote MDS with nodsh"
12860
12861         local testdir=$DIR/$tdir/stats_testdir
12862
12863         test_mkdir -p $testdir
12864
12865         # verify obdfilter stats.
12866         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12867         sync
12868         cancel_lru_locks osc
12869         wait_delete_completed
12870
12871         # clear stats.
12872         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12873         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12874
12875         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12876                 error "dd failed"
12877         sync
12878         cancel_lru_locks osc
12879         check_stats ost1 "write" 1
12880
12881         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12882         check_stats ost1 "read" 1
12883
12884         > $testdir/$tfile || error "truncate failed"
12885         check_stats ost1 "punch" 1
12886
12887         rm -f $testdir/$tfile || error "file remove failed"
12888         wait_delete_completed
12889         check_stats ost1 "destroy" 1
12890
12891         rm -rf $DIR/$tdir
12892 }
12893 run_test 133c "Verifying OST stats ========================================"
12894
12895 order_2() {
12896         local value=$1
12897         local orig=$value
12898         local order=1
12899
12900         while [ $value -ge 2 ]; do
12901                 order=$((order*2))
12902                 value=$((value/2))
12903         done
12904
12905         if [ $orig -gt $order ]; then
12906                 order=$((order*2))
12907         fi
12908         echo $order
12909 }
12910
12911 size_in_KMGT() {
12912     local value=$1
12913     local size=('K' 'M' 'G' 'T');
12914     local i=0
12915     local size_string=$value
12916
12917     while [ $value -ge 1024 ]; do
12918         if [ $i -gt 3 ]; then
12919             #T is the biggest unit we get here, if that is bigger,
12920             #just return XXXT
12921             size_string=${value}T
12922             break
12923         fi
12924         value=$((value >> 10))
12925         if [ $value -lt 1024 ]; then
12926             size_string=${value}${size[$i]}
12927             break
12928         fi
12929         i=$((i + 1))
12930     done
12931
12932     echo $size_string
12933 }
12934
12935 get_rename_size() {
12936         local size=$1
12937         local context=${2:-.}
12938         local sample=$(do_facet $SINGLEMDS $LCTL \
12939                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12940                 grep -A1 $context |
12941                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12942         echo $sample
12943 }
12944
12945 test_133d() {
12946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12947         remote_ost_nodsh && skip "remote OST with nodsh"
12948         remote_mds_nodsh && skip "remote MDS with nodsh"
12949         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12950                 skip_env "MDS doesn't support rename stats"
12951
12952         local testdir1=$DIR/${tdir}/stats_testdir1
12953         local testdir2=$DIR/${tdir}/stats_testdir2
12954         mkdir -p $DIR/${tdir}
12955
12956         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12957
12958         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12959         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12960
12961         createmany -o $testdir1/test 512 || error "createmany failed"
12962
12963         # check samedir rename size
12964         mv ${testdir1}/test0 ${testdir1}/test_0
12965
12966         local testdir1_size=$(ls -l $DIR/${tdir} |
12967                 awk '/stats_testdir1/ {print $5}')
12968         local 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         local cmd="do_facet $SINGLEMDS $LCTL "
12981         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12982
12983         eval $cmd || error "$cmd failed"
12984         local samedir=$($cmd | grep 'same_dir')
12985         local same_sample=$(get_rename_size $testdir1_size)
12986         [ -z "$samedir" ] && error "samedir_rename_size count error"
12987         [[ $same_sample -eq 1 ]] ||
12988                 error "samedir_rename_size error $same_sample"
12989         echo "Check same dir rename stats success"
12990
12991         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12992
12993         # check crossdir rename size
12994         mv ${testdir1}/test_0 ${testdir2}/test_0
12995
12996         testdir1_size=$(ls -l $DIR/${tdir} |
12997                 awk '/stats_testdir1/ {print $5}')
12998         testdir2_size=$(ls -l $DIR/${tdir} |
12999                 awk '/stats_testdir2/ {print $5}')
13000
13001         testdir1_size=$(order_2 $testdir1_size)
13002         testdir2_size=$(order_2 $testdir2_size)
13003
13004         testdir1_size=$(size_in_KMGT $testdir1_size)
13005         testdir2_size=$(size_in_KMGT $testdir2_size)
13006
13007         echo "source rename dir size: ${testdir1_size}"
13008         echo "target rename dir size: ${testdir2_size}"
13009
13010         eval $cmd || error "$cmd failed"
13011         local crossdir=$($cmd | grep 'crossdir')
13012         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13013         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13014         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13015         [[ $src_sample -eq 1 ]] ||
13016                 error "crossdir_rename_size error $src_sample"
13017         [[ $tgt_sample -eq 1 ]] ||
13018                 error "crossdir_rename_size error $tgt_sample"
13019         echo "Check cross dir rename stats success"
13020         rm -rf $DIR/${tdir}
13021 }
13022 run_test 133d "Verifying rename_stats ========================================"
13023
13024 test_133e() {
13025         remote_mds_nodsh && skip "remote MDS with nodsh"
13026         remote_ost_nodsh && skip "remote OST with nodsh"
13027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13028
13029         local testdir=$DIR/${tdir}/stats_testdir
13030         local ctr f0 f1 bs=32768 count=42 sum
13031
13032         mkdir -p ${testdir} || error "mkdir failed"
13033
13034         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13035
13036         for ctr in {write,read}_bytes; do
13037                 sync
13038                 cancel_lru_locks osc
13039
13040                 do_facet ost1 $LCTL set_param -n \
13041                         "obdfilter.*.exports.clear=clear"
13042
13043                 if [ $ctr = write_bytes ]; then
13044                         f0=/dev/zero
13045                         f1=${testdir}/${tfile}
13046                 else
13047                         f0=${testdir}/${tfile}
13048                         f1=/dev/null
13049                 fi
13050
13051                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13052                         error "dd failed"
13053                 sync
13054                 cancel_lru_locks osc
13055
13056                 sum=$(do_facet ost1 $LCTL get_param \
13057                         "obdfilter.*.exports.*.stats" |
13058                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13059                                 $1 == ctr { sum += $7 }
13060                                 END { printf("%0.0f", sum) }')
13061
13062                 if ((sum != bs * count)); then
13063                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13064                 fi
13065         done
13066
13067         rm -rf $DIR/${tdir}
13068 }
13069 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13070
13071 test_133f() {
13072         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13073                 skip "too old lustre for get_param -R ($facet_ver)"
13074
13075         # verifying readability.
13076         $LCTL get_param -R '*' &> /dev/null
13077
13078         # Verifing writability with badarea_io.
13079         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13080                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13081                 error "client badarea_io failed"
13082
13083         # remount the FS in case writes/reads /proc break the FS
13084         cleanup || error "failed to unmount"
13085         setup || error "failed to setup"
13086 }
13087 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13088
13089 test_133g() {
13090         remote_mds_nodsh && skip "remote MDS with nodsh"
13091         remote_ost_nodsh && skip "remote OST with nodsh"
13092
13093         local facet
13094         for facet in mds1 ost1; do
13095                 local facet_ver=$(lustre_version_code $facet)
13096                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13097                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13098                 else
13099                         log "$facet: too old lustre for get_param -R"
13100                 fi
13101                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13102                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13103                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13104                                 xargs badarea_io" ||
13105                                         error "$facet badarea_io failed"
13106                 else
13107                         skip_noexit "$facet: too old lustre for get_param -R"
13108                 fi
13109         done
13110
13111         # remount the FS in case writes/reads /proc break the FS
13112         cleanup || error "failed to unmount"
13113         setup || error "failed to setup"
13114 }
13115 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13116
13117 test_133h() {
13118         remote_mds_nodsh && skip "remote MDS with nodsh"
13119         remote_ost_nodsh && skip "remote OST with nodsh"
13120         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13121                 skip "Need MDS version at least 2.9.54"
13122
13123         local facet
13124         for facet in client mds1 ost1; do
13125                 # Get the list of files that are missing the terminating newline
13126                 local plist=$(do_facet $facet
13127                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13128                 local ent
13129                 for ent in $plist; do
13130                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13131                                 awk -v FS='\v' -v RS='\v\v' \
13132                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13133                                         print FILENAME}'" 2>/dev/null)
13134                         [ -z $missing ] || {
13135                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13136                                 error "file does not end with newline: $facet-$ent"
13137                         }
13138                 done
13139         done
13140 }
13141 run_test 133h "Proc files should end with newlines"
13142
13143 test_134a() {
13144         remote_mds_nodsh && skip "remote MDS with nodsh"
13145         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13146                 skip "Need MDS version at least 2.7.54"
13147
13148         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13149         cancel_lru_locks mdc
13150
13151         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13152         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13153         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13154
13155         local nr=1000
13156         createmany -o $DIR/$tdir/f $nr ||
13157                 error "failed to create $nr files in $DIR/$tdir"
13158         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13159
13160         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13161         do_facet mds1 $LCTL set_param fail_loc=0x327
13162         do_facet mds1 $LCTL set_param fail_val=500
13163         touch $DIR/$tdir/m
13164
13165         echo "sleep 10 seconds ..."
13166         sleep 10
13167         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13168
13169         do_facet mds1 $LCTL set_param fail_loc=0
13170         do_facet mds1 $LCTL set_param fail_val=0
13171         [ $lck_cnt -lt $unused ] ||
13172                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13173
13174         rm $DIR/$tdir/m
13175         unlinkmany $DIR/$tdir/f $nr
13176 }
13177 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13178
13179 test_134b() {
13180         remote_mds_nodsh && skip "remote MDS with nodsh"
13181         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13182                 skip "Need MDS version at least 2.7.54"
13183
13184         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13185         cancel_lru_locks mdc
13186
13187         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13188                         ldlm.lock_reclaim_threshold_mb)
13189         # disable reclaim temporarily
13190         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13191
13192         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13193         do_facet mds1 $LCTL set_param fail_loc=0x328
13194         do_facet mds1 $LCTL set_param fail_val=500
13195
13196         $LCTL set_param debug=+trace
13197
13198         local nr=600
13199         createmany -o $DIR/$tdir/f $nr &
13200         local create_pid=$!
13201
13202         echo "Sleep $TIMEOUT seconds ..."
13203         sleep $TIMEOUT
13204         if ! ps -p $create_pid  > /dev/null 2>&1; then
13205                 do_facet mds1 $LCTL set_param fail_loc=0
13206                 do_facet mds1 $LCTL set_param fail_val=0
13207                 do_facet mds1 $LCTL set_param \
13208                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13209                 error "createmany finished incorrectly!"
13210         fi
13211         do_facet mds1 $LCTL set_param fail_loc=0
13212         do_facet mds1 $LCTL set_param fail_val=0
13213         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13214         wait $create_pid || return 1
13215
13216         unlinkmany $DIR/$tdir/f $nr
13217 }
13218 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13219
13220 test_135() {
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
13228 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13229         #set only one record at plain llog
13230         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13231
13232         #fill already existed plain llog each 64767
13233         #wrapping whole catalog
13234         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13235
13236         createmany -o $DIR/$tdir/$tfile_ 64700
13237         for (( i = 0; i < 64700; i = i + 2 ))
13238         do
13239                 rm $DIR/$tdir/$tfile_$i &
13240                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13241                 local pid=$!
13242                 wait $pid
13243         done
13244
13245         #waiting osp synchronization
13246         wait_delete_completed
13247 }
13248 run_test 135 "Race catalog processing"
13249
13250 test_136() {
13251         remote_mds_nodsh && skip "remote MDS with nodsh"
13252         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13253                 skip "Need MDS version at least 2.13.50"
13254         local fname
13255
13256         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13257         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13258         #set only one record at plain llog
13259 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13260         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13261
13262         #fill already existed 2 plain llogs each 64767
13263         #wrapping whole catalog
13264         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13265         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13266         wait_delete_completed
13267
13268         createmany -o $DIR/$tdir/$tfile_ 10
13269         sleep 25
13270
13271         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13272         for (( i = 0; i < 10; i = i + 3 ))
13273         do
13274                 rm $DIR/$tdir/$tfile_$i &
13275                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13276                 local pid=$!
13277                 wait $pid
13278                 sleep 7
13279                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13280         done
13281
13282         #waiting osp synchronization
13283         wait_delete_completed
13284 }
13285 run_test 136 "Race catalog processing 2"
13286
13287 test_140() { #bug-17379
13288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13289
13290         test_mkdir $DIR/$tdir
13291         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13292         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13293
13294         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13295         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13296         local i=0
13297         while i=$((i + 1)); do
13298                 test_mkdir $i
13299                 cd $i || error "Changing to $i"
13300                 ln -s ../stat stat || error "Creating stat symlink"
13301                 # Read the symlink until ELOOP present,
13302                 # not LBUGing the system is considered success,
13303                 # we didn't overrun the stack.
13304                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13305                 if [ $ret -ne 0 ]; then
13306                         if [ $ret -eq 40 ]; then
13307                                 break  # -ELOOP
13308                         else
13309                                 error "Open stat symlink"
13310                                         return
13311                         fi
13312                 fi
13313         done
13314         i=$((i - 1))
13315         echo "The symlink depth = $i"
13316         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13317                 error "Invalid symlink depth"
13318
13319         # Test recursive symlink
13320         ln -s symlink_self symlink_self
13321         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13322         echo "open symlink_self returns $ret"
13323         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13324 }
13325 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13326
13327 test_150a() {
13328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13329
13330         local TF="$TMP/$tfile"
13331
13332         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13333         cp $TF $DIR/$tfile
13334         cancel_lru_locks $OSC
13335         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13336         remount_client $MOUNT
13337         df -P $MOUNT
13338         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13339
13340         $TRUNCATE $TF 6000
13341         $TRUNCATE $DIR/$tfile 6000
13342         cancel_lru_locks $OSC
13343         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13344
13345         echo "12345" >>$TF
13346         echo "12345" >>$DIR/$tfile
13347         cancel_lru_locks $OSC
13348         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13349
13350         echo "12345" >>$TF
13351         echo "12345" >>$DIR/$tfile
13352         cancel_lru_locks $OSC
13353         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13354
13355         rm -f $TF
13356         true
13357 }
13358 run_test 150a "truncate/append tests"
13359
13360 test_150b() {
13361         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13362         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13363                 skip "Need OST version at least 2.13.53"
13364         touch $DIR/$tfile
13365         check_fallocate $DIR/$tfile || error "fallocate failed"
13366 }
13367 run_test 150b "Verify fallocate (prealloc) functionality"
13368
13369 test_150c() {
13370         local bytes
13371         local want
13372
13373         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13374         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13375                 skip "Need OST version at least 2.13.53"
13376
13377         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13378         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13379         sync; sync_all_data
13380         cancel_lru_locks $OSC
13381         sleep 5
13382         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13383         want=$((OSTCOUNT * 1048576))
13384
13385         # Must allocate all requested space, not more than 5% extra
13386         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13387                 error "bytes $bytes is not $want"
13388 }
13389 run_test 150c "Verify fallocate Size and Blocks"
13390
13391 test_150d() {
13392         local bytes
13393         local want
13394
13395         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13396         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13397                 skip "Need OST version at least 2.13.53"
13398
13399         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13400         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13401         sync; sync_all_data
13402         cancel_lru_locks $OSC
13403         sleep 5
13404         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13405         want=$((OSTCOUNT * 1048576))
13406
13407         # Must allocate all requested space, not more than 5% extra
13408         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13409                 error "bytes $bytes is not $want"
13410 }
13411 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13412
13413 test_150e() {
13414         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13415         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13416                 skip "Need OST version at least 2.13.55"
13417
13418         echo "df before:"
13419         $LFS df
13420         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13421                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13422
13423         # Find OST with Minimum Size
13424         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13425                        sort -un | head -1)
13426
13427         # Get 90% of the available space
13428         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13429
13430         fallocate -l${space}k $DIR/$tfile ||
13431                 error "fallocate ${space}k $DIR/$tfile failed"
13432         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13433
13434         # get size immediately after fallocate. This should be correctly
13435         # updated
13436         local size=$(stat -c '%s' $DIR/$tfile)
13437         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13438
13439         # Sleep for a while for statfs to get updated. And not pull from cache.
13440         sleep 2
13441
13442         echo "df after fallocate:"
13443         $LFS df
13444
13445         (( size / 1024 == space )) || error "size $size != requested $space"
13446         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13447                 error "used $used < space $space"
13448
13449         rm $DIR/$tfile || error "rm failed"
13450         sync
13451         wait_delete_completed
13452
13453         echo "df after unlink:"
13454         $LFS df
13455 }
13456 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13457
13458 #LU-2902 roc_hit was not able to read all values from lproc
13459 function roc_hit_init() {
13460         local list=$(comma_list $(osts_nodes))
13461         local dir=$DIR/$tdir-check
13462         local file=$dir/$tfile
13463         local BEFORE
13464         local AFTER
13465         local idx
13466
13467         test_mkdir $dir
13468         #use setstripe to do a write to every ost
13469         for i in $(seq 0 $((OSTCOUNT-1))); do
13470                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13471                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13472                 idx=$(printf %04x $i)
13473                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13474                         awk '$1 == "cache_access" {sum += $7}
13475                                 END { printf("%0.0f", sum) }')
13476
13477                 cancel_lru_locks osc
13478                 cat $file >/dev/null
13479
13480                 AFTER=$(get_osd_param $list *OST*$idx stats |
13481                         awk '$1 == "cache_access" {sum += $7}
13482                                 END { printf("%0.0f", sum) }')
13483
13484                 echo BEFORE:$BEFORE AFTER:$AFTER
13485                 if ! let "AFTER - BEFORE == 4"; then
13486                         rm -rf $dir
13487                         error "roc_hit is not safe to use"
13488                 fi
13489                 rm $file
13490         done
13491
13492         rm -rf $dir
13493 }
13494
13495 function roc_hit() {
13496         local list=$(comma_list $(osts_nodes))
13497         echo $(get_osd_param $list '' stats |
13498                 awk '$1 == "cache_hit" {sum += $7}
13499                         END { printf("%0.0f", sum) }')
13500 }
13501
13502 function set_cache() {
13503         local on=1
13504
13505         if [ "$2" == "off" ]; then
13506                 on=0;
13507         fi
13508         local list=$(comma_list $(osts_nodes))
13509         set_osd_param $list '' $1_cache_enable $on
13510
13511         cancel_lru_locks osc
13512 }
13513
13514 test_151() {
13515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13516         remote_ost_nodsh && skip "remote OST with nodsh"
13517
13518         local CPAGES=3
13519         local list=$(comma_list $(osts_nodes))
13520
13521         # check whether obdfilter is cache capable at all
13522         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13523                 skip "not cache-capable obdfilter"
13524         fi
13525
13526         # check cache is enabled on all obdfilters
13527         if get_osd_param $list '' read_cache_enable | grep 0; then
13528                 skip "oss cache is disabled"
13529         fi
13530
13531         set_osd_param $list '' writethrough_cache_enable 1
13532
13533         # check write cache is enabled on all obdfilters
13534         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13535                 skip "oss write cache is NOT enabled"
13536         fi
13537
13538         roc_hit_init
13539
13540         #define OBD_FAIL_OBD_NO_LRU  0x609
13541         do_nodes $list $LCTL set_param fail_loc=0x609
13542
13543         # pages should be in the case right after write
13544         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13545                 error "dd failed"
13546
13547         local BEFORE=$(roc_hit)
13548         cancel_lru_locks osc
13549         cat $DIR/$tfile >/dev/null
13550         local AFTER=$(roc_hit)
13551
13552         do_nodes $list $LCTL set_param fail_loc=0
13553
13554         if ! let "AFTER - BEFORE == CPAGES"; then
13555                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13556         fi
13557
13558         cancel_lru_locks osc
13559         # invalidates OST cache
13560         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13561         set_osd_param $list '' read_cache_enable 0
13562         cat $DIR/$tfile >/dev/null
13563
13564         # now data shouldn't be found in the cache
13565         BEFORE=$(roc_hit)
13566         cancel_lru_locks osc
13567         cat $DIR/$tfile >/dev/null
13568         AFTER=$(roc_hit)
13569         if let "AFTER - BEFORE != 0"; then
13570                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13571         fi
13572
13573         set_osd_param $list '' read_cache_enable 1
13574         rm -f $DIR/$tfile
13575 }
13576 run_test 151 "test cache on oss and controls ==============================="
13577
13578 test_152() {
13579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13580
13581         local TF="$TMP/$tfile"
13582
13583         # simulate ENOMEM during write
13584 #define OBD_FAIL_OST_NOMEM      0x226
13585         lctl set_param fail_loc=0x80000226
13586         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13587         cp $TF $DIR/$tfile
13588         sync || error "sync failed"
13589         lctl set_param fail_loc=0
13590
13591         # discard client's cache
13592         cancel_lru_locks osc
13593
13594         # simulate ENOMEM during read
13595         lctl set_param fail_loc=0x80000226
13596         cmp $TF $DIR/$tfile || error "cmp failed"
13597         lctl set_param fail_loc=0
13598
13599         rm -f $TF
13600 }
13601 run_test 152 "test read/write with enomem ============================"
13602
13603 test_153() {
13604         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13605 }
13606 run_test 153 "test if fdatasync does not crash ======================="
13607
13608 dot_lustre_fid_permission_check() {
13609         local fid=$1
13610         local ffid=$MOUNT/.lustre/fid/$fid
13611         local test_dir=$2
13612
13613         echo "stat fid $fid"
13614         stat $ffid > /dev/null || error "stat $ffid failed."
13615         echo "touch fid $fid"
13616         touch $ffid || error "touch $ffid failed."
13617         echo "write to fid $fid"
13618         cat /etc/hosts > $ffid || error "write $ffid failed."
13619         echo "read fid $fid"
13620         diff /etc/hosts $ffid || error "read $ffid failed."
13621         echo "append write to fid $fid"
13622         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13623         echo "rename fid $fid"
13624         mv $ffid $test_dir/$tfile.1 &&
13625                 error "rename $ffid to $tfile.1 should fail."
13626         touch $test_dir/$tfile.1
13627         mv $test_dir/$tfile.1 $ffid &&
13628                 error "rename $tfile.1 to $ffid should fail."
13629         rm -f $test_dir/$tfile.1
13630         echo "truncate fid $fid"
13631         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13632         echo "link fid $fid"
13633         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13634         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13635                 echo "setfacl fid $fid"
13636                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13637                 echo "getfacl fid $fid"
13638                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13639         fi
13640         echo "unlink fid $fid"
13641         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13642         echo "mknod fid $fid"
13643         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13644
13645         fid=[0xf00000400:0x1:0x0]
13646         ffid=$MOUNT/.lustre/fid/$fid
13647
13648         echo "stat non-exist fid $fid"
13649         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13650         echo "write to non-exist fid $fid"
13651         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13652         echo "link new fid $fid"
13653         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13654
13655         mkdir -p $test_dir/$tdir
13656         touch $test_dir/$tdir/$tfile
13657         fid=$($LFS path2fid $test_dir/$tdir)
13658         rc=$?
13659         [ $rc -ne 0 ] &&
13660                 error "error: could not get fid for $test_dir/$dir/$tfile."
13661
13662         ffid=$MOUNT/.lustre/fid/$fid
13663
13664         echo "ls $fid"
13665         ls $ffid > /dev/null || error "ls $ffid failed."
13666         echo "touch $fid/$tfile.1"
13667         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13668
13669         echo "touch $MOUNT/.lustre/fid/$tfile"
13670         touch $MOUNT/.lustre/fid/$tfile && \
13671                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13672
13673         echo "setxattr to $MOUNT/.lustre/fid"
13674         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13675
13676         echo "listxattr for $MOUNT/.lustre/fid"
13677         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13678
13679         echo "delxattr from $MOUNT/.lustre/fid"
13680         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13681
13682         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13683         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13684                 error "touch invalid fid should fail."
13685
13686         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13687         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13688                 error "touch non-normal fid should fail."
13689
13690         echo "rename $tdir to $MOUNT/.lustre/fid"
13691         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13692                 error "rename to $MOUNT/.lustre/fid should fail."
13693
13694         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13695         then            # LU-3547
13696                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13697                 local new_obf_mode=777
13698
13699                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13700                 chmod $new_obf_mode $DIR/.lustre/fid ||
13701                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13702
13703                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13704                 [ $obf_mode -eq $new_obf_mode ] ||
13705                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13706
13707                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13708                 chmod $old_obf_mode $DIR/.lustre/fid ||
13709                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13710         fi
13711
13712         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13713         fid=$($LFS path2fid $test_dir/$tfile-2)
13714
13715         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13716         then # LU-5424
13717                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13718                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13719                         error "create lov data thru .lustre failed"
13720         fi
13721         echo "cp /etc/passwd $test_dir/$tfile-2"
13722         cp /etc/passwd $test_dir/$tfile-2 ||
13723                 error "copy to $test_dir/$tfile-2 failed."
13724         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13725         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13726                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13727
13728         rm -rf $test_dir/tfile.lnk
13729         rm -rf $test_dir/$tfile-2
13730 }
13731
13732 test_154A() {
13733         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13734                 skip "Need MDS version at least 2.4.1"
13735
13736         local tf=$DIR/$tfile
13737         touch $tf
13738
13739         local fid=$($LFS path2fid $tf)
13740         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13741
13742         # check that we get the same pathname back
13743         local rootpath
13744         local found
13745         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13746                 echo "$rootpath $fid"
13747                 found=$($LFS fid2path $rootpath "$fid")
13748                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13749                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13750         done
13751
13752         # check wrong root path format
13753         rootpath=$MOUNT"_wrong"
13754         found=$($LFS fid2path $rootpath "$fid")
13755         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13756 }
13757 run_test 154A "lfs path2fid and fid2path basic checks"
13758
13759 test_154B() {
13760         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13761                 skip "Need MDS version at least 2.4.1"
13762
13763         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13764         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13765         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13766         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13767
13768         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13769         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13770
13771         # check that we get the same pathname
13772         echo "PFID: $PFID, name: $name"
13773         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13774         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13775         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13776                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13777
13778         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13779 }
13780 run_test 154B "verify the ll_decode_linkea tool"
13781
13782 test_154a() {
13783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13784         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13785         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13786                 skip "Need MDS version at least 2.2.51"
13787         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13788
13789         cp /etc/hosts $DIR/$tfile
13790
13791         fid=$($LFS path2fid $DIR/$tfile)
13792         rc=$?
13793         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13794
13795         dot_lustre_fid_permission_check "$fid" $DIR ||
13796                 error "dot lustre permission check $fid failed"
13797
13798         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13799
13800         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13801
13802         touch $MOUNT/.lustre/file &&
13803                 error "creation is not allowed under .lustre"
13804
13805         mkdir $MOUNT/.lustre/dir &&
13806                 error "mkdir is not allowed under .lustre"
13807
13808         rm -rf $DIR/$tfile
13809 }
13810 run_test 154a "Open-by-FID"
13811
13812 test_154b() {
13813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13814         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13816         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13817                 skip "Need MDS version at least 2.2.51"
13818
13819         local remote_dir=$DIR/$tdir/remote_dir
13820         local MDTIDX=1
13821         local rc=0
13822
13823         mkdir -p $DIR/$tdir
13824         $LFS mkdir -i $MDTIDX $remote_dir ||
13825                 error "create remote directory failed"
13826
13827         cp /etc/hosts $remote_dir/$tfile
13828
13829         fid=$($LFS path2fid $remote_dir/$tfile)
13830         rc=$?
13831         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13832
13833         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13834                 error "dot lustre permission check $fid failed"
13835         rm -rf $DIR/$tdir
13836 }
13837 run_test 154b "Open-by-FID for remote directory"
13838
13839 test_154c() {
13840         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13841                 skip "Need MDS version at least 2.4.1"
13842
13843         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13844         local FID1=$($LFS path2fid $DIR/$tfile.1)
13845         local FID2=$($LFS path2fid $DIR/$tfile.2)
13846         local FID3=$($LFS path2fid $DIR/$tfile.3)
13847
13848         local N=1
13849         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13850                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13851                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13852                 local want=FID$N
13853                 [ "$FID" = "${!want}" ] ||
13854                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13855                 N=$((N + 1))
13856         done
13857
13858         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13859         do
13860                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13861                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13862                 N=$((N + 1))
13863         done
13864 }
13865 run_test 154c "lfs path2fid and fid2path multiple arguments"
13866
13867 test_154d() {
13868         remote_mds_nodsh && skip "remote MDS with nodsh"
13869         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13870                 skip "Need MDS version at least 2.5.53"
13871
13872         if remote_mds; then
13873                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13874         else
13875                 nid="0@lo"
13876         fi
13877         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13878         local fd
13879         local cmd
13880
13881         rm -f $DIR/$tfile
13882         touch $DIR/$tfile
13883
13884         local fid=$($LFS path2fid $DIR/$tfile)
13885         # Open the file
13886         fd=$(free_fd)
13887         cmd="exec $fd<$DIR/$tfile"
13888         eval $cmd
13889         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13890         echo "$fid_list" | grep "$fid"
13891         rc=$?
13892
13893         cmd="exec $fd>/dev/null"
13894         eval $cmd
13895         if [ $rc -ne 0 ]; then
13896                 error "FID $fid not found in open files list $fid_list"
13897         fi
13898 }
13899 run_test 154d "Verify open file fid"
13900
13901 test_154e()
13902 {
13903         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13904                 skip "Need MDS version at least 2.6.50"
13905
13906         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13907                 error ".lustre returned by readdir"
13908         fi
13909 }
13910 run_test 154e ".lustre is not returned by readdir"
13911
13912 test_154f() {
13913         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13914
13915         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13916         test_mkdir -p -c1 $DIR/$tdir/d
13917         # test dirs inherit from its stripe
13918         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13919         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13920         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13921         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13922         touch $DIR/f
13923
13924         # get fid of parents
13925         local FID0=$($LFS path2fid $DIR/$tdir/d)
13926         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13927         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13928         local FID3=$($LFS path2fid $DIR)
13929
13930         # check that path2fid --parents returns expected <parent_fid>/name
13931         # 1) test for a directory (single parent)
13932         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13933         [ "$parent" == "$FID0/foo1" ] ||
13934                 error "expected parent: $FID0/foo1, got: $parent"
13935
13936         # 2) test for a file with nlink > 1 (multiple parents)
13937         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13938         echo "$parent" | grep -F "$FID1/$tfile" ||
13939                 error "$FID1/$tfile not returned in parent list"
13940         echo "$parent" | grep -F "$FID2/link" ||
13941                 error "$FID2/link not returned in parent list"
13942
13943         # 3) get parent by fid
13944         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13945         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13946         echo "$parent" | grep -F "$FID1/$tfile" ||
13947                 error "$FID1/$tfile not returned in parent list (by fid)"
13948         echo "$parent" | grep -F "$FID2/link" ||
13949                 error "$FID2/link not returned in parent list (by fid)"
13950
13951         # 4) test for entry in root directory
13952         parent=$($LFS path2fid --parents $DIR/f)
13953         echo "$parent" | grep -F "$FID3/f" ||
13954                 error "$FID3/f not returned in parent list"
13955
13956         # 5) test it on root directory
13957         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13958                 error "$MOUNT should not have parents"
13959
13960         # enable xattr caching and check that linkea is correctly updated
13961         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13962         save_lustre_params client "llite.*.xattr_cache" > $save
13963         lctl set_param llite.*.xattr_cache 1
13964
13965         # 6.1) linkea update on rename
13966         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13967
13968         # get parents by fid
13969         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13970         # foo1 should no longer be returned in parent list
13971         echo "$parent" | grep -F "$FID1" &&
13972                 error "$FID1 should no longer be in parent list"
13973         # the new path should appear
13974         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13975                 error "$FID2/$tfile.moved is not in parent list"
13976
13977         # 6.2) linkea update on unlink
13978         rm -f $DIR/$tdir/d/foo2/link
13979         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13980         # foo2/link should no longer be returned in parent list
13981         echo "$parent" | grep -F "$FID2/link" &&
13982                 error "$FID2/link should no longer be in parent list"
13983         true
13984
13985         rm -f $DIR/f
13986         restore_lustre_params < $save
13987         rm -f $save
13988 }
13989 run_test 154f "get parent fids by reading link ea"
13990
13991 test_154g()
13992 {
13993         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13994         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13995            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13996                 skip "Need MDS version at least 2.6.92"
13997
13998         mkdir -p $DIR/$tdir
13999         llapi_fid_test -d $DIR/$tdir
14000 }
14001 run_test 154g "various llapi FID tests"
14002
14003 test_155_small_load() {
14004     local temp=$TMP/$tfile
14005     local file=$DIR/$tfile
14006
14007     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14008         error "dd of=$temp bs=6096 count=1 failed"
14009     cp $temp $file
14010     cancel_lru_locks $OSC
14011     cmp $temp $file || error "$temp $file differ"
14012
14013     $TRUNCATE $temp 6000
14014     $TRUNCATE $file 6000
14015     cmp $temp $file || error "$temp $file differ (truncate1)"
14016
14017     echo "12345" >>$temp
14018     echo "12345" >>$file
14019     cmp $temp $file || error "$temp $file differ (append1)"
14020
14021     echo "12345" >>$temp
14022     echo "12345" >>$file
14023     cmp $temp $file || error "$temp $file differ (append2)"
14024
14025     rm -f $temp $file
14026     true
14027 }
14028
14029 test_155_big_load() {
14030         remote_ost_nodsh && skip "remote OST with nodsh"
14031
14032         local temp=$TMP/$tfile
14033         local file=$DIR/$tfile
14034
14035         free_min_max
14036         local cache_size=$(do_facet ost$((MAXI+1)) \
14037                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14038         local large_file_size=$((cache_size * 2))
14039
14040         echo "OSS cache size: $cache_size KB"
14041         echo "Large file size: $large_file_size KB"
14042
14043         [ $MAXV -le $large_file_size ] &&
14044                 skip_env "max available OST size needs > $large_file_size KB"
14045
14046         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14047
14048         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14049                 error "dd of=$temp bs=$large_file_size count=1k failed"
14050         cp $temp $file
14051         ls -lh $temp $file
14052         cancel_lru_locks osc
14053         cmp $temp $file || error "$temp $file differ"
14054
14055         rm -f $temp $file
14056         true
14057 }
14058
14059 save_writethrough() {
14060         local facets=$(get_facets OST)
14061
14062         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14063 }
14064
14065 test_155a() {
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 on
14074         test_155_small_load
14075         restore_lustre_params < $p
14076         rm -f $p
14077 }
14078 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14079
14080 test_155b() {
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 on
14088         set_cache writethrough off
14089         test_155_small_load
14090         restore_lustre_params < $p
14091         rm -f $p
14092 }
14093 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14094
14095 test_155c() {
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 on
14104         test_155_small_load
14105         restore_lustre_params < $p
14106         rm -f $p
14107 }
14108 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14109
14110 test_155d() {
14111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14112
14113         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14114
14115         save_writethrough $p
14116
14117         set_cache read off
14118         set_cache writethrough off
14119         test_155_small_load
14120         restore_lustre_params < $p
14121         rm -f $p
14122 }
14123 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14124
14125 test_155e() {
14126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14127
14128         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14129
14130         save_writethrough $p
14131
14132         set_cache read on
14133         set_cache writethrough on
14134         test_155_big_load
14135         restore_lustre_params < $p
14136         rm -f $p
14137 }
14138 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14139
14140 test_155f() {
14141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14142
14143         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14144
14145         save_writethrough $p
14146
14147         set_cache read on
14148         set_cache writethrough off
14149         test_155_big_load
14150         restore_lustre_params < $p
14151         rm -f $p
14152 }
14153 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14154
14155 test_155g() {
14156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14157
14158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14159
14160         save_writethrough $p
14161
14162         set_cache read off
14163         set_cache writethrough on
14164         test_155_big_load
14165         restore_lustre_params < $p
14166         rm -f $p
14167 }
14168 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14169
14170 test_155h() {
14171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14172
14173         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14174
14175         save_writethrough $p
14176
14177         set_cache read off
14178         set_cache writethrough off
14179         test_155_big_load
14180         restore_lustre_params < $p
14181         rm -f $p
14182 }
14183 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14184
14185 test_156() {
14186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14187         remote_ost_nodsh && skip "remote OST with nodsh"
14188         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14189                 skip "stats not implemented on old servers"
14190         [ "$ost1_FSTYPE" = "zfs" ] &&
14191                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14192
14193         local CPAGES=3
14194         local BEFORE
14195         local AFTER
14196         local file="$DIR/$tfile"
14197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14198
14199         save_writethrough $p
14200         roc_hit_init
14201
14202         log "Turn on read and write cache"
14203         set_cache read on
14204         set_cache writethrough on
14205
14206         log "Write data and read it back."
14207         log "Read should be satisfied from the cache."
14208         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14209         BEFORE=$(roc_hit)
14210         cancel_lru_locks osc
14211         cat $file >/dev/null
14212         AFTER=$(roc_hit)
14213         if ! let "AFTER - BEFORE == CPAGES"; then
14214                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14215         else
14216                 log "cache hits: before: $BEFORE, after: $AFTER"
14217         fi
14218
14219         log "Read again; it should be satisfied from the cache."
14220         BEFORE=$AFTER
14221         cancel_lru_locks osc
14222         cat $file >/dev/null
14223         AFTER=$(roc_hit)
14224         if ! let "AFTER - BEFORE == CPAGES"; then
14225                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14226         else
14227                 log "cache hits:: before: $BEFORE, after: $AFTER"
14228         fi
14229
14230         log "Turn off the read cache and turn on the write cache"
14231         set_cache read off
14232         set_cache writethrough on
14233
14234         log "Read again; it should be satisfied from the cache."
14235         BEFORE=$(roc_hit)
14236         cancel_lru_locks osc
14237         cat $file >/dev/null
14238         AFTER=$(roc_hit)
14239         if ! let "AFTER - BEFORE == CPAGES"; then
14240                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14241         else
14242                 log "cache hits:: before: $BEFORE, after: $AFTER"
14243         fi
14244
14245         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14246                 # > 2.12.56 uses pagecache if cached
14247                 log "Read again; it should not be satisfied from the cache."
14248                 BEFORE=$AFTER
14249                 cancel_lru_locks osc
14250                 cat $file >/dev/null
14251                 AFTER=$(roc_hit)
14252                 if ! let "AFTER - BEFORE == 0"; then
14253                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14254                 else
14255                         log "cache hits:: before: $BEFORE, after: $AFTER"
14256                 fi
14257         fi
14258
14259         log "Write data and read it back."
14260         log "Read should be satisfied from the cache."
14261         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14262         BEFORE=$(roc_hit)
14263         cancel_lru_locks osc
14264         cat $file >/dev/null
14265         AFTER=$(roc_hit)
14266         if ! let "AFTER - BEFORE == CPAGES"; then
14267                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14268         else
14269                 log "cache hits:: before: $BEFORE, after: $AFTER"
14270         fi
14271
14272         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14273                 # > 2.12.56 uses pagecache if cached
14274                 log "Read again; it should not be satisfied from the cache."
14275                 BEFORE=$AFTER
14276                 cancel_lru_locks osc
14277                 cat $file >/dev/null
14278                 AFTER=$(roc_hit)
14279                 if ! let "AFTER - BEFORE == 0"; then
14280                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14281                 else
14282                         log "cache hits:: before: $BEFORE, after: $AFTER"
14283                 fi
14284         fi
14285
14286         log "Turn off read and write cache"
14287         set_cache read off
14288         set_cache writethrough off
14289
14290         log "Write data and read it back"
14291         log "It should not be satisfied from the cache."
14292         rm -f $file
14293         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14294         cancel_lru_locks osc
14295         BEFORE=$(roc_hit)
14296         cat $file >/dev/null
14297         AFTER=$(roc_hit)
14298         if ! let "AFTER - BEFORE == 0"; then
14299                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14300         else
14301                 log "cache hits:: before: $BEFORE, after: $AFTER"
14302         fi
14303
14304         log "Turn on the read cache and turn off the write cache"
14305         set_cache read on
14306         set_cache writethrough off
14307
14308         log "Write data and read it back"
14309         log "It should not be satisfied from the cache."
14310         rm -f $file
14311         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14312         BEFORE=$(roc_hit)
14313         cancel_lru_locks osc
14314         cat $file >/dev/null
14315         AFTER=$(roc_hit)
14316         if ! let "AFTER - BEFORE == 0"; then
14317                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14318         else
14319                 log "cache hits:: before: $BEFORE, after: $AFTER"
14320         fi
14321
14322         log "Read again; it should be satisfied from the cache."
14323         BEFORE=$(roc_hit)
14324         cancel_lru_locks osc
14325         cat $file >/dev/null
14326         AFTER=$(roc_hit)
14327         if ! let "AFTER - BEFORE == CPAGES"; then
14328                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14329         else
14330                 log "cache hits:: before: $BEFORE, after: $AFTER"
14331         fi
14332
14333         restore_lustre_params < $p
14334         rm -f $p $file
14335 }
14336 run_test 156 "Verification of tunables"
14337
14338 test_160a() {
14339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14340         remote_mds_nodsh && skip "remote MDS with nodsh"
14341         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14342                 skip "Need MDS version at least 2.2.0"
14343
14344         changelog_register || error "changelog_register failed"
14345         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14346         changelog_users $SINGLEMDS | grep -q $cl_user ||
14347                 error "User $cl_user not found in changelog_users"
14348
14349         # change something
14350         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14351         changelog_clear 0 || error "changelog_clear failed"
14352         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14353         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14354         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14355         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14356         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14357         rm $DIR/$tdir/pics/desktop.jpg
14358
14359         changelog_dump | tail -10
14360
14361         echo "verifying changelog mask"
14362         changelog_chmask "-MKDIR"
14363         changelog_chmask "-CLOSE"
14364
14365         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14366         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14367
14368         changelog_chmask "+MKDIR"
14369         changelog_chmask "+CLOSE"
14370
14371         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14372         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14373
14374         changelog_dump | tail -10
14375         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14376         CLOSES=$(changelog_dump | grep -c "CLOSE")
14377         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14378         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14379
14380         # verify contents
14381         echo "verifying target fid"
14382         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14383         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14384         [ "$fidc" == "$fidf" ] ||
14385                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14386         echo "verifying parent fid"
14387         # The FID returned from the Changelog may be the directory shard on
14388         # a different MDT, and not the FID returned by path2fid on the parent.
14389         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14390         # since this is what will matter when recreating this file in the tree.
14391         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14392         local pathp=$($LFS fid2path $MOUNT "$fidp")
14393         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14394                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14395
14396         echo "getting records for $cl_user"
14397         changelog_users $SINGLEMDS
14398         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14399         local nclr=3
14400         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14401                 error "changelog_clear failed"
14402         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14403         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14404         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14405                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14406
14407         local min0_rec=$(changelog_users $SINGLEMDS |
14408                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14409         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14410                           awk '{ print $1; exit; }')
14411
14412         changelog_dump | tail -n 5
14413         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14414         [ $first_rec == $((min0_rec + 1)) ] ||
14415                 error "first index should be $min0_rec + 1 not $first_rec"
14416
14417         # LU-3446 changelog index reset on MDT restart
14418         local cur_rec1=$(changelog_users $SINGLEMDS |
14419                          awk '/^current.index:/ { print $NF }')
14420         changelog_clear 0 ||
14421                 error "clear all changelog records for $cl_user failed"
14422         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14423         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14424                 error "Fail to start $SINGLEMDS"
14425         local cur_rec2=$(changelog_users $SINGLEMDS |
14426                          awk '/^current.index:/ { print $NF }')
14427         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14428         [ $cur_rec1 == $cur_rec2 ] ||
14429                 error "current index should be $cur_rec1 not $cur_rec2"
14430
14431         echo "verifying users from this test are deregistered"
14432         changelog_deregister || error "changelog_deregister failed"
14433         changelog_users $SINGLEMDS | grep -q $cl_user &&
14434                 error "User '$cl_user' still in changelog_users"
14435
14436         # lctl get_param -n mdd.*.changelog_users
14437         # current index: 144
14438         # ID    index (idle seconds)
14439         # cl3   144 (2)
14440         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14441                 # this is the normal case where all users were deregistered
14442                 # make sure no new records are added when no users are present
14443                 local last_rec1=$(changelog_users $SINGLEMDS |
14444                                   awk '/^current.index:/ { print $NF }')
14445                 touch $DIR/$tdir/chloe
14446                 local last_rec2=$(changelog_users $SINGLEMDS |
14447                                   awk '/^current.index:/ { print $NF }')
14448                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14449                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14450         else
14451                 # any changelog users must be leftovers from a previous test
14452                 changelog_users $SINGLEMDS
14453                 echo "other changelog users; can't verify off"
14454         fi
14455 }
14456 run_test 160a "changelog sanity"
14457
14458 test_160b() { # LU-3587
14459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14460         remote_mds_nodsh && skip "remote MDS with nodsh"
14461         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14462                 skip "Need MDS version at least 2.2.0"
14463
14464         changelog_register || error "changelog_register failed"
14465         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14466         changelog_users $SINGLEMDS | grep -q $cl_user ||
14467                 error "User '$cl_user' not found in changelog_users"
14468
14469         local longname1=$(str_repeat a 255)
14470         local longname2=$(str_repeat b 255)
14471
14472         cd $DIR
14473         echo "creating very long named file"
14474         touch $longname1 || error "create of '$longname1' failed"
14475         echo "renaming very long named file"
14476         mv $longname1 $longname2
14477
14478         changelog_dump | grep RENME | tail -n 5
14479         rm -f $longname2
14480 }
14481 run_test 160b "Verify that very long rename doesn't crash in changelog"
14482
14483 test_160c() {
14484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14485         remote_mds_nodsh && skip "remote MDS with nodsh"
14486
14487         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14488                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14489                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14490                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14491
14492         local rc=0
14493
14494         # Registration step
14495         changelog_register || error "changelog_register failed"
14496
14497         rm -rf $DIR/$tdir
14498         mkdir -p $DIR/$tdir
14499         $MCREATE $DIR/$tdir/foo_160c
14500         changelog_chmask "-TRUNC"
14501         $TRUNCATE $DIR/$tdir/foo_160c 200
14502         changelog_chmask "+TRUNC"
14503         $TRUNCATE $DIR/$tdir/foo_160c 199
14504         changelog_dump | tail -n 5
14505         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14506         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14507 }
14508 run_test 160c "verify that changelog log catch the truncate event"
14509
14510 test_160d() {
14511         remote_mds_nodsh && skip "remote MDS with nodsh"
14512         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14514         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14515                 skip "Need MDS version at least 2.7.60"
14516
14517         # Registration step
14518         changelog_register || error "changelog_register failed"
14519
14520         mkdir -p $DIR/$tdir/migrate_dir
14521         changelog_clear 0 || error "changelog_clear failed"
14522
14523         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14524         changelog_dump | tail -n 5
14525         local migrates=$(changelog_dump | grep -c "MIGRT")
14526         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14527 }
14528 run_test 160d "verify that changelog log catch the migrate event"
14529
14530 test_160e() {
14531         remote_mds_nodsh && skip "remote MDS with nodsh"
14532
14533         # Create a user
14534         changelog_register || error "changelog_register failed"
14535
14536         # Delete a future user (expect fail)
14537         local MDT0=$(facet_svc $SINGLEMDS)
14538         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14539         local rc=$?
14540
14541         if [ $rc -eq 0 ]; then
14542                 error "Deleted non-existant user cl77"
14543         elif [ $rc -ne 2 ]; then
14544                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14545         fi
14546
14547         # Clear to a bad index (1 billion should be safe)
14548         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14549         rc=$?
14550
14551         if [ $rc -eq 0 ]; then
14552                 error "Successfully cleared to invalid CL index"
14553         elif [ $rc -ne 22 ]; then
14554                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14555         fi
14556 }
14557 run_test 160e "changelog negative testing (should return errors)"
14558
14559 test_160f() {
14560         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14561         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14562                 skip "Need MDS version at least 2.10.56"
14563
14564         local mdts=$(comma_list $(mdts_nodes))
14565
14566         # Create a user
14567         changelog_register || error "first changelog_register failed"
14568         changelog_register || error "second changelog_register failed"
14569         local cl_users
14570         declare -A cl_user1
14571         declare -A cl_user2
14572         local user_rec1
14573         local user_rec2
14574         local i
14575
14576         # generate some changelog records to accumulate on each MDT
14577         # use fnv1a because created files should be evenly distributed
14578         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14579                 error "test_mkdir $tdir failed"
14580         log "$(date +%s): creating first files"
14581         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14582                 error "create $DIR/$tdir/$tfile failed"
14583
14584         # check changelogs have been generated
14585         local start=$SECONDS
14586         local idle_time=$((MDSCOUNT * 5 + 5))
14587         local nbcl=$(changelog_dump | wc -l)
14588         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14589
14590         for param in "changelog_max_idle_time=$idle_time" \
14591                      "changelog_gc=1" \
14592                      "changelog_min_gc_interval=2" \
14593                      "changelog_min_free_cat_entries=3"; do
14594                 local MDT0=$(facet_svc $SINGLEMDS)
14595                 local var="${param%=*}"
14596                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14597
14598                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14599                 do_nodes $mdts $LCTL set_param mdd.*.$param
14600         done
14601
14602         # force cl_user2 to be idle (1st part), but also cancel the
14603         # cl_user1 records so that it is not evicted later in the test.
14604         local sleep1=$((idle_time / 2))
14605         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14606         sleep $sleep1
14607
14608         # simulate changelog catalog almost full
14609         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14610         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14611
14612         for i in $(seq $MDSCOUNT); do
14613                 cl_users=(${CL_USERS[mds$i]})
14614                 cl_user1[mds$i]="${cl_users[0]}"
14615                 cl_user2[mds$i]="${cl_users[1]}"
14616
14617                 [ -n "${cl_user1[mds$i]}" ] ||
14618                         error "mds$i: no user registered"
14619                 [ -n "${cl_user2[mds$i]}" ] ||
14620                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14621
14622                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14623                 [ -n "$user_rec1" ] ||
14624                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14625                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14626                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14627                 [ -n "$user_rec2" ] ||
14628                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14629                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14630                      "$user_rec1 + 2 == $user_rec2"
14631                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14632                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14633                               "$user_rec1 + 2, but is $user_rec2"
14634                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14635                 [ -n "$user_rec2" ] ||
14636                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14637                 [ $user_rec1 == $user_rec2 ] ||
14638                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14639                               "$user_rec1, but is $user_rec2"
14640         done
14641
14642         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14643         local sleep2=$((idle_time - (SECONDS - start) + 1))
14644         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14645         sleep $sleep2
14646
14647         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14648         # cl_user1 should be OK because it recently processed records.
14649         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14650         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14651                 error "create $DIR/$tdir/${tfile}b failed"
14652
14653         # ensure gc thread is done
14654         for i in $(mdts_nodes); do
14655                 wait_update $i \
14656                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14657                         error "$i: GC-thread not done"
14658         done
14659
14660         local first_rec
14661         for i in $(seq $MDSCOUNT); do
14662                 # check cl_user1 still registered
14663                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14664                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14665                 # check cl_user2 unregistered
14666                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14667                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14668
14669                 # check changelogs are present and starting at $user_rec1 + 1
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                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14674                             awk '{ print $1; exit; }')
14675
14676                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14677                 [ $((user_rec1 + 1)) == $first_rec ] ||
14678                         error "mds$i: first index should be $user_rec1 + 1, " \
14679                               "but is $first_rec"
14680         done
14681 }
14682 run_test 160f "changelog garbage collect (timestamped users)"
14683
14684 test_160g() {
14685         remote_mds_nodsh && skip "remote MDS with nodsh"
14686         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14687                 skip "Need MDS version at least 2.10.56"
14688
14689         local mdts=$(comma_list $(mdts_nodes))
14690
14691         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14692         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14693
14694         # Create a user
14695         changelog_register || error "first changelog_register failed"
14696         changelog_register || error "second changelog_register failed"
14697         local cl_users
14698         declare -A cl_user1
14699         declare -A cl_user2
14700         local user_rec1
14701         local user_rec2
14702         local i
14703
14704         # generate some changelog records to accumulate on each MDT
14705         # use fnv1a because created files should be evenly distributed
14706         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14707                 error "mkdir $tdir failed"
14708         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14709                 error "create $DIR/$tdir/$tfile failed"
14710
14711         # check changelogs have been generated
14712         local nbcl=$(changelog_dump | wc -l)
14713         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14714
14715         # reduce the max_idle_indexes value to make sure we exceed it
14716         max_ndx=$((nbcl / 2 - 1))
14717
14718         for param in "changelog_max_idle_indexes=$max_ndx" \
14719                      "changelog_gc=1" \
14720                      "changelog_min_gc_interval=2" \
14721                      "changelog_min_free_cat_entries=3"; do
14722                 local MDT0=$(facet_svc $SINGLEMDS)
14723                 local var="${param%=*}"
14724                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14725
14726                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14727                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14728                         error "unable to set mdd.*.$param"
14729         done
14730
14731         # simulate changelog catalog almost full
14732         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14733         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14734
14735         for i in $(seq $MDSCOUNT); do
14736                 cl_users=(${CL_USERS[mds$i]})
14737                 cl_user1[mds$i]="${cl_users[0]}"
14738                 cl_user2[mds$i]="${cl_users[1]}"
14739
14740                 [ -n "${cl_user1[mds$i]}" ] ||
14741                         error "mds$i: no user registered"
14742                 [ -n "${cl_user2[mds$i]}" ] ||
14743                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14744
14745                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14746                 [ -n "$user_rec1" ] ||
14747                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14748                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14749                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14750                 [ -n "$user_rec2" ] ||
14751                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14752                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14753                      "$user_rec1 + 2 == $user_rec2"
14754                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14755                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14756                               "$user_rec1 + 2, but is $user_rec2"
14757                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14758                 [ -n "$user_rec2" ] ||
14759                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14760                 [ $user_rec1 == $user_rec2 ] ||
14761                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14762                               "$user_rec1, but is $user_rec2"
14763         done
14764
14765         # ensure we are past the previous changelog_min_gc_interval set above
14766         sleep 2
14767
14768         # generate one more changelog to trigger fail_loc
14769         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14770                 error "create $DIR/$tdir/${tfile}bis failed"
14771
14772         # ensure gc thread is done
14773         for i in $(mdts_nodes); do
14774                 wait_update $i \
14775                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14776                         error "$i: GC-thread not done"
14777         done
14778
14779         local first_rec
14780         for i in $(seq $MDSCOUNT); do
14781                 # check cl_user1 still registered
14782                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14783                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14784                 # check cl_user2 unregistered
14785                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14786                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14787
14788                 # check changelogs are present and starting at $user_rec1 + 1
14789                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14790                 [ -n "$user_rec1" ] ||
14791                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14792                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14793                             awk '{ print $1; exit; }')
14794
14795                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14796                 [ $((user_rec1 + 1)) == $first_rec ] ||
14797                         error "mds$i: first index should be $user_rec1 + 1, " \
14798                               "but is $first_rec"
14799         done
14800 }
14801 run_test 160g "changelog garbage collect (old users)"
14802
14803 test_160h() {
14804         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14805         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14806                 skip "Need MDS version at least 2.10.56"
14807
14808         local mdts=$(comma_list $(mdts_nodes))
14809
14810         # Create a user
14811         changelog_register || error "first changelog_register failed"
14812         changelog_register || error "second changelog_register failed"
14813         local cl_users
14814         declare -A cl_user1
14815         declare -A cl_user2
14816         local user_rec1
14817         local user_rec2
14818         local i
14819
14820         # generate some changelog records to accumulate on each MDT
14821         # use fnv1a because created files should be evenly distributed
14822         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14823                 error "test_mkdir $tdir failed"
14824         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14825                 error "create $DIR/$tdir/$tfile failed"
14826
14827         # check changelogs have been generated
14828         local nbcl=$(changelog_dump | wc -l)
14829         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14830
14831         for param in "changelog_max_idle_time=10" \
14832                      "changelog_gc=1" \
14833                      "changelog_min_gc_interval=2"; do
14834                 local MDT0=$(facet_svc $SINGLEMDS)
14835                 local var="${param%=*}"
14836                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14837
14838                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14839                 do_nodes $mdts $LCTL set_param mdd.*.$param
14840         done
14841
14842         # force cl_user2 to be idle (1st part)
14843         sleep 9
14844
14845         for i in $(seq $MDSCOUNT); do
14846                 cl_users=(${CL_USERS[mds$i]})
14847                 cl_user1[mds$i]="${cl_users[0]}"
14848                 cl_user2[mds$i]="${cl_users[1]}"
14849
14850                 [ -n "${cl_user1[mds$i]}" ] ||
14851                         error "mds$i: no user registered"
14852                 [ -n "${cl_user2[mds$i]}" ] ||
14853                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14854
14855                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14856                 [ -n "$user_rec1" ] ||
14857                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14858                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14859                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14860                 [ -n "$user_rec2" ] ||
14861                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14862                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14863                      "$user_rec1 + 2 == $user_rec2"
14864                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14865                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14866                               "$user_rec1 + 2, but is $user_rec2"
14867                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14868                 [ -n "$user_rec2" ] ||
14869                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14870                 [ $user_rec1 == $user_rec2 ] ||
14871                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14872                               "$user_rec1, but is $user_rec2"
14873         done
14874
14875         # force cl_user2 to be idle (2nd part) and to reach
14876         # changelog_max_idle_time
14877         sleep 2
14878
14879         # force each GC-thread start and block then
14880         # one per MDT/MDD, set fail_val accordingly
14881         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14882         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14883
14884         # generate more changelogs to trigger fail_loc
14885         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14886                 error "create $DIR/$tdir/${tfile}bis failed"
14887
14888         # stop MDT to stop GC-thread, should be done in back-ground as it will
14889         # block waiting for the thread to be released and exit
14890         declare -A stop_pids
14891         for i in $(seq $MDSCOUNT); do
14892                 stop mds$i &
14893                 stop_pids[mds$i]=$!
14894         done
14895
14896         for i in $(mdts_nodes); do
14897                 local facet
14898                 local nb=0
14899                 local facets=$(facets_up_on_host $i)
14900
14901                 for facet in ${facets//,/ }; do
14902                         if [[ $facet == mds* ]]; then
14903                                 nb=$((nb + 1))
14904                         fi
14905                 done
14906                 # ensure each MDS's gc threads are still present and all in "R"
14907                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14908                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14909                         error "$i: expected $nb GC-thread"
14910                 wait_update $i \
14911                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14912                         "R" 20 ||
14913                         error "$i: GC-thread not found in R-state"
14914                 # check umounts of each MDT on MDS have reached kthread_stop()
14915                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14916                         error "$i: expected $nb umount"
14917                 wait_update $i \
14918                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14919                         error "$i: umount not found in D-state"
14920         done
14921
14922         # release all GC-threads
14923         do_nodes $mdts $LCTL set_param fail_loc=0
14924
14925         # wait for MDT stop to complete
14926         for i in $(seq $MDSCOUNT); do
14927                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14928         done
14929
14930         # XXX
14931         # may try to check if any orphan changelog records are present
14932         # via ldiskfs/zfs and llog_reader...
14933
14934         # re-start/mount MDTs
14935         for i in $(seq $MDSCOUNT); do
14936                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14937                         error "Fail to start mds$i"
14938         done
14939
14940         local first_rec
14941         for i in $(seq $MDSCOUNT); do
14942                 # check cl_user1 still registered
14943                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14944                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14945                 # check cl_user2 unregistered
14946                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14947                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14948
14949                 # check changelogs are present and starting at $user_rec1 + 1
14950                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14951                 [ -n "$user_rec1" ] ||
14952                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14953                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14954                             awk '{ print $1; exit; }')
14955
14956                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14957                 [ $((user_rec1 + 1)) == $first_rec ] ||
14958                         error "mds$i: first index should be $user_rec1 + 1, " \
14959                               "but is $first_rec"
14960         done
14961 }
14962 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14963               "during mount"
14964
14965 test_160i() {
14966
14967         local mdts=$(comma_list $(mdts_nodes))
14968
14969         changelog_register || error "first changelog_register failed"
14970
14971         # generate some changelog records to accumulate on each MDT
14972         # use fnv1a because created files should be evenly distributed
14973         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14974                 error "mkdir $tdir failed"
14975         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14976                 error "create $DIR/$tdir/$tfile failed"
14977
14978         # check changelogs have been generated
14979         local nbcl=$(changelog_dump | wc -l)
14980         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14981
14982         # simulate race between register and unregister
14983         # XXX as fail_loc is set per-MDS, with DNE configs the race
14984         # simulation will only occur for one MDT per MDS and for the
14985         # others the normal race scenario will take place
14986         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14987         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14988         do_nodes $mdts $LCTL set_param fail_val=1
14989
14990         # unregister 1st user
14991         changelog_deregister &
14992         local pid1=$!
14993         # wait some time for deregister work to reach race rdv
14994         sleep 2
14995         # register 2nd user
14996         changelog_register || error "2nd user register failed"
14997
14998         wait $pid1 || error "1st user deregister failed"
14999
15000         local i
15001         local last_rec
15002         declare -A LAST_REC
15003         for i in $(seq $MDSCOUNT); do
15004                 if changelog_users mds$i | grep "^cl"; then
15005                         # make sure new records are added with one user present
15006                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15007                                           awk '/^current.index:/ { print $NF }')
15008                 else
15009                         error "mds$i has no user registered"
15010                 fi
15011         done
15012
15013         # generate more changelog records to accumulate on each MDT
15014         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15015                 error "create $DIR/$tdir/${tfile}bis failed"
15016
15017         for i in $(seq $MDSCOUNT); do
15018                 last_rec=$(changelog_users $SINGLEMDS |
15019                            awk '/^current.index:/ { print $NF }')
15020                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15021                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15022                         error "changelogs are off on mds$i"
15023         done
15024 }
15025 run_test 160i "changelog user register/unregister race"
15026
15027 test_160j() {
15028         remote_mds_nodsh && skip "remote MDS with nodsh"
15029         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15030                 skip "Need MDS version at least 2.12.56"
15031
15032         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15033         stack_trap "umount $MOUNT2" EXIT
15034
15035         changelog_register || error "first changelog_register failed"
15036         stack_trap "changelog_deregister" EXIT
15037
15038         # generate some changelog
15039         # use fnv1a because created files should be evenly distributed
15040         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15041                 error "mkdir $tdir failed"
15042         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15043                 error "create $DIR/$tdir/${tfile}bis failed"
15044
15045         # open the changelog device
15046         exec 3>/dev/changelog-$FSNAME-MDT0000
15047         stack_trap "exec 3>&-" EXIT
15048         exec 4</dev/changelog-$FSNAME-MDT0000
15049         stack_trap "exec 4<&-" EXIT
15050
15051         # umount the first lustre mount
15052         umount $MOUNT
15053         stack_trap "mount_client $MOUNT" EXIT
15054
15055         # read changelog
15056         cat <&4 >/dev/null || error "read changelog failed"
15057
15058         # clear changelog
15059         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15060         changelog_users $SINGLEMDS | grep -q $cl_user ||
15061                 error "User $cl_user not found in changelog_users"
15062
15063         printf 'clear:'$cl_user':0' >&3
15064 }
15065 run_test 160j "client can be umounted  while its chanangelog is being used"
15066
15067 test_160k() {
15068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15069         remote_mds_nodsh && skip "remote MDS with nodsh"
15070
15071         mkdir -p $DIR/$tdir/1/1
15072
15073         changelog_register || error "changelog_register failed"
15074         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15075
15076         changelog_users $SINGLEMDS | grep -q $cl_user ||
15077                 error "User '$cl_user' not found in changelog_users"
15078 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15079         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15080         rmdir $DIR/$tdir/1/1 & sleep 1
15081         mkdir $DIR/$tdir/2
15082         touch $DIR/$tdir/2/2
15083         rm -rf $DIR/$tdir/2
15084
15085         wait
15086         sleep 4
15087
15088         changelog_dump | grep rmdir || error "rmdir not recorded"
15089
15090         rm -rf $DIR/$tdir
15091         changelog_deregister
15092 }
15093 run_test 160k "Verify that changelog records are not lost"
15094
15095 # Verifies that a file passed as a parameter has recently had an operation
15096 # performed on it that has generated an MTIME changelog which contains the
15097 # correct parent FID. As files might reside on a different MDT from the
15098 # parent directory in DNE configurations, the FIDs are translated to paths
15099 # before being compared, which should be identical
15100 compare_mtime_changelog() {
15101         local file="${1}"
15102         local mdtidx
15103         local mtime
15104         local cl_fid
15105         local pdir
15106         local dir
15107
15108         mdtidx=$($LFS getstripe --mdt-index $file)
15109         mdtidx=$(printf "%04x" $mdtidx)
15110
15111         # Obtain the parent FID from the MTIME changelog
15112         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15113         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15114
15115         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15116         [ -z "$cl_fid" ] && error "parent FID not present"
15117
15118         # Verify that the path for the parent FID is the same as the path for
15119         # the test directory
15120         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15121
15122         dir=$(dirname $1)
15123
15124         [[ "${pdir%/}" == "$dir" ]] ||
15125                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15126 }
15127
15128 test_160l() {
15129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15130
15131         remote_mds_nodsh && skip "remote MDS with nodsh"
15132         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15133                 skip "Need MDS version at least 2.13.55"
15134
15135         local cl_user
15136
15137         changelog_register || error "changelog_register failed"
15138         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15139
15140         changelog_users $SINGLEMDS | grep -q $cl_user ||
15141                 error "User '$cl_user' not found in changelog_users"
15142
15143         # Clear some types so that MTIME changelogs are generated
15144         changelog_chmask "-CREAT"
15145         changelog_chmask "-CLOSE"
15146
15147         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15148
15149         # Test CL_MTIME during setattr
15150         touch $DIR/$tdir/$tfile
15151         compare_mtime_changelog $DIR/$tdir/$tfile
15152
15153         # Test CL_MTIME during close
15154         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15155                 error "cannot create file $DIR/$tdir/${tfile}_2"
15156         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15157 }
15158 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15159
15160 test_161a() {
15161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15162
15163         test_mkdir -c1 $DIR/$tdir
15164         cp /etc/hosts $DIR/$tdir/$tfile
15165         test_mkdir -c1 $DIR/$tdir/foo1
15166         test_mkdir -c1 $DIR/$tdir/foo2
15167         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15168         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15169         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15170         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15171         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15172         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15173                 $LFS fid2path $DIR $FID
15174                 error "bad link ea"
15175         fi
15176         # middle
15177         rm $DIR/$tdir/foo2/zachary
15178         # last
15179         rm $DIR/$tdir/foo2/thor
15180         # first
15181         rm $DIR/$tdir/$tfile
15182         # rename
15183         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15184         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15185                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15186         rm $DIR/$tdir/foo2/maggie
15187
15188         # overflow the EA
15189         local longname=$tfile.avg_len_is_thirty_two_
15190         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15191                 error_noexit 'failed to unlink many hardlinks'" EXIT
15192         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15193                 error "failed to hardlink many files"
15194         links=$($LFS fid2path $DIR $FID | wc -l)
15195         echo -n "${links}/1000 links in link EA"
15196         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15197 }
15198 run_test 161a "link ea sanity"
15199
15200 test_161b() {
15201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15202         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15203
15204         local MDTIDX=1
15205         local remote_dir=$DIR/$tdir/remote_dir
15206
15207         mkdir -p $DIR/$tdir
15208         $LFS mkdir -i $MDTIDX $remote_dir ||
15209                 error "create remote directory failed"
15210
15211         cp /etc/hosts $remote_dir/$tfile
15212         mkdir -p $remote_dir/foo1
15213         mkdir -p $remote_dir/foo2
15214         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15215         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15216         ln $remote_dir/$tfile $remote_dir/foo1/luna
15217         ln $remote_dir/$tfile $remote_dir/foo2/thor
15218
15219         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15220                      tr -d ']')
15221         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15222                 $LFS fid2path $DIR $FID
15223                 error "bad link ea"
15224         fi
15225         # middle
15226         rm $remote_dir/foo2/zachary
15227         # last
15228         rm $remote_dir/foo2/thor
15229         # first
15230         rm $remote_dir/$tfile
15231         # rename
15232         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15233         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15234         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15235                 $LFS fid2path $DIR $FID
15236                 error "bad link rename"
15237         fi
15238         rm $remote_dir/foo2/maggie
15239
15240         # overflow the EA
15241         local longname=filename_avg_len_is_thirty_two_
15242         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15243                 error "failed to hardlink many files"
15244         links=$($LFS fid2path $DIR $FID | wc -l)
15245         echo -n "${links}/1000 links in link EA"
15246         [[ ${links} -gt 60 ]] ||
15247                 error "expected at least 60 links in link EA"
15248         unlinkmany $remote_dir/foo2/$longname 1000 ||
15249         error "failed to unlink many hardlinks"
15250 }
15251 run_test 161b "link ea sanity under remote directory"
15252
15253 test_161c() {
15254         remote_mds_nodsh && skip "remote MDS with nodsh"
15255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15256         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15257                 skip "Need MDS version at least 2.1.5"
15258
15259         # define CLF_RENAME_LAST 0x0001
15260         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15261         changelog_register || error "changelog_register failed"
15262
15263         rm -rf $DIR/$tdir
15264         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15265         touch $DIR/$tdir/foo_161c
15266         touch $DIR/$tdir/bar_161c
15267         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15268         changelog_dump | grep RENME | tail -n 5
15269         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15270         changelog_clear 0 || error "changelog_clear failed"
15271         if [ x$flags != "x0x1" ]; then
15272                 error "flag $flags is not 0x1"
15273         fi
15274
15275         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15276         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15277         touch $DIR/$tdir/foo_161c
15278         touch $DIR/$tdir/bar_161c
15279         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15280         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15281         changelog_dump | grep RENME | tail -n 5
15282         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15283         changelog_clear 0 || error "changelog_clear failed"
15284         if [ x$flags != "x0x0" ]; then
15285                 error "flag $flags is not 0x0"
15286         fi
15287         echo "rename overwrite a target having nlink > 1," \
15288                 "changelog record has flags of $flags"
15289
15290         # rename doesn't overwrite a target (changelog flag 0x0)
15291         touch $DIR/$tdir/foo_161c
15292         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15293         changelog_dump | grep RENME | tail -n 5
15294         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15295         changelog_clear 0 || error "changelog_clear failed"
15296         if [ x$flags != "x0x0" ]; then
15297                 error "flag $flags is not 0x0"
15298         fi
15299         echo "rename doesn't overwrite a target," \
15300                 "changelog record has flags of $flags"
15301
15302         # define CLF_UNLINK_LAST 0x0001
15303         # unlink a file having nlink = 1 (changelog flag 0x1)
15304         rm -f $DIR/$tdir/foo2_161c
15305         changelog_dump | grep UNLNK | tail -n 5
15306         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15307         changelog_clear 0 || error "changelog_clear failed"
15308         if [ x$flags != "x0x1" ]; then
15309                 error "flag $flags is not 0x1"
15310         fi
15311         echo "unlink a file having nlink = 1," \
15312                 "changelog record has flags of $flags"
15313
15314         # unlink a file having nlink > 1 (changelog flag 0x0)
15315         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15316         rm -f $DIR/$tdir/foobar_161c
15317         changelog_dump | grep UNLNK | tail -n 5
15318         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15319         changelog_clear 0 || error "changelog_clear failed"
15320         if [ x$flags != "x0x0" ]; then
15321                 error "flag $flags is not 0x0"
15322         fi
15323         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15324 }
15325 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15326
15327 test_161d() {
15328         remote_mds_nodsh && skip "remote MDS with nodsh"
15329         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15330
15331         local pid
15332         local fid
15333
15334         changelog_register || error "changelog_register failed"
15335
15336         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15337         # interfer with $MOUNT/.lustre/fid/ access
15338         mkdir $DIR/$tdir
15339         [[ $? -eq 0 ]] || error "mkdir failed"
15340
15341         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15342         $LCTL set_param fail_loc=0x8000140c
15343         # 5s pause
15344         $LCTL set_param fail_val=5
15345
15346         # create file
15347         echo foofoo > $DIR/$tdir/$tfile &
15348         pid=$!
15349
15350         # wait for create to be delayed
15351         sleep 2
15352
15353         ps -p $pid
15354         [[ $? -eq 0 ]] || error "create should be blocked"
15355
15356         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15357         stack_trap "rm -f $tempfile"
15358         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15359         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15360         # some delay may occur during ChangeLog publishing and file read just
15361         # above, that could allow file write to happen finally
15362         [[ -s $tempfile ]] && echo "file should be empty"
15363
15364         $LCTL set_param fail_loc=0
15365
15366         wait $pid
15367         [[ $? -eq 0 ]] || error "create failed"
15368 }
15369 run_test 161d "create with concurrent .lustre/fid access"
15370
15371 check_path() {
15372         local expected="$1"
15373         shift
15374         local fid="$2"
15375
15376         local path
15377         path=$($LFS fid2path "$@")
15378         local rc=$?
15379
15380         if [ $rc -ne 0 ]; then
15381                 error "path looked up of '$expected' failed: rc=$rc"
15382         elif [ "$path" != "$expected" ]; then
15383                 error "path looked up '$path' instead of '$expected'"
15384         else
15385                 echo "FID '$fid' resolves to path '$path' as expected"
15386         fi
15387 }
15388
15389 test_162a() { # was test_162
15390         test_mkdir -p -c1 $DIR/$tdir/d2
15391         touch $DIR/$tdir/d2/$tfile
15392         touch $DIR/$tdir/d2/x1
15393         touch $DIR/$tdir/d2/x2
15394         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15395         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15396         # regular file
15397         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15398         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15399
15400         # softlink
15401         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15402         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15403         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15404
15405         # softlink to wrong file
15406         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15407         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15408         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15409
15410         # hardlink
15411         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15412         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15413         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15414         # fid2path dir/fsname should both work
15415         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15416         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15417
15418         # hardlink count: check that there are 2 links
15419         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15420         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15421
15422         # hardlink indexing: remove the first link
15423         rm $DIR/$tdir/d2/p/q/r/hlink
15424         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15425 }
15426 run_test 162a "path lookup sanity"
15427
15428 test_162b() {
15429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15431
15432         mkdir $DIR/$tdir
15433         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15434                                 error "create striped dir failed"
15435
15436         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15437                                         tail -n 1 | awk '{print $2}')
15438         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15439
15440         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15441         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15442
15443         # regular file
15444         for ((i=0;i<5;i++)); do
15445                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15446                         error "get fid for f$i failed"
15447                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15448
15449                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15450                         error "get fid for d$i failed"
15451                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15452         done
15453
15454         return 0
15455 }
15456 run_test 162b "striped directory path lookup sanity"
15457
15458 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15459 test_162c() {
15460         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15461                 skip "Need MDS version at least 2.7.51"
15462
15463         local lpath=$tdir.local
15464         local rpath=$tdir.remote
15465
15466         test_mkdir $DIR/$lpath
15467         test_mkdir $DIR/$rpath
15468
15469         for ((i = 0; i <= 101; i++)); do
15470                 lpath="$lpath/$i"
15471                 mkdir $DIR/$lpath
15472                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15473                         error "get fid for local directory $DIR/$lpath failed"
15474                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15475
15476                 rpath="$rpath/$i"
15477                 test_mkdir $DIR/$rpath
15478                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15479                         error "get fid for remote directory $DIR/$rpath failed"
15480                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15481         done
15482
15483         return 0
15484 }
15485 run_test 162c "fid2path works with paths 100 or more directories deep"
15486
15487 oalr_event_count() {
15488         local event="${1}"
15489         local trace="${2}"
15490
15491         awk -v name="${FSNAME}-OST0000" \
15492             -v event="${event}" \
15493             '$1 == "TRACE" && $2 == event && $3 == name' \
15494             "${trace}" |
15495         wc -l
15496 }
15497
15498 oalr_expect_event_count() {
15499         local event="${1}"
15500         local trace="${2}"
15501         local expect="${3}"
15502         local count
15503
15504         count=$(oalr_event_count "${event}" "${trace}")
15505         if ((count == expect)); then
15506                 return 0
15507         fi
15508
15509         error_noexit "${event} event count was '${count}', expected ${expect}"
15510         cat "${trace}" >&2
15511         exit 1
15512 }
15513
15514 cleanup_165() {
15515         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15516         stop ost1
15517         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15518 }
15519
15520 setup_165() {
15521         sync # Flush previous IOs so we can count log entries.
15522         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15523         stack_trap cleanup_165 EXIT
15524 }
15525
15526 test_165a() {
15527         local trace="/tmp/${tfile}.trace"
15528         local rc
15529         local count
15530
15531         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15532         setup_165
15533         sleep 5
15534
15535         do_facet ost1 ofd_access_log_reader --list
15536         stop ost1
15537
15538         do_facet ost1 killall -TERM ofd_access_log_reader
15539         wait
15540         rc=$?
15541
15542         if ((rc != 0)); then
15543                 error "ofd_access_log_reader exited with rc = '${rc}'"
15544         fi
15545
15546         # Parse trace file for discovery events:
15547         oalr_expect_event_count alr_log_add "${trace}" 1
15548         oalr_expect_event_count alr_log_eof "${trace}" 1
15549         oalr_expect_event_count alr_log_free "${trace}" 1
15550 }
15551 run_test 165a "ofd access log discovery"
15552
15553 test_165b() {
15554         local trace="/tmp/${tfile}.trace"
15555         local file="${DIR}/${tfile}"
15556         local pfid1
15557         local pfid2
15558         local -a entry
15559         local rc
15560         local count
15561         local size
15562         local flags
15563
15564         setup_165
15565
15566         lfs setstripe -c 1 -i 0 "${file}"
15567         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15568         do_facet ost1 ofd_access_log_reader --list
15569
15570         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15571         sleep 5
15572         do_facet ost1 killall -TERM ofd_access_log_reader
15573         wait
15574         rc=$?
15575
15576         if ((rc != 0)); then
15577                 error "ofd_access_log_reader exited with rc = '${rc}'"
15578         fi
15579
15580         oalr_expect_event_count alr_log_entry "${trace}" 1
15581
15582         pfid1=$($LFS path2fid "${file}")
15583
15584         # 1     2             3   4    5     6   7    8    9     10
15585         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15586         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15587
15588         echo "entry = '${entry[*]}'" >&2
15589
15590         pfid2=${entry[4]}
15591         if [[ "${pfid1}" != "${pfid2}" ]]; then
15592                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15593         fi
15594
15595         size=${entry[8]}
15596         if ((size != 1048576)); then
15597                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15598         fi
15599
15600         flags=${entry[10]}
15601         if [[ "${flags}" != "w" ]]; then
15602                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15603         fi
15604
15605         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15606         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15607         sleep 5
15608         do_facet ost1 killall -TERM ofd_access_log_reader
15609         wait
15610         rc=$?
15611
15612         if ((rc != 0)); then
15613                 error "ofd_access_log_reader exited with rc = '${rc}'"
15614         fi
15615
15616         oalr_expect_event_count alr_log_entry "${trace}" 1
15617
15618         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15619         echo "entry = '${entry[*]}'" >&2
15620
15621         pfid2=${entry[4]}
15622         if [[ "${pfid1}" != "${pfid2}" ]]; then
15623                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15624         fi
15625
15626         size=${entry[8]}
15627         if ((size != 524288)); then
15628                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15629         fi
15630
15631         flags=${entry[10]}
15632         if [[ "${flags}" != "r" ]]; then
15633                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15634         fi
15635 }
15636 run_test 165b "ofd access log entries are produced and consumed"
15637
15638 test_165c() {
15639         local file="${DIR}/${tdir}/${tfile}"
15640         test_mkdir "${DIR}/${tdir}"
15641
15642         setup_165
15643
15644         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15645
15646         # 4096 / 64 = 64. Create twice as many entries.
15647         for ((i = 0; i < 128; i++)); do
15648                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15649         done
15650
15651         sync
15652         do_facet ost1 ofd_access_log_reader --list
15653         unlinkmany  "${file}-%d" 128
15654 }
15655 run_test 165c "full ofd access logs do not block IOs"
15656
15657 oal_peek_entry_count() {
15658         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15659 }
15660
15661 oal_expect_entry_count() {
15662         local entry_count=$(oal_peek_entry_count)
15663         local expect="$1"
15664
15665         if ((entry_count == expect)); then
15666                 return 0
15667         fi
15668
15669         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15670         do_facet ost1 ofd_access_log_reader --list >&2
15671         exit 1
15672 }
15673
15674 test_165d() {
15675         local trace="/tmp/${tfile}.trace"
15676         local file="${DIR}/${tdir}/${tfile}"
15677         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15678         local entry_count
15679         test_mkdir "${DIR}/${tdir}"
15680
15681         setup_165
15682         lfs setstripe -c 1 -i 0 "${file}"
15683
15684         do_facet ost1 lctl set_param "${param}=rw"
15685         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15686         oal_expect_entry_count 1
15687
15688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15689         oal_expect_entry_count 2
15690
15691         do_facet ost1 lctl set_param "${param}=r"
15692         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15693         oal_expect_entry_count 2
15694
15695         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15696         oal_expect_entry_count 3
15697
15698         do_facet ost1 lctl set_param "${param}=w"
15699         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15700         oal_expect_entry_count 4
15701
15702         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15703         oal_expect_entry_count 4
15704
15705         do_facet ost1 lctl set_param "${param}=0"
15706         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15707         oal_expect_entry_count 4
15708
15709         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15710         oal_expect_entry_count 4
15711 }
15712 run_test 165d "ofd_access_log mask works"
15713
15714 test_169() {
15715         # do directio so as not to populate the page cache
15716         log "creating a 10 Mb file"
15717         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15718         log "starting reads"
15719         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15720         log "truncating the file"
15721         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15722         log "killing dd"
15723         kill %+ || true # reads might have finished
15724         echo "wait until dd is finished"
15725         wait
15726         log "removing the temporary file"
15727         rm -rf $DIR/$tfile || error "tmp file removal failed"
15728 }
15729 run_test 169 "parallel read and truncate should not deadlock"
15730
15731 test_170() {
15732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15733
15734         $LCTL clear     # bug 18514
15735         $LCTL debug_daemon start $TMP/${tfile}_log_good
15736         touch $DIR/$tfile
15737         $LCTL debug_daemon stop
15738         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15739                 error "sed failed to read log_good"
15740
15741         $LCTL debug_daemon start $TMP/${tfile}_log_good
15742         rm -rf $DIR/$tfile
15743         $LCTL debug_daemon stop
15744
15745         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15746                error "lctl df log_bad failed"
15747
15748         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15749         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15750
15751         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15752         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15753
15754         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15755                 error "bad_line good_line1 good_line2 are empty"
15756
15757         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15758         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15759         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15760
15761         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15762         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15763         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15764
15765         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15766                 error "bad_line_new good_line_new are empty"
15767
15768         local expected_good=$((good_line1 + good_line2*2))
15769
15770         rm -f $TMP/${tfile}*
15771         # LU-231, short malformed line may not be counted into bad lines
15772         if [ $bad_line -ne $bad_line_new ] &&
15773                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15774                 error "expected $bad_line bad lines, but got $bad_line_new"
15775                 return 1
15776         fi
15777
15778         if [ $expected_good -ne $good_line_new ]; then
15779                 error "expected $expected_good good lines, but got $good_line_new"
15780                 return 2
15781         fi
15782         true
15783 }
15784 run_test 170 "test lctl df to handle corrupted log ====================="
15785
15786 test_171() { # bug20592
15787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15788
15789         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15790         $LCTL set_param fail_loc=0x50e
15791         $LCTL set_param fail_val=3000
15792         multiop_bg_pause $DIR/$tfile O_s || true
15793         local MULTIPID=$!
15794         kill -USR1 $MULTIPID
15795         # cause log dump
15796         sleep 3
15797         wait $MULTIPID
15798         if dmesg | grep "recursive fault"; then
15799                 error "caught a recursive fault"
15800         fi
15801         $LCTL set_param fail_loc=0
15802         true
15803 }
15804 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15805
15806 # it would be good to share it with obdfilter-survey/iokit-libecho code
15807 setup_obdecho_osc () {
15808         local rc=0
15809         local ost_nid=$1
15810         local obdfilter_name=$2
15811         echo "Creating new osc for $obdfilter_name on $ost_nid"
15812         # make sure we can find loopback nid
15813         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15814
15815         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15816                            ${obdfilter_name}_osc_UUID || rc=2; }
15817         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15818                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15819         return $rc
15820 }
15821
15822 cleanup_obdecho_osc () {
15823         local obdfilter_name=$1
15824         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15825         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15826         return 0
15827 }
15828
15829 obdecho_test() {
15830         local OBD=$1
15831         local node=$2
15832         local pages=${3:-64}
15833         local rc=0
15834         local id
15835
15836         local count=10
15837         local obd_size=$(get_obd_size $node $OBD)
15838         local page_size=$(get_page_size $node)
15839         if [[ -n "$obd_size" ]]; then
15840                 local new_count=$((obd_size / (pages * page_size / 1024)))
15841                 [[ $new_count -ge $count ]] || count=$new_count
15842         fi
15843
15844         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15845         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15846                            rc=2; }
15847         if [ $rc -eq 0 ]; then
15848             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15849             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15850         fi
15851         echo "New object id is $id"
15852         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15853                            rc=4; }
15854         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15855                            "test_brw $count w v $pages $id" || rc=4; }
15856         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15857                            rc=4; }
15858         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15859                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15860         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15861                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15862         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15863         return $rc
15864 }
15865
15866 test_180a() {
15867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15868
15869         if ! [ -d /sys/fs/lustre/echo_client ] &&
15870            ! module_loaded obdecho; then
15871                 load_module obdecho/obdecho &&
15872                         stack_trap "rmmod obdecho" EXIT ||
15873                         error "unable to load obdecho on client"
15874         fi
15875
15876         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15877         local host=$($LCTL get_param -n osc.$osc.import |
15878                      awk '/current_connection:/ { print $2 }' )
15879         local target=$($LCTL get_param -n osc.$osc.import |
15880                        awk '/target:/ { print $2 }' )
15881         target=${target%_UUID}
15882
15883         if [ -n "$target" ]; then
15884                 setup_obdecho_osc $host $target &&
15885                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15886                         { error "obdecho setup failed with $?"; return; }
15887
15888                 obdecho_test ${target}_osc client ||
15889                         error "obdecho_test failed on ${target}_osc"
15890         else
15891                 $LCTL get_param osc.$osc.import
15892                 error "there is no osc.$osc.import target"
15893         fi
15894 }
15895 run_test 180a "test obdecho on osc"
15896
15897 test_180b() {
15898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15899         remote_ost_nodsh && skip "remote OST with nodsh"
15900
15901         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15902                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15903                 error "failed to load module obdecho"
15904
15905         local target=$(do_facet ost1 $LCTL dl |
15906                        awk '/obdfilter/ { print $4; exit; }')
15907
15908         if [ -n "$target" ]; then
15909                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15910         else
15911                 do_facet ost1 $LCTL dl
15912                 error "there is no obdfilter target on ost1"
15913         fi
15914 }
15915 run_test 180b "test obdecho directly on obdfilter"
15916
15917 test_180c() { # LU-2598
15918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15919         remote_ost_nodsh && skip "remote OST with nodsh"
15920         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15921                 skip "Need MDS version at least 2.4.0"
15922
15923         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15924                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15925                 error "failed to load module obdecho"
15926
15927         local target=$(do_facet ost1 $LCTL dl |
15928                        awk '/obdfilter/ { print $4; exit; }')
15929
15930         if [ -n "$target" ]; then
15931                 local pages=16384 # 64MB bulk I/O RPC size
15932
15933                 obdecho_test "$target" ost1 "$pages" ||
15934                         error "obdecho_test with pages=$pages failed with $?"
15935         else
15936                 do_facet ost1 $LCTL dl
15937                 error "there is no obdfilter target on ost1"
15938         fi
15939 }
15940 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15941
15942 test_181() { # bug 22177
15943         test_mkdir $DIR/$tdir
15944         # create enough files to index the directory
15945         createmany -o $DIR/$tdir/foobar 4000
15946         # print attributes for debug purpose
15947         lsattr -d .
15948         # open dir
15949         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15950         MULTIPID=$!
15951         # remove the files & current working dir
15952         unlinkmany $DIR/$tdir/foobar 4000
15953         rmdir $DIR/$tdir
15954         kill -USR1 $MULTIPID
15955         wait $MULTIPID
15956         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15957         return 0
15958 }
15959 run_test 181 "Test open-unlinked dir ========================"
15960
15961 test_182() {
15962         local fcount=1000
15963         local tcount=10
15964
15965         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15966
15967         $LCTL set_param mdc.*.rpc_stats=clear
15968
15969         for (( i = 0; i < $tcount; i++ )) ; do
15970                 mkdir $DIR/$tdir/$i
15971         done
15972
15973         for (( i = 0; i < $tcount; i++ )) ; do
15974                 createmany -o $DIR/$tdir/$i/f- $fcount &
15975         done
15976         wait
15977
15978         for (( i = 0; i < $tcount; i++ )) ; do
15979                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15980         done
15981         wait
15982
15983         $LCTL get_param mdc.*.rpc_stats
15984
15985         rm -rf $DIR/$tdir
15986 }
15987 run_test 182 "Test parallel modify metadata operations ================"
15988
15989 test_183() { # LU-2275
15990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15991         remote_mds_nodsh && skip "remote MDS with nodsh"
15992         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15993                 skip "Need MDS version at least 2.3.56"
15994
15995         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15996         echo aaa > $DIR/$tdir/$tfile
15997
15998 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15999         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16000
16001         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16002         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16003
16004         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16005
16006         # Flush negative dentry cache
16007         touch $DIR/$tdir/$tfile
16008
16009         # We are not checking for any leaked references here, they'll
16010         # become evident next time we do cleanup with module unload.
16011         rm -rf $DIR/$tdir
16012 }
16013 run_test 183 "No crash or request leak in case of strange dispositions ========"
16014
16015 # test suite 184 is for LU-2016, LU-2017
16016 test_184a() {
16017         check_swap_layouts_support
16018
16019         dir0=$DIR/$tdir/$testnum
16020         test_mkdir -p -c1 $dir0
16021         ref1=/etc/passwd
16022         ref2=/etc/group
16023         file1=$dir0/f1
16024         file2=$dir0/f2
16025         $LFS setstripe -c1 $file1
16026         cp $ref1 $file1
16027         $LFS setstripe -c2 $file2
16028         cp $ref2 $file2
16029         gen1=$($LFS getstripe -g $file1)
16030         gen2=$($LFS getstripe -g $file2)
16031
16032         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16033         gen=$($LFS getstripe -g $file1)
16034         [[ $gen1 != $gen ]] ||
16035                 "Layout generation on $file1 does not change"
16036         gen=$($LFS getstripe -g $file2)
16037         [[ $gen2 != $gen ]] ||
16038                 "Layout generation on $file2 does not change"
16039
16040         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16041         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16042
16043         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16044 }
16045 run_test 184a "Basic layout swap"
16046
16047 test_184b() {
16048         check_swap_layouts_support
16049
16050         dir0=$DIR/$tdir/$testnum
16051         mkdir -p $dir0 || error "creating dir $dir0"
16052         file1=$dir0/f1
16053         file2=$dir0/f2
16054         file3=$dir0/f3
16055         dir1=$dir0/d1
16056         dir2=$dir0/d2
16057         mkdir $dir1 $dir2
16058         $LFS setstripe -c1 $file1
16059         $LFS setstripe -c2 $file2
16060         $LFS setstripe -c1 $file3
16061         chown $RUNAS_ID $file3
16062         gen1=$($LFS getstripe -g $file1)
16063         gen2=$($LFS getstripe -g $file2)
16064
16065         $LFS swap_layouts $dir1 $dir2 &&
16066                 error "swap of directories layouts should fail"
16067         $LFS swap_layouts $dir1 $file1 &&
16068                 error "swap of directory and file layouts should fail"
16069         $RUNAS $LFS swap_layouts $file1 $file2 &&
16070                 error "swap of file we cannot write should fail"
16071         $LFS swap_layouts $file1 $file3 &&
16072                 error "swap of file with different owner should fail"
16073         /bin/true # to clear error code
16074 }
16075 run_test 184b "Forbidden layout swap (will generate errors)"
16076
16077 test_184c() {
16078         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16079         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16080         check_swap_layouts_support
16081         check_swap_layout_no_dom $DIR
16082
16083         local dir0=$DIR/$tdir/$testnum
16084         mkdir -p $dir0 || error "creating dir $dir0"
16085
16086         local ref1=$dir0/ref1
16087         local ref2=$dir0/ref2
16088         local file1=$dir0/file1
16089         local file2=$dir0/file2
16090         # create a file large enough for the concurrent test
16091         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16092         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16093         echo "ref file size: ref1($(stat -c %s $ref1))," \
16094              "ref2($(stat -c %s $ref2))"
16095
16096         cp $ref2 $file2
16097         dd if=$ref1 of=$file1 bs=16k &
16098         local DD_PID=$!
16099
16100         # Make sure dd starts to copy file, but wait at most 5 seconds
16101         local loops=0
16102         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16103
16104         $LFS swap_layouts $file1 $file2
16105         local rc=$?
16106         wait $DD_PID
16107         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16108         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16109
16110         # how many bytes copied before swapping layout
16111         local copied=$(stat -c %s $file2)
16112         local remaining=$(stat -c %s $ref1)
16113         remaining=$((remaining - copied))
16114         echo "Copied $copied bytes before swapping layout..."
16115
16116         cmp -n $copied $file1 $ref2 | grep differ &&
16117                 error "Content mismatch [0, $copied) of ref2 and file1"
16118         cmp -n $copied $file2 $ref1 ||
16119                 error "Content mismatch [0, $copied) of ref1 and file2"
16120         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16121                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16122
16123         # clean up
16124         rm -f $ref1 $ref2 $file1 $file2
16125 }
16126 run_test 184c "Concurrent write and layout swap"
16127
16128 test_184d() {
16129         check_swap_layouts_support
16130         check_swap_layout_no_dom $DIR
16131         [ -z "$(which getfattr 2>/dev/null)" ] &&
16132                 skip_env "no getfattr command"
16133
16134         local file1=$DIR/$tdir/$tfile-1
16135         local file2=$DIR/$tdir/$tfile-2
16136         local file3=$DIR/$tdir/$tfile-3
16137         local lovea1
16138         local lovea2
16139
16140         mkdir -p $DIR/$tdir
16141         touch $file1 || error "create $file1 failed"
16142         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16143                 error "create $file2 failed"
16144         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16145                 error "create $file3 failed"
16146         lovea1=$(get_layout_param $file1)
16147
16148         $LFS swap_layouts $file2 $file3 ||
16149                 error "swap $file2 $file3 layouts failed"
16150         $LFS swap_layouts $file1 $file2 ||
16151                 error "swap $file1 $file2 layouts failed"
16152
16153         lovea2=$(get_layout_param $file2)
16154         echo "$lovea1"
16155         echo "$lovea2"
16156         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16157
16158         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16159         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16160 }
16161 run_test 184d "allow stripeless layouts swap"
16162
16163 test_184e() {
16164         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16165                 skip "Need MDS version at least 2.6.94"
16166         check_swap_layouts_support
16167         check_swap_layout_no_dom $DIR
16168         [ -z "$(which getfattr 2>/dev/null)" ] &&
16169                 skip_env "no getfattr command"
16170
16171         local file1=$DIR/$tdir/$tfile-1
16172         local file2=$DIR/$tdir/$tfile-2
16173         local file3=$DIR/$tdir/$tfile-3
16174         local lovea
16175
16176         mkdir -p $DIR/$tdir
16177         touch $file1 || error "create $file1 failed"
16178         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16179                 error "create $file2 failed"
16180         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16181                 error "create $file3 failed"
16182
16183         $LFS swap_layouts $file1 $file2 ||
16184                 error "swap $file1 $file2 layouts failed"
16185
16186         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16187         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16188
16189         echo 123 > $file1 || error "Should be able to write into $file1"
16190
16191         $LFS swap_layouts $file1 $file3 ||
16192                 error "swap $file1 $file3 layouts failed"
16193
16194         echo 123 > $file1 || error "Should be able to write into $file1"
16195
16196         rm -rf $file1 $file2 $file3
16197 }
16198 run_test 184e "Recreate layout after stripeless layout swaps"
16199
16200 test_184f() {
16201         # Create a file with name longer than sizeof(struct stat) ==
16202         # 144 to see if we can get chars from the file name to appear
16203         # in the returned striping. Note that 'f' == 0x66.
16204         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16205
16206         mkdir -p $DIR/$tdir
16207         mcreate $DIR/$tdir/$file
16208         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16209                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16210         fi
16211 }
16212 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16213
16214 test_185() { # LU-2441
16215         # LU-3553 - no volatile file support in old servers
16216         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16217                 skip "Need MDS version at least 2.3.60"
16218
16219         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16220         touch $DIR/$tdir/spoo
16221         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16222         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16223                 error "cannot create/write a volatile file"
16224         [ "$FILESET" == "" ] &&
16225         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16226                 error "FID is still valid after close"
16227
16228         multiop_bg_pause $DIR/$tdir vVw4096_c
16229         local multi_pid=$!
16230
16231         local OLD_IFS=$IFS
16232         IFS=":"
16233         local fidv=($fid)
16234         IFS=$OLD_IFS
16235         # assume that the next FID for this client is sequential, since stdout
16236         # is unfortunately eaten by multiop_bg_pause
16237         local n=$((${fidv[1]} + 1))
16238         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16239         if [ "$FILESET" == "" ]; then
16240                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16241                         error "FID is missing before close"
16242         fi
16243         kill -USR1 $multi_pid
16244         # 1 second delay, so if mtime change we will see it
16245         sleep 1
16246         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16247         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16248 }
16249 run_test 185 "Volatile file support"
16250
16251 function create_check_volatile() {
16252         local idx=$1
16253         local tgt
16254
16255         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16256         local PID=$!
16257         sleep 1
16258         local FID=$(cat /tmp/${tfile}.fid)
16259         [ "$FID" == "" ] && error "can't get FID for volatile"
16260         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16261         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16262         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16263         kill -USR1 $PID
16264         wait
16265         sleep 1
16266         cancel_lru_locks mdc # flush opencache
16267         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16268         return 0
16269 }
16270
16271 test_185a(){
16272         # LU-12516 - volatile creation via .lustre
16273         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16274                 skip "Need MDS version at least 2.3.55"
16275
16276         create_check_volatile 0
16277         [ $MDSCOUNT -lt 2 ] && return 0
16278
16279         # DNE case
16280         create_check_volatile 1
16281
16282         return 0
16283 }
16284 run_test 185a "Volatile file creation in .lustre/fid/"
16285
16286 test_187a() {
16287         remote_mds_nodsh && skip "remote MDS with nodsh"
16288         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16289                 skip "Need MDS version at least 2.3.0"
16290
16291         local dir0=$DIR/$tdir/$testnum
16292         mkdir -p $dir0 || error "creating dir $dir0"
16293
16294         local file=$dir0/file1
16295         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16296         local dv1=$($LFS data_version $file)
16297         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16298         local dv2=$($LFS data_version $file)
16299         [[ $dv1 != $dv2 ]] ||
16300                 error "data version did not change on write $dv1 == $dv2"
16301
16302         # clean up
16303         rm -f $file1
16304 }
16305 run_test 187a "Test data version change"
16306
16307 test_187b() {
16308         remote_mds_nodsh && skip "remote MDS with nodsh"
16309         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16310                 skip "Need MDS version at least 2.3.0"
16311
16312         local dir0=$DIR/$tdir/$testnum
16313         mkdir -p $dir0 || error "creating dir $dir0"
16314
16315         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16316         [[ ${DV[0]} != ${DV[1]} ]] ||
16317                 error "data version did not change on write"\
16318                       " ${DV[0]} == ${DV[1]}"
16319
16320         # clean up
16321         rm -f $file1
16322 }
16323 run_test 187b "Test data version change on volatile file"
16324
16325 test_200() {
16326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16327         remote_mgs_nodsh && skip "remote MGS with nodsh"
16328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16329
16330         local POOL=${POOL:-cea1}
16331         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16332         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16333         # Pool OST targets
16334         local first_ost=0
16335         local last_ost=$(($OSTCOUNT - 1))
16336         local ost_step=2
16337         local ost_list=$(seq $first_ost $ost_step $last_ost)
16338         local ost_range="$first_ost $last_ost $ost_step"
16339         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16340         local file_dir=$POOL_ROOT/file_tst
16341         local subdir=$test_path/subdir
16342         local rc=0
16343
16344         while : ; do
16345                 # former test_200a test_200b
16346                 pool_add $POOL                          || { rc=$? ; break; }
16347                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16348                 # former test_200c test_200d
16349                 mkdir -p $test_path
16350                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16351                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16352                 mkdir -p $subdir
16353                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16354                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16355                                                         || { rc=$? ; break; }
16356                 # former test_200e test_200f
16357                 local files=$((OSTCOUNT*3))
16358                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16359                                                         || { rc=$? ; break; }
16360                 pool_create_files $POOL $file_dir $files "$ost_list" \
16361                                                         || { rc=$? ; break; }
16362                 # former test_200g test_200h
16363                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16364                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16365
16366                 # former test_201a test_201b test_201c
16367                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16368
16369                 local f=$test_path/$tfile
16370                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16371                 pool_remove $POOL $f                    || { rc=$? ; break; }
16372                 break
16373         done
16374
16375         destroy_test_pools
16376
16377         return $rc
16378 }
16379 run_test 200 "OST pools"
16380
16381 # usage: default_attr <count | size | offset>
16382 default_attr() {
16383         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16384 }
16385
16386 # usage: check_default_stripe_attr
16387 check_default_stripe_attr() {
16388         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16389         case $1 in
16390         --stripe-count|-c)
16391                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16392         --stripe-size|-S)
16393                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16394         --stripe-index|-i)
16395                 EXPECTED=-1;;
16396         *)
16397                 error "unknown getstripe attr '$1'"
16398         esac
16399
16400         [ $ACTUAL == $EXPECTED ] ||
16401                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16402 }
16403
16404 test_204a() {
16405         test_mkdir $DIR/$tdir
16406         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16407
16408         check_default_stripe_attr --stripe-count
16409         check_default_stripe_attr --stripe-size
16410         check_default_stripe_attr --stripe-index
16411 }
16412 run_test 204a "Print default stripe attributes"
16413
16414 test_204b() {
16415         test_mkdir $DIR/$tdir
16416         $LFS setstripe --stripe-count 1 $DIR/$tdir
16417
16418         check_default_stripe_attr --stripe-size
16419         check_default_stripe_attr --stripe-index
16420 }
16421 run_test 204b "Print default stripe size and offset"
16422
16423 test_204c() {
16424         test_mkdir $DIR/$tdir
16425         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16426
16427         check_default_stripe_attr --stripe-count
16428         check_default_stripe_attr --stripe-index
16429 }
16430 run_test 204c "Print default stripe count and offset"
16431
16432 test_204d() {
16433         test_mkdir $DIR/$tdir
16434         $LFS setstripe --stripe-index 0 $DIR/$tdir
16435
16436         check_default_stripe_attr --stripe-count
16437         check_default_stripe_attr --stripe-size
16438 }
16439 run_test 204d "Print default stripe count and size"
16440
16441 test_204e() {
16442         test_mkdir $DIR/$tdir
16443         $LFS setstripe -d $DIR/$tdir
16444
16445         check_default_stripe_attr --stripe-count --raw
16446         check_default_stripe_attr --stripe-size --raw
16447         check_default_stripe_attr --stripe-index --raw
16448 }
16449 run_test 204e "Print raw stripe attributes"
16450
16451 test_204f() {
16452         test_mkdir $DIR/$tdir
16453         $LFS setstripe --stripe-count 1 $DIR/$tdir
16454
16455         check_default_stripe_attr --stripe-size --raw
16456         check_default_stripe_attr --stripe-index --raw
16457 }
16458 run_test 204f "Print raw stripe size and offset"
16459
16460 test_204g() {
16461         test_mkdir $DIR/$tdir
16462         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16463
16464         check_default_stripe_attr --stripe-count --raw
16465         check_default_stripe_attr --stripe-index --raw
16466 }
16467 run_test 204g "Print raw stripe count and offset"
16468
16469 test_204h() {
16470         test_mkdir $DIR/$tdir
16471         $LFS setstripe --stripe-index 0 $DIR/$tdir
16472
16473         check_default_stripe_attr --stripe-count --raw
16474         check_default_stripe_attr --stripe-size --raw
16475 }
16476 run_test 204h "Print raw stripe count and size"
16477
16478 # Figure out which job scheduler is being used, if any,
16479 # or use a fake one
16480 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16481         JOBENV=SLURM_JOB_ID
16482 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16483         JOBENV=LSB_JOBID
16484 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16485         JOBENV=PBS_JOBID
16486 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16487         JOBENV=LOADL_STEP_ID
16488 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16489         JOBENV=JOB_ID
16490 else
16491         $LCTL list_param jobid_name > /dev/null 2>&1
16492         if [ $? -eq 0 ]; then
16493                 JOBENV=nodelocal
16494         else
16495                 JOBENV=FAKE_JOBID
16496         fi
16497 fi
16498 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16499
16500 verify_jobstats() {
16501         local cmd=($1)
16502         shift
16503         local facets="$@"
16504
16505 # we don't really need to clear the stats for this test to work, since each
16506 # command has a unique jobid, but it makes debugging easier if needed.
16507 #       for facet in $facets; do
16508 #               local dev=$(convert_facet2label $facet)
16509 #               # clear old jobstats
16510 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16511 #       done
16512
16513         # use a new JobID for each test, or we might see an old one
16514         [ "$JOBENV" = "FAKE_JOBID" ] &&
16515                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16516
16517         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16518
16519         [ "$JOBENV" = "nodelocal" ] && {
16520                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16521                 $LCTL set_param jobid_name=$FAKE_JOBID
16522                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16523         }
16524
16525         log "Test: ${cmd[*]}"
16526         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16527
16528         if [ $JOBENV = "FAKE_JOBID" ]; then
16529                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16530         else
16531                 ${cmd[*]}
16532         fi
16533
16534         # all files are created on OST0000
16535         for facet in $facets; do
16536                 local stats="*.$(convert_facet2label $facet).job_stats"
16537
16538                 # strip out libtool wrappers for in-tree executables
16539                 if [ $(do_facet $facet lctl get_param $stats |
16540                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16541                         do_facet $facet lctl get_param $stats
16542                         error "No jobstats for $JOBVAL found on $facet::$stats"
16543                 fi
16544         done
16545 }
16546
16547 jobstats_set() {
16548         local new_jobenv=$1
16549
16550         set_persistent_param_and_check client "jobid_var" \
16551                 "$FSNAME.sys.jobid_var" $new_jobenv
16552 }
16553
16554 test_205a() { # Job stats
16555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16556         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16557                 skip "Need MDS version with at least 2.7.1"
16558         remote_mgs_nodsh && skip "remote MGS with nodsh"
16559         remote_mds_nodsh && skip "remote MDS with nodsh"
16560         remote_ost_nodsh && skip "remote OST with nodsh"
16561         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16562                 skip "Server doesn't support jobstats"
16563         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16564
16565         local old_jobenv=$($LCTL get_param -n jobid_var)
16566         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16567
16568         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16569                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16570         else
16571                 stack_trap "do_facet mgs $PERM_CMD \
16572                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16573         fi
16574         changelog_register
16575
16576         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16577                                 mdt.*.job_cleanup_interval | head -n 1)
16578         local new_interval=5
16579         do_facet $SINGLEMDS \
16580                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16581         stack_trap "do_facet $SINGLEMDS \
16582                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16583         local start=$SECONDS
16584
16585         local cmd
16586         # mkdir
16587         cmd="mkdir $DIR/$tdir"
16588         verify_jobstats "$cmd" "$SINGLEMDS"
16589         # rmdir
16590         cmd="rmdir $DIR/$tdir"
16591         verify_jobstats "$cmd" "$SINGLEMDS"
16592         # mkdir on secondary MDT
16593         if [ $MDSCOUNT -gt 1 ]; then
16594                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16595                 verify_jobstats "$cmd" "mds2"
16596         fi
16597         # mknod
16598         cmd="mknod $DIR/$tfile c 1 3"
16599         verify_jobstats "$cmd" "$SINGLEMDS"
16600         # unlink
16601         cmd="rm -f $DIR/$tfile"
16602         verify_jobstats "$cmd" "$SINGLEMDS"
16603         # create all files on OST0000 so verify_jobstats can find OST stats
16604         # open & close
16605         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16606         verify_jobstats "$cmd" "$SINGLEMDS"
16607         # setattr
16608         cmd="touch $DIR/$tfile"
16609         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16610         # write
16611         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16612         verify_jobstats "$cmd" "ost1"
16613         # read
16614         cancel_lru_locks osc
16615         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16616         verify_jobstats "$cmd" "ost1"
16617         # truncate
16618         cmd="$TRUNCATE $DIR/$tfile 0"
16619         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16620         # rename
16621         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16622         verify_jobstats "$cmd" "$SINGLEMDS"
16623         # jobstats expiry - sleep until old stats should be expired
16624         local left=$((new_interval + 5 - (SECONDS - start)))
16625         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16626                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16627                         "0" $left
16628         cmd="mkdir $DIR/$tdir.expire"
16629         verify_jobstats "$cmd" "$SINGLEMDS"
16630         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16631             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16632
16633         # Ensure that jobid are present in changelog (if supported by MDS)
16634         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16635                 changelog_dump | tail -10
16636                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16637                 [ $jobids -eq 9 ] ||
16638                         error "Wrong changelog jobid count $jobids != 9"
16639
16640                 # LU-5862
16641                 JOBENV="disable"
16642                 jobstats_set $JOBENV
16643                 touch $DIR/$tfile
16644                 changelog_dump | grep $tfile
16645                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16646                 [ $jobids -eq 0 ] ||
16647                         error "Unexpected jobids when jobid_var=$JOBENV"
16648         fi
16649
16650         # test '%j' access to environment variable - if supported
16651         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16652                 JOBENV="JOBCOMPLEX"
16653                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16654
16655                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16656         fi
16657
16658         # test '%j' access to per-session jobid - if supported
16659         if lctl list_param jobid_this_session > /dev/null 2>&1
16660         then
16661                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16662                 lctl set_param jobid_this_session=$USER
16663
16664                 JOBENV="JOBCOMPLEX"
16665                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16666
16667                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16668         fi
16669 }
16670 run_test 205a "Verify job stats"
16671
16672 # LU-13117, LU-13597
16673 test_205b() {
16674         job_stats="mdt.*.job_stats"
16675         $LCTL set_param $job_stats=clear
16676         # Setting jobid_var to USER might not be supported
16677         $LCTL set_param jobid_var=USER || true
16678         $LCTL set_param jobid_name="%e.%u"
16679         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16680         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16681                 grep "job_id:.*foolish" &&
16682                         error "Unexpected jobid found"
16683         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16684                 grep "open:.*min.*max.*sum" ||
16685                         error "wrong job_stats format found"
16686 }
16687 run_test 205b "Verify job stats jobid and output format"
16688
16689 # LU-13733
16690 test_205c() {
16691         $LCTL set_param llite.*.stats=0
16692         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16693         $LCTL get_param llite.*.stats
16694         $LCTL get_param llite.*.stats | grep \
16695                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16696                         error "wrong client stats format found"
16697 }
16698 run_test 205c "Verify client stats format"
16699
16700 # LU-1480, LU-1773 and LU-1657
16701 test_206() {
16702         mkdir -p $DIR/$tdir
16703         $LFS setstripe -c -1 $DIR/$tdir
16704 #define OBD_FAIL_LOV_INIT 0x1403
16705         $LCTL set_param fail_loc=0xa0001403
16706         $LCTL set_param fail_val=1
16707         touch $DIR/$tdir/$tfile || true
16708 }
16709 run_test 206 "fail lov_init_raid0() doesn't lbug"
16710
16711 test_207a() {
16712         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16713         local fsz=`stat -c %s $DIR/$tfile`
16714         cancel_lru_locks mdc
16715
16716         # do not return layout in getattr intent
16717 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16718         $LCTL set_param fail_loc=0x170
16719         local sz=`stat -c %s $DIR/$tfile`
16720
16721         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16722
16723         rm -rf $DIR/$tfile
16724 }
16725 run_test 207a "can refresh layout at glimpse"
16726
16727 test_207b() {
16728         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16729         local cksum=`md5sum $DIR/$tfile`
16730         local fsz=`stat -c %s $DIR/$tfile`
16731         cancel_lru_locks mdc
16732         cancel_lru_locks osc
16733
16734         # do not return layout in getattr intent
16735 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16736         $LCTL set_param fail_loc=0x171
16737
16738         # it will refresh layout after the file is opened but before read issues
16739         echo checksum is "$cksum"
16740         echo "$cksum" |md5sum -c --quiet || error "file differs"
16741
16742         rm -rf $DIR/$tfile
16743 }
16744 run_test 207b "can refresh layout at open"
16745
16746 test_208() {
16747         # FIXME: in this test suite, only RD lease is used. This is okay
16748         # for now as only exclusive open is supported. After generic lease
16749         # is done, this test suite should be revised. - Jinshan
16750
16751         remote_mds_nodsh && skip "remote MDS with nodsh"
16752         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16753                 skip "Need MDS version at least 2.4.52"
16754
16755         echo "==== test 1: verify get lease work"
16756         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16757
16758         echo "==== test 2: verify lease can be broken by upcoming open"
16759         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16760         local PID=$!
16761         sleep 1
16762
16763         $MULTIOP $DIR/$tfile oO_RDONLY:c
16764         kill -USR1 $PID && wait $PID || error "break lease error"
16765
16766         echo "==== test 3: verify lease can't be granted if an open already exists"
16767         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16768         local PID=$!
16769         sleep 1
16770
16771         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16772         kill -USR1 $PID && wait $PID || error "open file error"
16773
16774         echo "==== test 4: lease can sustain over recovery"
16775         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16776         PID=$!
16777         sleep 1
16778
16779         fail mds1
16780
16781         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16782
16783         echo "==== test 5: lease broken can't be regained by replay"
16784         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16785         PID=$!
16786         sleep 1
16787
16788         # open file to break lease and then recovery
16789         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16790         fail mds1
16791
16792         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16793
16794         rm -f $DIR/$tfile
16795 }
16796 run_test 208 "Exclusive open"
16797
16798 test_209() {
16799         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16800                 skip_env "must have disp_stripe"
16801
16802         touch $DIR/$tfile
16803         sync; sleep 5; sync;
16804
16805         echo 3 > /proc/sys/vm/drop_caches
16806         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16807                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16808         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16809
16810         # open/close 500 times
16811         for i in $(seq 500); do
16812                 cat $DIR/$tfile
16813         done
16814
16815         echo 3 > /proc/sys/vm/drop_caches
16816         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16817                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16818         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16819
16820         echo "before: $req_before, after: $req_after"
16821         [ $((req_after - req_before)) -ge 300 ] &&
16822                 error "open/close requests are not freed"
16823         return 0
16824 }
16825 run_test 209 "read-only open/close requests should be freed promptly"
16826
16827 test_210() {
16828         local pid
16829
16830         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16831         pid=$!
16832         sleep 1
16833
16834         $LFS getstripe $DIR/$tfile
16835         kill -USR1 $pid
16836         wait $pid || error "multiop failed"
16837
16838         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16839         pid=$!
16840         sleep 1
16841
16842         $LFS getstripe $DIR/$tfile
16843         kill -USR1 $pid
16844         wait $pid || error "multiop failed"
16845 }
16846 run_test 210 "lfs getstripe does not break leases"
16847
16848 test_212() {
16849         size=`date +%s`
16850         size=$((size % 8192 + 1))
16851         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16852         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16853         rm -f $DIR/f212 $DIR/f212.xyz
16854 }
16855 run_test 212 "Sendfile test ============================================"
16856
16857 test_213() {
16858         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16859         cancel_lru_locks osc
16860         lctl set_param fail_loc=0x8000040f
16861         # generate a read lock
16862         cat $DIR/$tfile > /dev/null
16863         # write to the file, it will try to cancel the above read lock.
16864         cat /etc/hosts >> $DIR/$tfile
16865 }
16866 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16867
16868 test_214() { # for bug 20133
16869         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16870         for (( i=0; i < 340; i++ )) ; do
16871                 touch $DIR/$tdir/d214c/a$i
16872         done
16873
16874         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16875         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16876         ls $DIR/d214c || error "ls $DIR/d214c failed"
16877         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16878         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16879 }
16880 run_test 214 "hash-indexed directory test - bug 20133"
16881
16882 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16883 create_lnet_proc_files() {
16884         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16885 }
16886
16887 # counterpart of create_lnet_proc_files
16888 remove_lnet_proc_files() {
16889         rm -f $TMP/lnet_$1.sys
16890 }
16891
16892 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16893 # 3rd arg as regexp for body
16894 check_lnet_proc_stats() {
16895         local l=$(cat "$TMP/lnet_$1" |wc -l)
16896         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16897
16898         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16899 }
16900
16901 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16902 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16903 # optional and can be regexp for 2nd line (lnet.routes case)
16904 check_lnet_proc_entry() {
16905         local blp=2          # blp stands for 'position of 1st line of body'
16906         [ -z "$5" ] || blp=3 # lnet.routes case
16907
16908         local l=$(cat "$TMP/lnet_$1" |wc -l)
16909         # subtracting one from $blp because the body can be empty
16910         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16911
16912         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16913                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16914
16915         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16916                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16917
16918         # bail out if any unexpected line happened
16919         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16920         [ "$?" != 0 ] || error "$2 misformatted"
16921 }
16922
16923 test_215() { # for bugs 18102, 21079, 21517
16924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16925
16926         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16927         local P='[1-9][0-9]*'           # positive numeric
16928         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16929         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16930         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16931         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16932
16933         local L1 # regexp for 1st line
16934         local L2 # regexp for 2nd line (optional)
16935         local BR # regexp for the rest (body)
16936
16937         # lnet.stats should look as 11 space-separated non-negative numerics
16938         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16939         create_lnet_proc_files "stats"
16940         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16941         remove_lnet_proc_files "stats"
16942
16943         # lnet.routes should look like this:
16944         # Routing disabled/enabled
16945         # net hops priority state router
16946         # where net is a string like tcp0, hops > 0, priority >= 0,
16947         # state is up/down,
16948         # router is a string like 192.168.1.1@tcp2
16949         L1="^Routing (disabled|enabled)$"
16950         L2="^net +hops +priority +state +router$"
16951         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16952         create_lnet_proc_files "routes"
16953         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16954         remove_lnet_proc_files "routes"
16955
16956         # lnet.routers should look like this:
16957         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16958         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16959         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16960         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16961         L1="^ref +rtr_ref +alive +router$"
16962         BR="^$P +$P +(up|down) +$NID$"
16963         create_lnet_proc_files "routers"
16964         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16965         remove_lnet_proc_files "routers"
16966
16967         # lnet.peers should look like this:
16968         # nid refs state last max rtr min tx min queue
16969         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16970         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16971         # numeric (0 or >0 or <0), queue >= 0.
16972         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16973         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16974         create_lnet_proc_files "peers"
16975         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16976         remove_lnet_proc_files "peers"
16977
16978         # lnet.buffers  should look like this:
16979         # pages count credits min
16980         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16981         L1="^pages +count +credits +min$"
16982         BR="^ +$N +$N +$I +$I$"
16983         create_lnet_proc_files "buffers"
16984         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16985         remove_lnet_proc_files "buffers"
16986
16987         # lnet.nis should look like this:
16988         # nid status alive refs peer rtr max tx min
16989         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16990         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16991         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16992         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16993         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16994         create_lnet_proc_files "nis"
16995         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16996         remove_lnet_proc_files "nis"
16997
16998         # can we successfully write to lnet.stats?
16999         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17000 }
17001 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17002
17003 test_216() { # bug 20317
17004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17005         remote_ost_nodsh && skip "remote OST with nodsh"
17006
17007         local node
17008         local facets=$(get_facets OST)
17009         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17010
17011         save_lustre_params client "osc.*.contention_seconds" > $p
17012         save_lustre_params $facets \
17013                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17014         save_lustre_params $facets \
17015                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17016         save_lustre_params $facets \
17017                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17018         clear_stats osc.*.osc_stats
17019
17020         # agressive lockless i/o settings
17021         do_nodes $(comma_list $(osts_nodes)) \
17022                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17023                         ldlm.namespaces.filter-*.contended_locks=0 \
17024                         ldlm.namespaces.filter-*.contention_seconds=60"
17025         lctl set_param -n osc.*.contention_seconds=60
17026
17027         $DIRECTIO write $DIR/$tfile 0 10 4096
17028         $CHECKSTAT -s 40960 $DIR/$tfile
17029
17030         # disable lockless i/o
17031         do_nodes $(comma_list $(osts_nodes)) \
17032                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17033                         ldlm.namespaces.filter-*.contended_locks=32 \
17034                         ldlm.namespaces.filter-*.contention_seconds=0"
17035         lctl set_param -n osc.*.contention_seconds=0
17036         clear_stats osc.*.osc_stats
17037
17038         dd if=/dev/zero of=$DIR/$tfile count=0
17039         $CHECKSTAT -s 0 $DIR/$tfile
17040
17041         restore_lustre_params <$p
17042         rm -f $p
17043         rm $DIR/$tfile
17044 }
17045 run_test 216 "check lockless direct write updates file size and kms correctly"
17046
17047 test_217() { # bug 22430
17048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17049
17050         local node
17051         local nid
17052
17053         for node in $(nodes_list); do
17054                 nid=$(host_nids_address $node $NETTYPE)
17055                 if [[ $nid = *-* ]] ; then
17056                         echo "lctl ping $(h2nettype $nid)"
17057                         lctl ping $(h2nettype $nid)
17058                 else
17059                         echo "skipping $node (no hyphen detected)"
17060                 fi
17061         done
17062 }
17063 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17064
17065 test_218() {
17066        # do directio so as not to populate the page cache
17067        log "creating a 10 Mb file"
17068        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17069        log "starting reads"
17070        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17071        log "truncating the file"
17072        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17073        log "killing dd"
17074        kill %+ || true # reads might have finished
17075        echo "wait until dd is finished"
17076        wait
17077        log "removing the temporary file"
17078        rm -rf $DIR/$tfile || error "tmp file removal failed"
17079 }
17080 run_test 218 "parallel read and truncate should not deadlock"
17081
17082 test_219() {
17083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17084
17085         # write one partial page
17086         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17087         # set no grant so vvp_io_commit_write will do sync write
17088         $LCTL set_param fail_loc=0x411
17089         # write a full page at the end of file
17090         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17091
17092         $LCTL set_param fail_loc=0
17093         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17094         $LCTL set_param fail_loc=0x411
17095         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17096
17097         # LU-4201
17098         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17099         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17100 }
17101 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17102
17103 test_220() { #LU-325
17104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17105         remote_ost_nodsh && skip "remote OST with nodsh"
17106         remote_mds_nodsh && skip "remote MDS with nodsh"
17107         remote_mgs_nodsh && skip "remote MGS with nodsh"
17108
17109         local OSTIDX=0
17110
17111         # create on MDT0000 so the last_id and next_id are correct
17112         mkdir $DIR/$tdir
17113         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17114         OST=${OST%_UUID}
17115
17116         # on the mdt's osc
17117         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17118         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17119                         osp.$mdtosc_proc1.prealloc_last_id)
17120         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17121                         osp.$mdtosc_proc1.prealloc_next_id)
17122
17123         $LFS df -i
17124
17125         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17126         #define OBD_FAIL_OST_ENOINO              0x229
17127         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17128         create_pool $FSNAME.$TESTNAME || return 1
17129         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17130
17131         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17132
17133         MDSOBJS=$((last_id - next_id))
17134         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17135
17136         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17137         echo "OST still has $count kbytes free"
17138
17139         echo "create $MDSOBJS files @next_id..."
17140         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17141
17142         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17143                         osp.$mdtosc_proc1.prealloc_last_id)
17144         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17145                         osp.$mdtosc_proc1.prealloc_next_id)
17146
17147         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17148         $LFS df -i
17149
17150         echo "cleanup..."
17151
17152         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17153         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17154
17155         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17156                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17157         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17158                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17159         echo "unlink $MDSOBJS files @$next_id..."
17160         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17161 }
17162 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17163
17164 test_221() {
17165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17166
17167         dd if=`which date` of=$MOUNT/date oflag=sync
17168         chmod +x $MOUNT/date
17169
17170         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17171         $LCTL set_param fail_loc=0x80001401
17172
17173         $MOUNT/date > /dev/null
17174         rm -f $MOUNT/date
17175 }
17176 run_test 221 "make sure fault and truncate race to not cause OOM"
17177
17178 test_222a () {
17179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17180
17181         rm -rf $DIR/$tdir
17182         test_mkdir $DIR/$tdir
17183         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17184         createmany -o $DIR/$tdir/$tfile 10
17185         cancel_lru_locks mdc
17186         cancel_lru_locks osc
17187         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17188         $LCTL set_param fail_loc=0x31a
17189         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17190         $LCTL set_param fail_loc=0
17191         rm -r $DIR/$tdir
17192 }
17193 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17194
17195 test_222b () {
17196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17197
17198         rm -rf $DIR/$tdir
17199         test_mkdir $DIR/$tdir
17200         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17201         createmany -o $DIR/$tdir/$tfile 10
17202         cancel_lru_locks mdc
17203         cancel_lru_locks osc
17204         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17205         $LCTL set_param fail_loc=0x31a
17206         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17207         $LCTL set_param fail_loc=0
17208 }
17209 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17210
17211 test_223 () {
17212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17213
17214         rm -rf $DIR/$tdir
17215         test_mkdir $DIR/$tdir
17216         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17217         createmany -o $DIR/$tdir/$tfile 10
17218         cancel_lru_locks mdc
17219         cancel_lru_locks osc
17220         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17221         $LCTL set_param fail_loc=0x31b
17222         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17223         $LCTL set_param fail_loc=0
17224         rm -r $DIR/$tdir
17225 }
17226 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17227
17228 test_224a() { # LU-1039, MRP-303
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230
17231         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17232         $LCTL set_param fail_loc=0x508
17233         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17234         $LCTL set_param fail_loc=0
17235         df $DIR
17236 }
17237 run_test 224a "Don't panic on bulk IO failure"
17238
17239 test_224b() { # LU-1039, MRP-303
17240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17241
17242         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17243         cancel_lru_locks osc
17244         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17245         $LCTL set_param fail_loc=0x515
17246         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17247         $LCTL set_param fail_loc=0
17248         df $DIR
17249 }
17250 run_test 224b "Don't panic on bulk IO failure"
17251
17252 test_224c() { # LU-6441
17253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17254         remote_mds_nodsh && skip "remote MDS with nodsh"
17255
17256         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17257         save_writethrough $p
17258         set_cache writethrough on
17259
17260         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17261         local at_max=$($LCTL get_param -n at_max)
17262         local timeout=$($LCTL get_param -n timeout)
17263         local test_at="at_max"
17264         local param_at="$FSNAME.sys.at_max"
17265         local test_timeout="timeout"
17266         local param_timeout="$FSNAME.sys.timeout"
17267
17268         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17269
17270         set_persistent_param_and_check client "$test_at" "$param_at" 0
17271         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17272
17273         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17274         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17275         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17276         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17277         sync
17278         do_facet ost1 "$LCTL set_param fail_loc=0"
17279
17280         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17281         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17282                 $timeout
17283
17284         $LCTL set_param -n $pages_per_rpc
17285         restore_lustre_params < $p
17286         rm -f $p
17287 }
17288 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17289
17290 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17291 test_225a () {
17292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17293         if [ -z ${MDSSURVEY} ]; then
17294                 skip_env "mds-survey not found"
17295         fi
17296         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17297                 skip "Need MDS version at least 2.2.51"
17298
17299         local mds=$(facet_host $SINGLEMDS)
17300         local target=$(do_nodes $mds 'lctl dl' |
17301                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17302
17303         local cmd1="file_count=1000 thrhi=4"
17304         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17305         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17306         local cmd="$cmd1 $cmd2 $cmd3"
17307
17308         rm -f ${TMP}/mds_survey*
17309         echo + $cmd
17310         eval $cmd || error "mds-survey with zero-stripe failed"
17311         cat ${TMP}/mds_survey*
17312         rm -f ${TMP}/mds_survey*
17313 }
17314 run_test 225a "Metadata survey sanity with zero-stripe"
17315
17316 test_225b () {
17317         if [ -z ${MDSSURVEY} ]; then
17318                 skip_env "mds-survey not found"
17319         fi
17320         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17321                 skip "Need MDS version at least 2.2.51"
17322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17323         remote_mds_nodsh && skip "remote MDS with nodsh"
17324         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17325                 skip_env "Need to mount OST to test"
17326         fi
17327
17328         local mds=$(facet_host $SINGLEMDS)
17329         local target=$(do_nodes $mds 'lctl dl' |
17330                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17331
17332         local cmd1="file_count=1000 thrhi=4"
17333         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17334         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17335         local cmd="$cmd1 $cmd2 $cmd3"
17336
17337         rm -f ${TMP}/mds_survey*
17338         echo + $cmd
17339         eval $cmd || error "mds-survey with stripe_count failed"
17340         cat ${TMP}/mds_survey*
17341         rm -f ${TMP}/mds_survey*
17342 }
17343 run_test 225b "Metadata survey sanity with stripe_count = 1"
17344
17345 mcreate_path2fid () {
17346         local mode=$1
17347         local major=$2
17348         local minor=$3
17349         local name=$4
17350         local desc=$5
17351         local path=$DIR/$tdir/$name
17352         local fid
17353         local rc
17354         local fid_path
17355
17356         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17357                 error "cannot create $desc"
17358
17359         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17360         rc=$?
17361         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17362
17363         fid_path=$($LFS fid2path $MOUNT $fid)
17364         rc=$?
17365         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17366
17367         [ "$path" == "$fid_path" ] ||
17368                 error "fid2path returned $fid_path, expected $path"
17369
17370         echo "pass with $path and $fid"
17371 }
17372
17373 test_226a () {
17374         rm -rf $DIR/$tdir
17375         mkdir -p $DIR/$tdir
17376
17377         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17378         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17379         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17380         mcreate_path2fid 0040666 0 0 dir "directory"
17381         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17382         mcreate_path2fid 0100666 0 0 file "regular file"
17383         mcreate_path2fid 0120666 0 0 link "symbolic link"
17384         mcreate_path2fid 0140666 0 0 sock "socket"
17385 }
17386 run_test 226a "call path2fid and fid2path on files of all type"
17387
17388 test_226b () {
17389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17390
17391         local MDTIDX=1
17392
17393         rm -rf $DIR/$tdir
17394         mkdir -p $DIR/$tdir
17395         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17396                 error "create remote directory failed"
17397         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17398         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17399                                 "character special file (null)"
17400         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17401                                 "character special file (no device)"
17402         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17403         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17404                                 "block special file (loop)"
17405         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17406         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17407         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17408 }
17409 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17410
17411 test_226c () {
17412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17413         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17414                 skip "Need MDS version at least 2.13.55"
17415
17416         local submnt=/mnt/submnt
17417         local srcfile=/etc/passwd
17418         local dstfile=$submnt/passwd
17419         local path
17420         local fid
17421
17422         rm -rf $DIR/$tdir
17423         rm -rf $submnt
17424         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17425                 error "create remote directory failed"
17426         mkdir -p $submnt || error "create $submnt failed"
17427         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17428                 error "mount $submnt failed"
17429         stack_trap "umount $submnt" EXIT
17430
17431         cp $srcfile $dstfile
17432         fid=$($LFS path2fid $dstfile)
17433         path=$($LFS fid2path $submnt "$fid")
17434         [ "$path" = "$dstfile" ] ||
17435                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17436 }
17437 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17438
17439 # LU-1299 Executing or running ldd on a truncated executable does not
17440 # cause an out-of-memory condition.
17441 test_227() {
17442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17443         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17444
17445         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17446         chmod +x $MOUNT/date
17447
17448         $MOUNT/date > /dev/null
17449         ldd $MOUNT/date > /dev/null
17450         rm -f $MOUNT/date
17451 }
17452 run_test 227 "running truncated executable does not cause OOM"
17453
17454 # LU-1512 try to reuse idle OI blocks
17455 test_228a() {
17456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17457         remote_mds_nodsh && skip "remote MDS with nodsh"
17458         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17459
17460         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17461         local myDIR=$DIR/$tdir
17462
17463         mkdir -p $myDIR
17464         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17465         $LCTL set_param fail_loc=0x80001002
17466         createmany -o $myDIR/t- 10000
17467         $LCTL set_param fail_loc=0
17468         # The guard is current the largest FID holder
17469         touch $myDIR/guard
17470         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17471                     tr -d '[')
17472         local IDX=$(($SEQ % 64))
17473
17474         do_facet $SINGLEMDS sync
17475         # Make sure journal flushed.
17476         sleep 6
17477         local blk1=$(do_facet $SINGLEMDS \
17478                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17479                      grep Blockcount | awk '{print $4}')
17480
17481         # Remove old files, some OI blocks will become idle.
17482         unlinkmany $myDIR/t- 10000
17483         # Create new files, idle OI blocks should be reused.
17484         createmany -o $myDIR/t- 2000
17485         do_facet $SINGLEMDS sync
17486         # Make sure journal flushed.
17487         sleep 6
17488         local blk2=$(do_facet $SINGLEMDS \
17489                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17490                      grep Blockcount | awk '{print $4}')
17491
17492         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17493 }
17494 run_test 228a "try to reuse idle OI blocks"
17495
17496 test_228b() {
17497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17498         remote_mds_nodsh && skip "remote MDS with nodsh"
17499         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17500
17501         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17502         local myDIR=$DIR/$tdir
17503
17504         mkdir -p $myDIR
17505         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17506         $LCTL set_param fail_loc=0x80001002
17507         createmany -o $myDIR/t- 10000
17508         $LCTL set_param fail_loc=0
17509         # The guard is current the largest FID holder
17510         touch $myDIR/guard
17511         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17512                     tr -d '[')
17513         local IDX=$(($SEQ % 64))
17514
17515         do_facet $SINGLEMDS sync
17516         # Make sure journal flushed.
17517         sleep 6
17518         local blk1=$(do_facet $SINGLEMDS \
17519                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17520                      grep Blockcount | awk '{print $4}')
17521
17522         # Remove old files, some OI blocks will become idle.
17523         unlinkmany $myDIR/t- 10000
17524
17525         # stop the MDT
17526         stop $SINGLEMDS || error "Fail to stop MDT."
17527         # remount the MDT
17528         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17529
17530         df $MOUNT || error "Fail to df."
17531         # Create new files, idle OI blocks should be reused.
17532         createmany -o $myDIR/t- 2000
17533         do_facet $SINGLEMDS sync
17534         # Make sure journal flushed.
17535         sleep 6
17536         local blk2=$(do_facet $SINGLEMDS \
17537                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17538                      grep Blockcount | awk '{print $4}')
17539
17540         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17541 }
17542 run_test 228b "idle OI blocks can be reused after MDT restart"
17543
17544 #LU-1881
17545 test_228c() {
17546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17547         remote_mds_nodsh && skip "remote MDS with nodsh"
17548         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17549
17550         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17551         local myDIR=$DIR/$tdir
17552
17553         mkdir -p $myDIR
17554         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17555         $LCTL set_param fail_loc=0x80001002
17556         # 20000 files can guarantee there are index nodes in the OI file
17557         createmany -o $myDIR/t- 20000
17558         $LCTL set_param fail_loc=0
17559         # The guard is current the largest FID holder
17560         touch $myDIR/guard
17561         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17562                     tr -d '[')
17563         local IDX=$(($SEQ % 64))
17564
17565         do_facet $SINGLEMDS sync
17566         # Make sure journal flushed.
17567         sleep 6
17568         local blk1=$(do_facet $SINGLEMDS \
17569                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17570                      grep Blockcount | awk '{print $4}')
17571
17572         # Remove old files, some OI blocks will become idle.
17573         unlinkmany $myDIR/t- 20000
17574         rm -f $myDIR/guard
17575         # The OI file should become empty now
17576
17577         # Create new files, idle OI blocks should be reused.
17578         createmany -o $myDIR/t- 2000
17579         do_facet $SINGLEMDS sync
17580         # Make sure journal flushed.
17581         sleep 6
17582         local blk2=$(do_facet $SINGLEMDS \
17583                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17584                      grep Blockcount | awk '{print $4}')
17585
17586         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17587 }
17588 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17589
17590 test_229() { # LU-2482, LU-3448
17591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17592         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17593         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17594                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17595
17596         rm -f $DIR/$tfile
17597
17598         # Create a file with a released layout and stripe count 2.
17599         $MULTIOP $DIR/$tfile H2c ||
17600                 error "failed to create file with released layout"
17601
17602         $LFS getstripe -v $DIR/$tfile
17603
17604         local pattern=$($LFS getstripe -L $DIR/$tfile)
17605         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17606
17607         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17608                 error "getstripe"
17609         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17610         stat $DIR/$tfile || error "failed to stat released file"
17611
17612         chown $RUNAS_ID $DIR/$tfile ||
17613                 error "chown $RUNAS_ID $DIR/$tfile failed"
17614
17615         chgrp $RUNAS_ID $DIR/$tfile ||
17616                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17617
17618         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17619         rm $DIR/$tfile || error "failed to remove released file"
17620 }
17621 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17622
17623 test_230a() {
17624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17625         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17626         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17627                 skip "Need MDS version at least 2.11.52"
17628
17629         local MDTIDX=1
17630
17631         test_mkdir $DIR/$tdir
17632         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17633         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17634         [ $mdt_idx -ne 0 ] &&
17635                 error "create local directory on wrong MDT $mdt_idx"
17636
17637         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17638                         error "create remote directory failed"
17639         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17640         [ $mdt_idx -ne $MDTIDX ] &&
17641                 error "create remote directory on wrong MDT $mdt_idx"
17642
17643         createmany -o $DIR/$tdir/test_230/t- 10 ||
17644                 error "create files on remote directory failed"
17645         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17646         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17647         rm -r $DIR/$tdir || error "unlink remote directory failed"
17648 }
17649 run_test 230a "Create remote directory and files under the remote directory"
17650
17651 test_230b() {
17652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17654         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17655                 skip "Need MDS version at least 2.11.52"
17656
17657         local MDTIDX=1
17658         local mdt_index
17659         local i
17660         local file
17661         local pid
17662         local stripe_count
17663         local migrate_dir=$DIR/$tdir/migrate_dir
17664         local other_dir=$DIR/$tdir/other_dir
17665
17666         test_mkdir $DIR/$tdir
17667         test_mkdir -i0 -c1 $migrate_dir
17668         test_mkdir -i0 -c1 $other_dir
17669         for ((i=0; i<10; i++)); do
17670                 mkdir -p $migrate_dir/dir_${i}
17671                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17672                         error "create files under remote dir failed $i"
17673         done
17674
17675         cp /etc/passwd $migrate_dir/$tfile
17676         cp /etc/passwd $other_dir/$tfile
17677         chattr +SAD $migrate_dir
17678         chattr +SAD $migrate_dir/$tfile
17679
17680         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17681         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17682         local old_dir_mode=$(stat -c%f $migrate_dir)
17683         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17684
17685         mkdir -p $migrate_dir/dir_default_stripe2
17686         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17687         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17688
17689         mkdir -p $other_dir
17690         ln $migrate_dir/$tfile $other_dir/luna
17691         ln $migrate_dir/$tfile $migrate_dir/sofia
17692         ln $other_dir/$tfile $migrate_dir/david
17693         ln -s $migrate_dir/$tfile $other_dir/zachary
17694         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17695         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17696
17697         local len
17698         local lnktgt
17699
17700         # inline symlink
17701         for len in 58 59 60; do
17702                 lnktgt=$(str_repeat 'l' $len)
17703                 touch $migrate_dir/$lnktgt
17704                 ln -s $lnktgt $migrate_dir/${len}char_ln
17705         done
17706
17707         # PATH_MAX
17708         for len in 4094 4095; do
17709                 lnktgt=$(str_repeat 'l' $len)
17710                 ln -s $lnktgt $migrate_dir/${len}char_ln
17711         done
17712
17713         # NAME_MAX
17714         for len in 254 255; do
17715                 touch $migrate_dir/$(str_repeat 'l' $len)
17716         done
17717
17718         $LFS migrate -m $MDTIDX $migrate_dir ||
17719                 error "fails on migrating remote dir to MDT1"
17720
17721         echo "migratate to MDT1, then checking.."
17722         for ((i = 0; i < 10; i++)); do
17723                 for file in $(find $migrate_dir/dir_${i}); do
17724                         mdt_index=$($LFS getstripe -m $file)
17725                         # broken symlink getstripe will fail
17726                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17727                                 error "$file is not on MDT${MDTIDX}"
17728                 done
17729         done
17730
17731         # the multiple link file should still in MDT0
17732         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17733         [ $mdt_index == 0 ] ||
17734                 error "$file is not on MDT${MDTIDX}"
17735
17736         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17737         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17738                 error " expect $old_dir_flag get $new_dir_flag"
17739
17740         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17741         [ "$old_file_flag" = "$new_file_flag" ] ||
17742                 error " expect $old_file_flag get $new_file_flag"
17743
17744         local new_dir_mode=$(stat -c%f $migrate_dir)
17745         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17746                 error "expect mode $old_dir_mode get $new_dir_mode"
17747
17748         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17749         [ "$old_file_mode" = "$new_file_mode" ] ||
17750                 error "expect mode $old_file_mode get $new_file_mode"
17751
17752         diff /etc/passwd $migrate_dir/$tfile ||
17753                 error "$tfile different after migration"
17754
17755         diff /etc/passwd $other_dir/luna ||
17756                 error "luna different after migration"
17757
17758         diff /etc/passwd $migrate_dir/sofia ||
17759                 error "sofia different after migration"
17760
17761         diff /etc/passwd $migrate_dir/david ||
17762                 error "david different after migration"
17763
17764         diff /etc/passwd $other_dir/zachary ||
17765                 error "zachary different after migration"
17766
17767         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17768                 error "${tfile}_ln different after migration"
17769
17770         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17771                 error "${tfile}_ln_other different after migration"
17772
17773         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17774         [ $stripe_count = 2 ] ||
17775                 error "dir strpe_count $d != 2 after migration."
17776
17777         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17778         [ $stripe_count = 2 ] ||
17779                 error "file strpe_count $d != 2 after migration."
17780
17781         #migrate back to MDT0
17782         MDTIDX=0
17783
17784         $LFS migrate -m $MDTIDX $migrate_dir ||
17785                 error "fails on migrating remote dir to MDT0"
17786
17787         echo "migrate back to MDT0, checking.."
17788         for file in $(find $migrate_dir); do
17789                 mdt_index=$($LFS getstripe -m $file)
17790                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17791                         error "$file is not on MDT${MDTIDX}"
17792         done
17793
17794         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17795         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17796                 error " expect $old_dir_flag get $new_dir_flag"
17797
17798         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17799         [ "$old_file_flag" = "$new_file_flag" ] ||
17800                 error " expect $old_file_flag get $new_file_flag"
17801
17802         local new_dir_mode=$(stat -c%f $migrate_dir)
17803         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17804                 error "expect mode $old_dir_mode get $new_dir_mode"
17805
17806         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17807         [ "$old_file_mode" = "$new_file_mode" ] ||
17808                 error "expect mode $old_file_mode get $new_file_mode"
17809
17810         diff /etc/passwd ${migrate_dir}/$tfile ||
17811                 error "$tfile different after migration"
17812
17813         diff /etc/passwd ${other_dir}/luna ||
17814                 error "luna different after migration"
17815
17816         diff /etc/passwd ${migrate_dir}/sofia ||
17817                 error "sofia different after migration"
17818
17819         diff /etc/passwd ${other_dir}/zachary ||
17820                 error "zachary different after migration"
17821
17822         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17823                 error "${tfile}_ln different after migration"
17824
17825         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17826                 error "${tfile}_ln_other different after migration"
17827
17828         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17829         [ $stripe_count = 2 ] ||
17830                 error "dir strpe_count $d != 2 after migration."
17831
17832         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17833         [ $stripe_count = 2 ] ||
17834                 error "file strpe_count $d != 2 after migration."
17835
17836         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17837 }
17838 run_test 230b "migrate directory"
17839
17840 test_230c() {
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17843         remote_mds_nodsh && skip "remote MDS with nodsh"
17844         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17845                 skip "Need MDS version at least 2.11.52"
17846
17847         local MDTIDX=1
17848         local total=3
17849         local mdt_index
17850         local file
17851         local migrate_dir=$DIR/$tdir/migrate_dir
17852
17853         #If migrating directory fails in the middle, all entries of
17854         #the directory is still accessiable.
17855         test_mkdir $DIR/$tdir
17856         test_mkdir -i0 -c1 $migrate_dir
17857         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17858         stat $migrate_dir
17859         createmany -o $migrate_dir/f $total ||
17860                 error "create files under ${migrate_dir} failed"
17861
17862         # fail after migrating top dir, and this will fail only once, so the
17863         # first sub file migration will fail (currently f3), others succeed.
17864         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17865         do_facet mds1 lctl set_param fail_loc=0x1801
17866         local t=$(ls $migrate_dir | wc -l)
17867         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17868                 error "migrate should fail"
17869         local u=$(ls $migrate_dir | wc -l)
17870         [ "$u" == "$t" ] || error "$u != $t during migration"
17871
17872         # add new dir/file should succeed
17873         mkdir $migrate_dir/dir ||
17874                 error "mkdir failed under migrating directory"
17875         touch $migrate_dir/file ||
17876                 error "create file failed under migrating directory"
17877
17878         # add file with existing name should fail
17879         for file in $migrate_dir/f*; do
17880                 stat $file > /dev/null || error "stat $file failed"
17881                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17882                         error "open(O_CREAT|O_EXCL) $file should fail"
17883                 $MULTIOP $file m && error "create $file should fail"
17884                 touch $DIR/$tdir/remote_dir/$tfile ||
17885                         error "touch $tfile failed"
17886                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17887                         error "link $file should fail"
17888                 mdt_index=$($LFS getstripe -m $file)
17889                 if [ $mdt_index == 0 ]; then
17890                         # file failed to migrate is not allowed to rename to
17891                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17892                                 error "rename to $file should fail"
17893                 else
17894                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17895                                 error "rename to $file failed"
17896                 fi
17897                 echo hello >> $file || error "write $file failed"
17898         done
17899
17900         # resume migration with different options should fail
17901         $LFS migrate -m 0 $migrate_dir &&
17902                 error "migrate -m 0 $migrate_dir should fail"
17903
17904         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17905                 error "migrate -c 2 $migrate_dir should fail"
17906
17907         # resume migration should succeed
17908         $LFS migrate -m $MDTIDX $migrate_dir ||
17909                 error "migrate $migrate_dir failed"
17910
17911         echo "Finish migration, then checking.."
17912         for file in $(find $migrate_dir); do
17913                 mdt_index=$($LFS getstripe -m $file)
17914                 [ $mdt_index == $MDTIDX ] ||
17915                         error "$file is not on MDT${MDTIDX}"
17916         done
17917
17918         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17919 }
17920 run_test 230c "check directory accessiblity if migration failed"
17921
17922 test_230d() {
17923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17925         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17926                 skip "Need MDS version at least 2.11.52"
17927         # LU-11235
17928         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17929
17930         local migrate_dir=$DIR/$tdir/migrate_dir
17931         local old_index
17932         local new_index
17933         local old_count
17934         local new_count
17935         local new_hash
17936         local mdt_index
17937         local i
17938         local j
17939
17940         old_index=$((RANDOM % MDSCOUNT))
17941         old_count=$((MDSCOUNT - old_index))
17942         new_index=$((RANDOM % MDSCOUNT))
17943         new_count=$((MDSCOUNT - new_index))
17944         new_hash=1 # for all_char
17945
17946         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17947         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17948
17949         test_mkdir $DIR/$tdir
17950         test_mkdir -i $old_index -c $old_count $migrate_dir
17951
17952         for ((i=0; i<100; i++)); do
17953                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17954                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17955                         error "create files under remote dir failed $i"
17956         done
17957
17958         echo -n "Migrate from MDT$old_index "
17959         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17960         echo -n "to MDT$new_index"
17961         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17962         echo
17963
17964         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17965         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17966                 error "migrate remote dir error"
17967
17968         echo "Finish migration, then checking.."
17969         for file in $(find $migrate_dir); do
17970                 mdt_index=$($LFS getstripe -m $file)
17971                 if [ $mdt_index -lt $new_index ] ||
17972                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17973                         error "$file is on MDT$mdt_index"
17974                 fi
17975         done
17976
17977         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17978 }
17979 run_test 230d "check migrate big directory"
17980
17981 test_230e() {
17982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17983         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17984         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17985                 skip "Need MDS version at least 2.11.52"
17986
17987         local i
17988         local j
17989         local a_fid
17990         local b_fid
17991
17992         mkdir -p $DIR/$tdir
17993         mkdir $DIR/$tdir/migrate_dir
17994         mkdir $DIR/$tdir/other_dir
17995         touch $DIR/$tdir/migrate_dir/a
17996         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17997         ls $DIR/$tdir/other_dir
17998
17999         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18000                 error "migrate dir fails"
18001
18002         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18003         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18004
18005         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18006         [ $mdt_index == 0 ] || error "a is not on MDT0"
18007
18008         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18009                 error "migrate dir fails"
18010
18011         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18012         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18013
18014         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18015         [ $mdt_index == 1 ] || error "a is not on MDT1"
18016
18017         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18018         [ $mdt_index == 1 ] || error "b is not on MDT1"
18019
18020         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18021         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18022
18023         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18024
18025         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18026 }
18027 run_test 230e "migrate mulitple local link files"
18028
18029 test_230f() {
18030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18031         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18032         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18033                 skip "Need MDS version at least 2.11.52"
18034
18035         local a_fid
18036         local ln_fid
18037
18038         mkdir -p $DIR/$tdir
18039         mkdir $DIR/$tdir/migrate_dir
18040         $LFS mkdir -i1 $DIR/$tdir/other_dir
18041         touch $DIR/$tdir/migrate_dir/a
18042         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18043         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18044         ls $DIR/$tdir/other_dir
18045
18046         # a should be migrated to MDT1, since no other links on MDT0
18047         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18048                 error "#1 migrate dir fails"
18049         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18050         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18051         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18052         [ $mdt_index == 1 ] || error "a is not on MDT1"
18053
18054         # a should stay on MDT1, because it is a mulitple link file
18055         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18056                 error "#2 migrate dir fails"
18057         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18058         [ $mdt_index == 1 ] || error "a is not on MDT1"
18059
18060         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18061                 error "#3 migrate dir fails"
18062
18063         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18064         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18065         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18066
18067         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18068         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18069
18070         # a should be migrated to MDT0, since no other links on MDT1
18071         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18072                 error "#4 migrate dir fails"
18073         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18074         [ $mdt_index == 0 ] || error "a is not on MDT0"
18075
18076         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18077 }
18078 run_test 230f "migrate mulitple remote link files"
18079
18080 test_230g() {
18081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18082         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18083         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18084                 skip "Need MDS version at least 2.11.52"
18085
18086         mkdir -p $DIR/$tdir/migrate_dir
18087
18088         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18089                 error "migrating dir to non-exist MDT succeeds"
18090         true
18091 }
18092 run_test 230g "migrate dir to non-exist MDT"
18093
18094 test_230h() {
18095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18097         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18098                 skip "Need MDS version at least 2.11.52"
18099
18100         local mdt_index
18101
18102         mkdir -p $DIR/$tdir/migrate_dir
18103
18104         $LFS migrate -m1 $DIR &&
18105                 error "migrating mountpoint1 should fail"
18106
18107         $LFS migrate -m1 $DIR/$tdir/.. &&
18108                 error "migrating mountpoint2 should fail"
18109
18110         # same as mv
18111         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18112                 error "migrating $tdir/migrate_dir/.. should fail"
18113
18114         true
18115 }
18116 run_test 230h "migrate .. and root"
18117
18118 test_230i() {
18119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18121         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18122                 skip "Need MDS version at least 2.11.52"
18123
18124         mkdir -p $DIR/$tdir/migrate_dir
18125
18126         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18127                 error "migration fails with a tailing slash"
18128
18129         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18130                 error "migration fails with two tailing slashes"
18131 }
18132 run_test 230i "lfs migrate -m tolerates trailing slashes"
18133
18134 test_230j() {
18135         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18136         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18137                 skip "Need MDS version at least 2.11.52"
18138
18139         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18140         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18141                 error "create $tfile failed"
18142         cat /etc/passwd > $DIR/$tdir/$tfile
18143
18144         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18145
18146         cmp /etc/passwd $DIR/$tdir/$tfile ||
18147                 error "DoM file mismatch after migration"
18148 }
18149 run_test 230j "DoM file data not changed after dir migration"
18150
18151 test_230k() {
18152         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18153         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18154                 skip "Need MDS version at least 2.11.56"
18155
18156         local total=20
18157         local files_on_starting_mdt=0
18158
18159         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18160         $LFS getdirstripe $DIR/$tdir
18161         for i in $(seq $total); do
18162                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18163                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18164                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18165         done
18166
18167         echo "$files_on_starting_mdt files on MDT0"
18168
18169         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18170         $LFS getdirstripe $DIR/$tdir
18171
18172         files_on_starting_mdt=0
18173         for i in $(seq $total); do
18174                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18175                         error "file $tfile.$i mismatch after migration"
18176                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18177                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18178         done
18179
18180         echo "$files_on_starting_mdt files on MDT1 after migration"
18181         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18182
18183         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18184         $LFS getdirstripe $DIR/$tdir
18185
18186         files_on_starting_mdt=0
18187         for i in $(seq $total); do
18188                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18189                         error "file $tfile.$i mismatch after 2nd migration"
18190                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18191                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18192         done
18193
18194         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18195         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18196
18197         true
18198 }
18199 run_test 230k "file data not changed after dir migration"
18200
18201 test_230l() {
18202         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18203         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18204                 skip "Need MDS version at least 2.11.56"
18205
18206         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18207         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18208                 error "create files under remote dir failed $i"
18209         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18210 }
18211 run_test 230l "readdir between MDTs won't crash"
18212
18213 test_230m() {
18214         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18215         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18216                 skip "Need MDS version at least 2.11.56"
18217
18218         local MDTIDX=1
18219         local mig_dir=$DIR/$tdir/migrate_dir
18220         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18221         local shortstr="b"
18222         local val
18223
18224         echo "Creating files and dirs with xattrs"
18225         test_mkdir $DIR/$tdir
18226         test_mkdir -i0 -c1 $mig_dir
18227         mkdir $mig_dir/dir
18228         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18229                 error "cannot set xattr attr1 on dir"
18230         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18231                 error "cannot set xattr attr2 on dir"
18232         touch $mig_dir/dir/f0
18233         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18234                 error "cannot set xattr attr1 on file"
18235         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18236                 error "cannot set xattr attr2 on file"
18237         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18238         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18239         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18240         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18241         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18242         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18243         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18244         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18245         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18246
18247         echo "Migrating to MDT1"
18248         $LFS migrate -m $MDTIDX $mig_dir ||
18249                 error "fails on migrating dir to MDT1"
18250
18251         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18252         echo "Checking xattrs"
18253         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18254         [ "$val" = $longstr ] ||
18255                 error "expecting xattr1 $longstr on dir, found $val"
18256         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18257         [ "$val" = $shortstr ] ||
18258                 error "expecting xattr2 $shortstr on dir, found $val"
18259         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18260         [ "$val" = $longstr ] ||
18261                 error "expecting xattr1 $longstr on file, found $val"
18262         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18263         [ "$val" = $shortstr ] ||
18264                 error "expecting xattr2 $shortstr on file, found $val"
18265 }
18266 run_test 230m "xattrs not changed after dir migration"
18267
18268 test_230n() {
18269         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18270         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18271                 skip "Need MDS version at least 2.13.53"
18272
18273         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18274         cat /etc/hosts > $DIR/$tdir/$tfile
18275         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18276         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18277
18278         cmp /etc/hosts $DIR/$tdir/$tfile ||
18279                 error "File data mismatch after migration"
18280 }
18281 run_test 230n "Dir migration with mirrored file"
18282
18283 test_230o() {
18284         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18285         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18286                 skip "Need MDS version at least 2.13.52"
18287
18288         local mdts=$(comma_list $(mdts_nodes))
18289         local timeout=100
18290
18291         local restripe_status
18292         local delta
18293         local i
18294         local j
18295
18296         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18297
18298         # in case "crush" hash type is not set
18299         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18300
18301         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18302                            mdt.*MDT0000.enable_dir_restripe)
18303         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18304         stack_trap "do_nodes $mdts $LCTL set_param \
18305                     mdt.*.enable_dir_restripe=$restripe_status"
18306
18307         mkdir $DIR/$tdir
18308         createmany -m $DIR/$tdir/f 100 ||
18309                 error "create files under remote dir failed $i"
18310         createmany -d $DIR/$tdir/d 100 ||
18311                 error "create dirs under remote dir failed $i"
18312
18313         for i in $(seq 2 $MDSCOUNT); do
18314                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18315                 $LFS setdirstripe -c $i $DIR/$tdir ||
18316                         error "split -c $i $tdir failed"
18317                 wait_update $HOSTNAME \
18318                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18319                         error "dir split not finished"
18320                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18321                         awk '/migrate/ {sum += $2} END { print sum }')
18322                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18323                 # delta is around total_files/stripe_count
18324                 [ $delta -lt $((200 /(i - 1))) ] ||
18325                         error "$delta files migrated"
18326         done
18327 }
18328 run_test 230o "dir split"
18329
18330 test_230p() {
18331         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18332         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18333                 skip "Need MDS version at least 2.13.52"
18334
18335         local mdts=$(comma_list $(mdts_nodes))
18336         local timeout=100
18337
18338         local restripe_status
18339         local delta
18340         local i
18341         local j
18342
18343         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18344
18345         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18346
18347         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18348                            mdt.*MDT0000.enable_dir_restripe)
18349         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18350         stack_trap "do_nodes $mdts $LCTL set_param \
18351                     mdt.*.enable_dir_restripe=$restripe_status"
18352
18353         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18354         createmany -m $DIR/$tdir/f 100 ||
18355                 error "create files under remote dir failed $i"
18356         createmany -d $DIR/$tdir/d 100 ||
18357                 error "create dirs under remote dir failed $i"
18358
18359         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18360                 local mdt_hash="crush"
18361
18362                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18363                 $LFS setdirstripe -c $i $DIR/$tdir ||
18364                         error "split -c $i $tdir failed"
18365                 [ $i -eq 1 ] && mdt_hash="none"
18366                 wait_update $HOSTNAME \
18367                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18368                         error "dir merge not finished"
18369                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18370                         awk '/migrate/ {sum += $2} END { print sum }')
18371                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18372                 # delta is around total_files/stripe_count
18373                 [ $delta -lt $((200 / i)) ] ||
18374                         error "$delta files migrated"
18375         done
18376 }
18377 run_test 230p "dir merge"
18378
18379 test_230q() {
18380         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18381         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18382                 skip "Need MDS version at least 2.13.52"
18383
18384         local mdts=$(comma_list $(mdts_nodes))
18385         local saved_threshold=$(do_facet mds1 \
18386                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18387         local saved_delta=$(do_facet mds1 \
18388                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18389         local threshold=100
18390         local delta=2
18391         local total=0
18392         local stripe_count=0
18393         local stripe_index
18394         local nr_files
18395
18396         # test with fewer files on ZFS
18397         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18398
18399         stack_trap "do_nodes $mdts $LCTL set_param \
18400                     mdt.*.dir_split_count=$saved_threshold"
18401         stack_trap "do_nodes $mdts $LCTL set_param \
18402                     mdt.*.dir_split_delta=$saved_delta"
18403         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18404         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18405         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18406         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18407         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18408         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18409
18410         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18411         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18412
18413         while [ $stripe_count -lt $MDSCOUNT ]; do
18414                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18415                         error "create sub files failed"
18416                 stat $DIR/$tdir > /dev/null
18417                 total=$((total + threshold * 3 / 2))
18418                 stripe_count=$((stripe_count + delta))
18419                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18420
18421                 wait_update $HOSTNAME \
18422                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18423                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18424
18425                 wait_update $HOSTNAME \
18426                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18427                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18428
18429                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18430                            grep -w $stripe_index | wc -l)
18431                 echo "$nr_files files on MDT$stripe_index after split"
18432                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18433                         error "$nr_files files on MDT$stripe_index after split"
18434
18435                 nr_files=$(ls $DIR/$tdir | wc -w)
18436                 [ $nr_files -eq $total ] ||
18437                         error "total sub files $nr_files != $total"
18438         done
18439 }
18440 run_test 230q "dir auto split"
18441
18442 test_230r() {
18443         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18444         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18445         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18446                 skip "Need MDS version at least 2.13.54"
18447
18448         # maximum amount of local locks:
18449         # parent striped dir - 2 locks
18450         # new stripe in parent to migrate to - 1 lock
18451         # source and target - 2 locks
18452         # Total 5 locks for regular file
18453         mkdir -p $DIR/$tdir
18454         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18455         touch $DIR/$tdir/dir1/eee
18456
18457         # create 4 hardlink for 4 more locks
18458         # Total: 9 locks > RS_MAX_LOCKS (8)
18459         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18460         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18461         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18462         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18463         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18464         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18465         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18466         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18467
18468         cancel_lru_locks mdc
18469
18470         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18471                 error "migrate dir fails"
18472
18473         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18474 }
18475 run_test 230r "migrate with too many local locks"
18476
18477 test_231a()
18478 {
18479         # For simplicity this test assumes that max_pages_per_rpc
18480         # is the same across all OSCs
18481         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18482         local bulk_size=$((max_pages * PAGE_SIZE))
18483         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18484                                        head -n 1)
18485
18486         mkdir -p $DIR/$tdir
18487         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18488                 error "failed to set stripe with -S ${brw_size}M option"
18489
18490         # clear the OSC stats
18491         $LCTL set_param osc.*.stats=0 &>/dev/null
18492         stop_writeback
18493
18494         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18495         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18496                 oflag=direct &>/dev/null || error "dd failed"
18497
18498         sync; sleep 1; sync # just to be safe
18499         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18500         if [ x$nrpcs != "x1" ]; then
18501                 $LCTL get_param osc.*.stats
18502                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18503         fi
18504
18505         start_writeback
18506         # Drop the OSC cache, otherwise we will read from it
18507         cancel_lru_locks osc
18508
18509         # clear the OSC stats
18510         $LCTL set_param osc.*.stats=0 &>/dev/null
18511
18512         # Client reads $bulk_size.
18513         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18514                 iflag=direct &>/dev/null || error "dd failed"
18515
18516         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18517         if [ x$nrpcs != "x1" ]; then
18518                 $LCTL get_param osc.*.stats
18519                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18520         fi
18521 }
18522 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18523
18524 test_231b() {
18525         mkdir -p $DIR/$tdir
18526         local i
18527         for i in {0..1023}; do
18528                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18529                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18530                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18531         done
18532         sync
18533 }
18534 run_test 231b "must not assert on fully utilized OST request buffer"
18535
18536 test_232a() {
18537         mkdir -p $DIR/$tdir
18538         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18539
18540         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18541         do_facet ost1 $LCTL set_param fail_loc=0x31c
18542
18543         # ignore dd failure
18544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18545
18546         do_facet ost1 $LCTL set_param fail_loc=0
18547         umount_client $MOUNT || error "umount failed"
18548         mount_client $MOUNT || error "mount failed"
18549         stop ost1 || error "cannot stop ost1"
18550         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18551 }
18552 run_test 232a "failed lock should not block umount"
18553
18554 test_232b() {
18555         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18556                 skip "Need MDS version at least 2.10.58"
18557
18558         mkdir -p $DIR/$tdir
18559         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18561         sync
18562         cancel_lru_locks osc
18563
18564         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18565         do_facet ost1 $LCTL set_param fail_loc=0x31c
18566
18567         # ignore failure
18568         $LFS data_version $DIR/$tdir/$tfile || true
18569
18570         do_facet ost1 $LCTL set_param fail_loc=0
18571         umount_client $MOUNT || error "umount failed"
18572         mount_client $MOUNT || error "mount failed"
18573         stop ost1 || error "cannot stop ost1"
18574         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18575 }
18576 run_test 232b "failed data version lock should not block umount"
18577
18578 test_233a() {
18579         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18580                 skip "Need MDS version at least 2.3.64"
18581         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18582
18583         local fid=$($LFS path2fid $MOUNT)
18584
18585         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18586                 error "cannot access $MOUNT using its FID '$fid'"
18587 }
18588 run_test 233a "checking that OBF of the FS root succeeds"
18589
18590 test_233b() {
18591         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18592                 skip "Need MDS version at least 2.5.90"
18593         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18594
18595         local fid=$($LFS path2fid $MOUNT/.lustre)
18596
18597         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18598                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18599
18600         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18601         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18602                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18603 }
18604 run_test 233b "checking that OBF of the FS .lustre succeeds"
18605
18606 test_234() {
18607         local p="$TMP/sanityN-$TESTNAME.parameters"
18608         save_lustre_params client "llite.*.xattr_cache" > $p
18609         lctl set_param llite.*.xattr_cache 1 ||
18610                 skip_env "xattr cache is not supported"
18611
18612         mkdir -p $DIR/$tdir || error "mkdir failed"
18613         touch $DIR/$tdir/$tfile || error "touch failed"
18614         # OBD_FAIL_LLITE_XATTR_ENOMEM
18615         $LCTL set_param fail_loc=0x1405
18616         getfattr -n user.attr $DIR/$tdir/$tfile &&
18617                 error "getfattr should have failed with ENOMEM"
18618         $LCTL set_param fail_loc=0x0
18619         rm -rf $DIR/$tdir
18620
18621         restore_lustre_params < $p
18622         rm -f $p
18623 }
18624 run_test 234 "xattr cache should not crash on ENOMEM"
18625
18626 test_235() {
18627         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18628                 skip "Need MDS version at least 2.4.52"
18629
18630         flock_deadlock $DIR/$tfile
18631         local RC=$?
18632         case $RC in
18633                 0)
18634                 ;;
18635                 124) error "process hangs on a deadlock"
18636                 ;;
18637                 *) error "error executing flock_deadlock $DIR/$tfile"
18638                 ;;
18639         esac
18640 }
18641 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18642
18643 #LU-2935
18644 test_236() {
18645         check_swap_layouts_support
18646
18647         local ref1=/etc/passwd
18648         local ref2=/etc/group
18649         local file1=$DIR/$tdir/f1
18650         local file2=$DIR/$tdir/f2
18651
18652         test_mkdir -c1 $DIR/$tdir
18653         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18654         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18655         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18656         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18657         local fd=$(free_fd)
18658         local cmd="exec $fd<>$file2"
18659         eval $cmd
18660         rm $file2
18661         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18662                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18663         cmd="exec $fd>&-"
18664         eval $cmd
18665         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18666
18667         #cleanup
18668         rm -rf $DIR/$tdir
18669 }
18670 run_test 236 "Layout swap on open unlinked file"
18671
18672 # LU-4659 linkea consistency
18673 test_238() {
18674         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18675                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18676                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18677                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18678
18679         touch $DIR/$tfile
18680         ln $DIR/$tfile $DIR/$tfile.lnk
18681         touch $DIR/$tfile.new
18682         mv $DIR/$tfile.new $DIR/$tfile
18683         local fid1=$($LFS path2fid $DIR/$tfile)
18684         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18685         local path1=$($LFS fid2path $FSNAME "$fid1")
18686         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18687         local path2=$($LFS fid2path $FSNAME "$fid2")
18688         [ $tfile.lnk == $path2 ] ||
18689                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18690         rm -f $DIR/$tfile*
18691 }
18692 run_test 238 "Verify linkea consistency"
18693
18694 test_239A() { # was test_239
18695         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18696                 skip "Need MDS version at least 2.5.60"
18697
18698         local list=$(comma_list $(mdts_nodes))
18699
18700         mkdir -p $DIR/$tdir
18701         createmany -o $DIR/$tdir/f- 5000
18702         unlinkmany $DIR/$tdir/f- 5000
18703         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18704                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18705         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18706                         osp.*MDT*.sync_in_flight" | calc_sum)
18707         [ "$changes" -eq 0 ] || error "$changes not synced"
18708 }
18709 run_test 239A "osp_sync test"
18710
18711 test_239a() { #LU-5297
18712         remote_mds_nodsh && skip "remote MDS with nodsh"
18713
18714         touch $DIR/$tfile
18715         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18716         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18717         chgrp $RUNAS_GID $DIR/$tfile
18718         wait_delete_completed
18719 }
18720 run_test 239a "process invalid osp sync record correctly"
18721
18722 test_239b() { #LU-5297
18723         remote_mds_nodsh && skip "remote MDS with nodsh"
18724
18725         touch $DIR/$tfile1
18726         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18727         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18728         chgrp $RUNAS_GID $DIR/$tfile1
18729         wait_delete_completed
18730         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18731         touch $DIR/$tfile2
18732         chgrp $RUNAS_GID $DIR/$tfile2
18733         wait_delete_completed
18734 }
18735 run_test 239b "process osp sync record with ENOMEM error correctly"
18736
18737 test_240() {
18738         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18739         remote_mds_nodsh && skip "remote MDS with nodsh"
18740
18741         mkdir -p $DIR/$tdir
18742
18743         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18744                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18745         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18746                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18747
18748         umount_client $MOUNT || error "umount failed"
18749         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18750         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18751         mount_client $MOUNT || error "failed to mount client"
18752
18753         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18754         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18755 }
18756 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18757
18758 test_241_bio() {
18759         local count=$1
18760         local bsize=$2
18761
18762         for LOOP in $(seq $count); do
18763                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18764                 cancel_lru_locks $OSC || true
18765         done
18766 }
18767
18768 test_241_dio() {
18769         local count=$1
18770         local bsize=$2
18771
18772         for LOOP in $(seq $1); do
18773                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18774                         2>/dev/null
18775         done
18776 }
18777
18778 test_241a() { # was test_241
18779         local bsize=$PAGE_SIZE
18780
18781         (( bsize < 40960 )) && bsize=40960
18782         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18783         ls -la $DIR/$tfile
18784         cancel_lru_locks $OSC
18785         test_241_bio 1000 $bsize &
18786         PID=$!
18787         test_241_dio 1000 $bsize
18788         wait $PID
18789 }
18790 run_test 241a "bio vs dio"
18791
18792 test_241b() {
18793         local bsize=$PAGE_SIZE
18794
18795         (( bsize < 40960 )) && bsize=40960
18796         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18797         ls -la $DIR/$tfile
18798         test_241_dio 1000 $bsize &
18799         PID=$!
18800         test_241_dio 1000 $bsize
18801         wait $PID
18802 }
18803 run_test 241b "dio vs dio"
18804
18805 test_242() {
18806         remote_mds_nodsh && skip "remote MDS with nodsh"
18807
18808         mkdir -p $DIR/$tdir
18809         touch $DIR/$tdir/$tfile
18810
18811         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18812         do_facet mds1 lctl set_param fail_loc=0x105
18813         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18814
18815         do_facet mds1 lctl set_param fail_loc=0
18816         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18817 }
18818 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18819
18820 test_243()
18821 {
18822         test_mkdir $DIR/$tdir
18823         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18824 }
18825 run_test 243 "various group lock tests"
18826
18827 test_244a()
18828 {
18829         test_mkdir $DIR/$tdir
18830         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18831         sendfile_grouplock $DIR/$tdir/$tfile || \
18832                 error "sendfile+grouplock failed"
18833         rm -rf $DIR/$tdir
18834 }
18835 run_test 244a "sendfile with group lock tests"
18836
18837 test_244b()
18838 {
18839         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18840
18841         local threads=50
18842         local size=$((1024*1024))
18843
18844         test_mkdir $DIR/$tdir
18845         for i in $(seq 1 $threads); do
18846                 local file=$DIR/$tdir/file_$((i / 10))
18847                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18848                 local pids[$i]=$!
18849         done
18850         for i in $(seq 1 $threads); do
18851                 wait ${pids[$i]}
18852         done
18853 }
18854 run_test 244b "multi-threaded write with group lock"
18855
18856 test_245() {
18857         local flagname="multi_mod_rpcs"
18858         local connect_data_name="max_mod_rpcs"
18859         local out
18860
18861         # check if multiple modify RPCs flag is set
18862         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18863                 grep "connect_flags:")
18864         echo "$out"
18865
18866         echo "$out" | grep -qw $flagname
18867         if [ $? -ne 0 ]; then
18868                 echo "connect flag $flagname is not set"
18869                 return
18870         fi
18871
18872         # check if multiple modify RPCs data is set
18873         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18874         echo "$out"
18875
18876         echo "$out" | grep -qw $connect_data_name ||
18877                 error "import should have connect data $connect_data_name"
18878 }
18879 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18880
18881 cleanup_247() {
18882         local submount=$1
18883
18884         trap 0
18885         umount_client $submount
18886         rmdir $submount
18887 }
18888
18889 test_247a() {
18890         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18891                 grep -q subtree ||
18892                 skip_env "Fileset feature is not supported"
18893
18894         local submount=${MOUNT}_$tdir
18895
18896         mkdir $MOUNT/$tdir
18897         mkdir -p $submount || error "mkdir $submount failed"
18898         FILESET="$FILESET/$tdir" mount_client $submount ||
18899                 error "mount $submount failed"
18900         trap "cleanup_247 $submount" EXIT
18901         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18902         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18903                 error "read $MOUNT/$tdir/$tfile failed"
18904         cleanup_247 $submount
18905 }
18906 run_test 247a "mount subdir as fileset"
18907
18908 test_247b() {
18909         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18910                 skip_env "Fileset feature is not supported"
18911
18912         local submount=${MOUNT}_$tdir
18913
18914         rm -rf $MOUNT/$tdir
18915         mkdir -p $submount || error "mkdir $submount failed"
18916         SKIP_FILESET=1
18917         FILESET="$FILESET/$tdir" mount_client $submount &&
18918                 error "mount $submount should fail"
18919         rmdir $submount
18920 }
18921 run_test 247b "mount subdir that dose not exist"
18922
18923 test_247c() {
18924         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18925                 skip_env "Fileset feature is not supported"
18926
18927         local submount=${MOUNT}_$tdir
18928
18929         mkdir -p $MOUNT/$tdir/dir1
18930         mkdir -p $submount || error "mkdir $submount failed"
18931         trap "cleanup_247 $submount" EXIT
18932         FILESET="$FILESET/$tdir" mount_client $submount ||
18933                 error "mount $submount failed"
18934         local fid=$($LFS path2fid $MOUNT/)
18935         $LFS fid2path $submount $fid && error "fid2path should fail"
18936         cleanup_247 $submount
18937 }
18938 run_test 247c "running fid2path outside subdirectory root"
18939
18940 test_247d() {
18941         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18942                 skip "Fileset feature is not supported"
18943
18944         local submount=${MOUNT}_$tdir
18945
18946         mkdir -p $MOUNT/$tdir/dir1
18947         mkdir -p $submount || error "mkdir $submount failed"
18948         FILESET="$FILESET/$tdir" mount_client $submount ||
18949                 error "mount $submount failed"
18950         trap "cleanup_247 $submount" EXIT
18951
18952         local td=$submount/dir1
18953         local fid=$($LFS path2fid $td)
18954         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18955
18956         # check that we get the same pathname back
18957         local rootpath
18958         local found
18959         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18960                 echo "$rootpath $fid"
18961                 found=$($LFS fid2path $rootpath "$fid")
18962                 [ -n "found" ] || error "fid2path should succeed"
18963                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18964         done
18965         # check wrong root path format
18966         rootpath=$submount"_wrong"
18967         found=$($LFS fid2path $rootpath "$fid")
18968         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18969
18970         cleanup_247 $submount
18971 }
18972 run_test 247d "running fid2path inside subdirectory root"
18973
18974 # LU-8037
18975 test_247e() {
18976         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18977                 grep -q subtree ||
18978                 skip "Fileset feature is not supported"
18979
18980         local submount=${MOUNT}_$tdir
18981
18982         mkdir $MOUNT/$tdir
18983         mkdir -p $submount || error "mkdir $submount failed"
18984         FILESET="$FILESET/.." mount_client $submount &&
18985                 error "mount $submount should fail"
18986         rmdir $submount
18987 }
18988 run_test 247e "mount .. as fileset"
18989
18990 test_247f() {
18991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18992         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18993                 skip "Need at least version 2.13.52"
18994         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18995                 grep -q subtree ||
18996                 skip "Fileset feature is not supported"
18997
18998         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18999         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19000                 error "mkdir remote failed"
19001         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19002         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19003                 error "mkdir striped failed"
19004         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19005
19006         local submount=${MOUNT}_$tdir
19007
19008         mkdir -p $submount || error "mkdir $submount failed"
19009
19010         local dir
19011         local fileset=$FILESET
19012
19013         for dir in $tdir/remote $tdir/remote/subdir \
19014                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19015                 FILESET="$fileset/$dir" mount_client $submount ||
19016                         error "mount $dir failed"
19017                 umount_client $submount
19018         done
19019 }
19020 run_test 247f "mount striped or remote directory as fileset"
19021
19022 test_248a() {
19023         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19024         [ -z "$fast_read_sav" ] && skip "no fast read support"
19025
19026         # create a large file for fast read verification
19027         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19028
19029         # make sure the file is created correctly
19030         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19031                 { rm -f $DIR/$tfile; skip "file creation error"; }
19032
19033         echo "Test 1: verify that fast read is 4 times faster on cache read"
19034
19035         # small read with fast read enabled
19036         $LCTL set_param -n llite.*.fast_read=1
19037         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19038                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19039                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19040         # small read with fast read disabled
19041         $LCTL set_param -n llite.*.fast_read=0
19042         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19043                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19044                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19045
19046         # verify that fast read is 4 times faster for cache read
19047         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19048                 error_not_in_vm "fast read was not 4 times faster: " \
19049                            "$t_fast vs $t_slow"
19050
19051         echo "Test 2: verify the performance between big and small read"
19052         $LCTL set_param -n llite.*.fast_read=1
19053
19054         # 1k non-cache read
19055         cancel_lru_locks osc
19056         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19057                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19058                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19059
19060         # 1M non-cache read
19061         cancel_lru_locks osc
19062         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19063                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19064                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19065
19066         # verify that big IO is not 4 times faster than small IO
19067         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19068                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19069
19070         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19071         rm -f $DIR/$tfile
19072 }
19073 run_test 248a "fast read verification"
19074
19075 test_248b() {
19076         # Default short_io_bytes=16384, try both smaller and larger sizes.
19077         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19078         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19079         echo "bs=53248 count=113 normal buffered write"
19080         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19081                 error "dd of initial data file failed"
19082         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19083
19084         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19085         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19086                 error "dd with sync normal writes failed"
19087         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19088
19089         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19090         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19091                 error "dd with sync small writes failed"
19092         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19093
19094         cancel_lru_locks osc
19095
19096         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19097         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19098         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19099         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19100                 iflag=direct || error "dd with O_DIRECT small read failed"
19101         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19102         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19103                 error "compare $TMP/$tfile.1 failed"
19104
19105         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19106         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19107
19108         # just to see what the maximum tunable value is, and test parsing
19109         echo "test invalid parameter 2MB"
19110         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19111                 error "too-large short_io_bytes allowed"
19112         echo "test maximum parameter 512KB"
19113         # if we can set a larger short_io_bytes, run test regardless of version
19114         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19115                 # older clients may not allow setting it this large, that's OK
19116                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19117                         skip "Need at least client version 2.13.50"
19118                 error "medium short_io_bytes failed"
19119         fi
19120         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19121         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19122
19123         echo "test large parameter 64KB"
19124         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19125         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19126
19127         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19128         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19129                 error "dd with sync large writes failed"
19130         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19131
19132         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19133         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19134         num=$((113 * 4096 / PAGE_SIZE))
19135         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19136         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19137                 error "dd with O_DIRECT large writes failed"
19138         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19139                 error "compare $DIR/$tfile.3 failed"
19140
19141         cancel_lru_locks osc
19142
19143         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19144         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19145                 error "dd with O_DIRECT large read failed"
19146         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19147                 error "compare $TMP/$tfile.2 failed"
19148
19149         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19150         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19151                 error "dd with O_DIRECT large read failed"
19152         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19153                 error "compare $TMP/$tfile.3 failed"
19154 }
19155 run_test 248b "test short_io read and write for both small and large sizes"
19156
19157 test_249() { # LU-7890
19158         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19159                 skip "Need at least version 2.8.54"
19160
19161         rm -f $DIR/$tfile
19162         $LFS setstripe -c 1 $DIR/$tfile
19163         # Offset 2T == 4k * 512M
19164         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19165                 error "dd to 2T offset failed"
19166 }
19167 run_test 249 "Write above 2T file size"
19168
19169 test_250() {
19170         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19171          && skip "no 16TB file size limit on ZFS"
19172
19173         $LFS setstripe -c 1 $DIR/$tfile
19174         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19175         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19176         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19177         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19178                 conv=notrunc,fsync && error "append succeeded"
19179         return 0
19180 }
19181 run_test 250 "Write above 16T limit"
19182
19183 test_251() {
19184         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19185
19186         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19187         #Skip once - writing the first stripe will succeed
19188         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19189         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19190                 error "short write happened"
19191
19192         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19193         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19194                 error "short read happened"
19195
19196         rm -f $DIR/$tfile
19197 }
19198 run_test 251 "Handling short read and write correctly"
19199
19200 test_252() {
19201         remote_mds_nodsh && skip "remote MDS with nodsh"
19202         remote_ost_nodsh && skip "remote OST with nodsh"
19203         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19204                 skip_env "ldiskfs only test"
19205         fi
19206
19207         local tgt
19208         local dev
19209         local out
19210         local uuid
19211         local num
19212         local gen
19213
19214         # check lr_reader on OST0000
19215         tgt=ost1
19216         dev=$(facet_device $tgt)
19217         out=$(do_facet $tgt $LR_READER $dev)
19218         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19219         echo "$out"
19220         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19221         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19222                 error "Invalid uuid returned by $LR_READER on target $tgt"
19223         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19224
19225         # check lr_reader -c on MDT0000
19226         tgt=mds1
19227         dev=$(facet_device $tgt)
19228         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19229                 skip "$LR_READER does not support additional options"
19230         fi
19231         out=$(do_facet $tgt $LR_READER -c $dev)
19232         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19233         echo "$out"
19234         num=$(echo "$out" | grep -c "mdtlov")
19235         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19236                 error "Invalid number of mdtlov clients returned by $LR_READER"
19237         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19238
19239         # check lr_reader -cr on MDT0000
19240         out=$(do_facet $tgt $LR_READER -cr $dev)
19241         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19242         echo "$out"
19243         echo "$out" | grep -q "^reply_data:$" ||
19244                 error "$LR_READER should have returned 'reply_data' section"
19245         num=$(echo "$out" | grep -c "client_generation")
19246         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19247 }
19248 run_test 252 "check lr_reader tool"
19249
19250 test_253() {
19251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19252         remote_mds_nodsh && skip "remote MDS with nodsh"
19253         remote_mgs_nodsh && skip "remote MGS with nodsh"
19254
19255         local ostidx=0
19256         local rc=0
19257         local ost_name=$(ostname_from_index $ostidx)
19258
19259         # on the mdt's osc
19260         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19261         do_facet $SINGLEMDS $LCTL get_param -n \
19262                 osp.$mdtosc_proc1.reserved_mb_high ||
19263                 skip  "remote MDS does not support reserved_mb_high"
19264
19265         rm -rf $DIR/$tdir
19266         wait_mds_ost_sync
19267         wait_delete_completed
19268         mkdir $DIR/$tdir
19269
19270         pool_add $TESTNAME || error "Pool creation failed"
19271         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19272
19273         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19274                 error "Setstripe failed"
19275
19276         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19277
19278         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19279                     grep "watermarks")
19280         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19281
19282         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19283                         osp.$mdtosc_proc1.prealloc_status)
19284         echo "prealloc_status $oa_status"
19285
19286         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19287                 error "File creation should fail"
19288
19289         #object allocation was stopped, but we still able to append files
19290         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19291                 oflag=append || error "Append failed"
19292
19293         rm -f $DIR/$tdir/$tfile.0
19294
19295         # For this test, we want to delete the files we created to go out of
19296         # space but leave the watermark, so we remain nearly out of space
19297         ost_watermarks_enospc_delete_files $tfile $ostidx
19298
19299         wait_delete_completed
19300
19301         sleep_maxage
19302
19303         for i in $(seq 10 12); do
19304                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19305                         2>/dev/null || error "File creation failed after rm"
19306         done
19307
19308         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19309                         osp.$mdtosc_proc1.prealloc_status)
19310         echo "prealloc_status $oa_status"
19311
19312         if (( oa_status != 0 )); then
19313                 error "Object allocation still disable after rm"
19314         fi
19315 }
19316 run_test 253 "Check object allocation limit"
19317
19318 test_254() {
19319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19320         remote_mds_nodsh && skip "remote MDS with nodsh"
19321         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19322                 skip "MDS does not support changelog_size"
19323
19324         local cl_user
19325         local MDT0=$(facet_svc $SINGLEMDS)
19326
19327         changelog_register || error "changelog_register failed"
19328
19329         changelog_clear 0 || error "changelog_clear failed"
19330
19331         local size1=$(do_facet $SINGLEMDS \
19332                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19333         echo "Changelog size $size1"
19334
19335         rm -rf $DIR/$tdir
19336         $LFS mkdir -i 0 $DIR/$tdir
19337         # change something
19338         mkdir -p $DIR/$tdir/pics/2008/zachy
19339         touch $DIR/$tdir/pics/2008/zachy/timestamp
19340         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19341         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19342         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19343         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19344         rm $DIR/$tdir/pics/desktop.jpg
19345
19346         local size2=$(do_facet $SINGLEMDS \
19347                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19348         echo "Changelog size after work $size2"
19349
19350         (( $size2 > $size1 )) ||
19351                 error "new Changelog size=$size2 less than old size=$size1"
19352 }
19353 run_test 254 "Check changelog size"
19354
19355 ladvise_no_type()
19356 {
19357         local type=$1
19358         local file=$2
19359
19360         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19361                 awk -F: '{print $2}' | grep $type > /dev/null
19362         if [ $? -ne 0 ]; then
19363                 return 0
19364         fi
19365         return 1
19366 }
19367
19368 ladvise_no_ioctl()
19369 {
19370         local file=$1
19371
19372         lfs ladvise -a willread $file > /dev/null 2>&1
19373         if [ $? -eq 0 ]; then
19374                 return 1
19375         fi
19376
19377         lfs ladvise -a willread $file 2>&1 |
19378                 grep "Inappropriate ioctl for device" > /dev/null
19379         if [ $? -eq 0 ]; then
19380                 return 0
19381         fi
19382         return 1
19383 }
19384
19385 percent() {
19386         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19387 }
19388
19389 # run a random read IO workload
19390 # usage: random_read_iops <filename> <filesize> <iosize>
19391 random_read_iops() {
19392         local file=$1
19393         local fsize=$2
19394         local iosize=${3:-4096}
19395
19396         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19397                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19398 }
19399
19400 drop_file_oss_cache() {
19401         local file="$1"
19402         local nodes="$2"
19403
19404         $LFS ladvise -a dontneed $file 2>/dev/null ||
19405                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19406 }
19407
19408 ladvise_willread_performance()
19409 {
19410         local repeat=10
19411         local average_origin=0
19412         local average_cache=0
19413         local average_ladvise=0
19414
19415         for ((i = 1; i <= $repeat; i++)); do
19416                 echo "Iter $i/$repeat: reading without willread hint"
19417                 cancel_lru_locks osc
19418                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19419                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19420                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19421                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19422
19423                 cancel_lru_locks osc
19424                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19425                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19426                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19427
19428                 cancel_lru_locks osc
19429                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19430                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19431                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19432                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19433                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19434         done
19435         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19436         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19437         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19438
19439         speedup_cache=$(percent $average_cache $average_origin)
19440         speedup_ladvise=$(percent $average_ladvise $average_origin)
19441
19442         echo "Average uncached read: $average_origin"
19443         echo "Average speedup with OSS cached read: " \
19444                 "$average_cache = +$speedup_cache%"
19445         echo "Average speedup with ladvise willread: " \
19446                 "$average_ladvise = +$speedup_ladvise%"
19447
19448         local lowest_speedup=20
19449         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19450                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19451                         "got $average_cache%. Skipping ladvise willread check."
19452                 return 0
19453         fi
19454
19455         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19456         # it is still good to run until then to exercise 'ladvise willread'
19457         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19458                 [ "$ost1_FSTYPE" = "zfs" ] &&
19459                 echo "osd-zfs does not support dontneed or drop_caches" &&
19460                 return 0
19461
19462         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19463         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19464                 error_not_in_vm "Speedup with willread is less than " \
19465                         "$lowest_speedup%, got $average_ladvise%"
19466 }
19467
19468 test_255a() {
19469         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19470                 skip "lustre < 2.8.54 does not support ladvise "
19471         remote_ost_nodsh && skip "remote OST with nodsh"
19472
19473         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19474
19475         ladvise_no_type willread $DIR/$tfile &&
19476                 skip "willread ladvise is not supported"
19477
19478         ladvise_no_ioctl $DIR/$tfile &&
19479                 skip "ladvise ioctl is not supported"
19480
19481         local size_mb=100
19482         local size=$((size_mb * 1048576))
19483         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19484                 error "dd to $DIR/$tfile failed"
19485
19486         lfs ladvise -a willread $DIR/$tfile ||
19487                 error "Ladvise failed with no range argument"
19488
19489         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19490                 error "Ladvise failed with no -l or -e argument"
19491
19492         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19493                 error "Ladvise failed with only -e argument"
19494
19495         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19496                 error "Ladvise failed with only -l argument"
19497
19498         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19499                 error "End offset should not be smaller than start offset"
19500
19501         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19502                 error "End offset should not be equal to start offset"
19503
19504         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19505                 error "Ladvise failed with overflowing -s argument"
19506
19507         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19508                 error "Ladvise failed with overflowing -e argument"
19509
19510         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19511                 error "Ladvise failed with overflowing -l argument"
19512
19513         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19514                 error "Ladvise succeeded with conflicting -l and -e arguments"
19515
19516         echo "Synchronous ladvise should wait"
19517         local delay=4
19518 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19519         do_nodes $(comma_list $(osts_nodes)) \
19520                 $LCTL set_param fail_val=$delay fail_loc=0x237
19521
19522         local start_ts=$SECONDS
19523         lfs ladvise -a willread $DIR/$tfile ||
19524                 error "Ladvise failed with no range argument"
19525         local end_ts=$SECONDS
19526         local inteval_ts=$((end_ts - start_ts))
19527
19528         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19529                 error "Synchronous advice didn't wait reply"
19530         fi
19531
19532         echo "Asynchronous ladvise shouldn't wait"
19533         local start_ts=$SECONDS
19534         lfs ladvise -a willread -b $DIR/$tfile ||
19535                 error "Ladvise failed with no range argument"
19536         local end_ts=$SECONDS
19537         local inteval_ts=$((end_ts - start_ts))
19538
19539         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19540                 error "Asynchronous advice blocked"
19541         fi
19542
19543         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19544         ladvise_willread_performance
19545 }
19546 run_test 255a "check 'lfs ladvise -a willread'"
19547
19548 facet_meminfo() {
19549         local facet=$1
19550         local info=$2
19551
19552         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19553 }
19554
19555 test_255b() {
19556         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19557                 skip "lustre < 2.8.54 does not support ladvise "
19558         remote_ost_nodsh && skip "remote OST with nodsh"
19559
19560         lfs setstripe -c 1 -i 0 $DIR/$tfile
19561
19562         ladvise_no_type dontneed $DIR/$tfile &&
19563                 skip "dontneed ladvise is not supported"
19564
19565         ladvise_no_ioctl $DIR/$tfile &&
19566                 skip "ladvise ioctl is not supported"
19567
19568         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19569                 [ "$ost1_FSTYPE" = "zfs" ] &&
19570                 skip "zfs-osd does not support 'ladvise dontneed'"
19571
19572         local size_mb=100
19573         local size=$((size_mb * 1048576))
19574         # In order to prevent disturbance of other processes, only check 3/4
19575         # of the memory usage
19576         local kibibytes=$((size_mb * 1024 * 3 / 4))
19577
19578         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19579                 error "dd to $DIR/$tfile failed"
19580
19581         #force write to complete before dropping OST cache & checking memory
19582         sync
19583
19584         local total=$(facet_meminfo ost1 MemTotal)
19585         echo "Total memory: $total KiB"
19586
19587         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19588         local before_read=$(facet_meminfo ost1 Cached)
19589         echo "Cache used before read: $before_read KiB"
19590
19591         lfs ladvise -a willread $DIR/$tfile ||
19592                 error "Ladvise willread failed"
19593         local after_read=$(facet_meminfo ost1 Cached)
19594         echo "Cache used after read: $after_read KiB"
19595
19596         lfs ladvise -a dontneed $DIR/$tfile ||
19597                 error "Ladvise dontneed again failed"
19598         local no_read=$(facet_meminfo ost1 Cached)
19599         echo "Cache used after dontneed ladvise: $no_read KiB"
19600
19601         if [ $total -lt $((before_read + kibibytes)) ]; then
19602                 echo "Memory is too small, abort checking"
19603                 return 0
19604         fi
19605
19606         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19607                 error "Ladvise willread should use more memory" \
19608                         "than $kibibytes KiB"
19609         fi
19610
19611         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19612                 error "Ladvise dontneed should release more memory" \
19613                         "than $kibibytes KiB"
19614         fi
19615 }
19616 run_test 255b "check 'lfs ladvise -a dontneed'"
19617
19618 test_255c() {
19619         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19620                 skip "lustre < 2.10.50 does not support lockahead"
19621
19622         local count
19623         local new_count
19624         local difference
19625         local i
19626         local rc
19627
19628         test_mkdir -p $DIR/$tdir
19629         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19630
19631         #test 10 returns only success/failure
19632         i=10
19633         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19634         rc=$?
19635         if [ $rc -eq 255 ]; then
19636                 error "Ladvise test${i} failed, ${rc}"
19637         fi
19638
19639         #test 11 counts lock enqueue requests, all others count new locks
19640         i=11
19641         count=$(do_facet ost1 \
19642                 $LCTL get_param -n ost.OSS.ost.stats)
19643         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19644
19645         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19646         rc=$?
19647         if [ $rc -eq 255 ]; then
19648                 error "Ladvise test${i} failed, ${rc}"
19649         fi
19650
19651         new_count=$(do_facet ost1 \
19652                 $LCTL get_param -n ost.OSS.ost.stats)
19653         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19654                    awk '{ print $2 }')
19655
19656         difference="$((new_count - count))"
19657         if [ $difference -ne $rc ]; then
19658                 error "Ladvise test${i}, bad enqueue count, returned " \
19659                       "${rc}, actual ${difference}"
19660         fi
19661
19662         for i in $(seq 12 21); do
19663                 # If we do not do this, we run the risk of having too many
19664                 # locks and starting lock cancellation while we are checking
19665                 # lock counts.
19666                 cancel_lru_locks osc
19667
19668                 count=$($LCTL get_param -n \
19669                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19670
19671                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19672                 rc=$?
19673                 if [ $rc -eq 255 ]; then
19674                         error "Ladvise test ${i} failed, ${rc}"
19675                 fi
19676
19677                 new_count=$($LCTL get_param -n \
19678                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19679                 difference="$((new_count - count))"
19680
19681                 # Test 15 output is divided by 100 to map down to valid return
19682                 if [ $i -eq 15 ]; then
19683                         rc="$((rc * 100))"
19684                 fi
19685
19686                 if [ $difference -ne $rc ]; then
19687                         error "Ladvise test ${i}, bad lock count, returned " \
19688                               "${rc}, actual ${difference}"
19689                 fi
19690         done
19691
19692         #test 22 returns only success/failure
19693         i=22
19694         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19695         rc=$?
19696         if [ $rc -eq 255 ]; then
19697                 error "Ladvise test${i} failed, ${rc}"
19698         fi
19699 }
19700 run_test 255c "suite of ladvise lockahead tests"
19701
19702 test_256() {
19703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19704         remote_mds_nodsh && skip "remote MDS with nodsh"
19705         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19706         changelog_users $SINGLEMDS | grep "^cl" &&
19707                 skip "active changelog user"
19708
19709         local cl_user
19710         local cat_sl
19711         local mdt_dev
19712
19713         mdt_dev=$(mdsdevname 1)
19714         echo $mdt_dev
19715
19716         changelog_register || error "changelog_register failed"
19717
19718         rm -rf $DIR/$tdir
19719         mkdir -p $DIR/$tdir
19720
19721         changelog_clear 0 || error "changelog_clear failed"
19722
19723         # change something
19724         touch $DIR/$tdir/{1..10}
19725
19726         # stop the MDT
19727         stop $SINGLEMDS || error "Fail to stop MDT"
19728
19729         # remount the MDT
19730
19731         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19732
19733         #after mount new plainllog is used
19734         touch $DIR/$tdir/{11..19}
19735         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19736         stack_trap "rm -f $tmpfile"
19737         cat_sl=$(do_facet $SINGLEMDS "sync; \
19738                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19739                  llog_reader $tmpfile | grep -c type=1064553b")
19740         do_facet $SINGLEMDS llog_reader $tmpfile
19741
19742         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19743
19744         changelog_clear 0 || error "changelog_clear failed"
19745
19746         cat_sl=$(do_facet $SINGLEMDS "sync; \
19747                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19748                  llog_reader $tmpfile | grep -c type=1064553b")
19749
19750         if (( cat_sl == 2 )); then
19751                 error "Empty plain llog was not deleted from changelog catalog"
19752         elif (( cat_sl != 1 )); then
19753                 error "Active plain llog shouldn't be deleted from catalog"
19754         fi
19755 }
19756 run_test 256 "Check llog delete for empty and not full state"
19757
19758 test_257() {
19759         remote_mds_nodsh && skip "remote MDS with nodsh"
19760         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19761                 skip "Need MDS version at least 2.8.55"
19762
19763         test_mkdir $DIR/$tdir
19764
19765         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19766                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19767         stat $DIR/$tdir
19768
19769 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19770         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19771         local facet=mds$((mdtidx + 1))
19772         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19773         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19774
19775         stop $facet || error "stop MDS failed"
19776         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19777                 error "start MDS fail"
19778         wait_recovery_complete $facet
19779 }
19780 run_test 257 "xattr locks are not lost"
19781
19782 # Verify we take the i_mutex when security requires it
19783 test_258a() {
19784 #define OBD_FAIL_IMUTEX_SEC 0x141c
19785         $LCTL set_param fail_loc=0x141c
19786         touch $DIR/$tfile
19787         chmod u+s $DIR/$tfile
19788         chmod a+rwx $DIR/$tfile
19789         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19790         RC=$?
19791         if [ $RC -ne 0 ]; then
19792                 error "error, failed to take i_mutex, rc=$?"
19793         fi
19794         rm -f $DIR/$tfile
19795 }
19796 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19797
19798 # Verify we do NOT take the i_mutex in the normal case
19799 test_258b() {
19800 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19801         $LCTL set_param fail_loc=0x141d
19802         touch $DIR/$tfile
19803         chmod a+rwx $DIR
19804         chmod a+rw $DIR/$tfile
19805         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19806         RC=$?
19807         if [ $RC -ne 0 ]; then
19808                 error "error, took i_mutex unnecessarily, rc=$?"
19809         fi
19810         rm -f $DIR/$tfile
19811
19812 }
19813 run_test 258b "verify i_mutex security behavior"
19814
19815 test_259() {
19816         local file=$DIR/$tfile
19817         local before
19818         local after
19819
19820         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19821
19822         stack_trap "rm -f $file" EXIT
19823
19824         wait_delete_completed
19825         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19826         echo "before: $before"
19827
19828         $LFS setstripe -i 0 -c 1 $file
19829         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19830         sync_all_data
19831         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19832         echo "after write: $after"
19833
19834 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19835         do_facet ost1 $LCTL set_param fail_loc=0x2301
19836         $TRUNCATE $file 0
19837         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19838         echo "after truncate: $after"
19839
19840         stop ost1
19841         do_facet ost1 $LCTL set_param fail_loc=0
19842         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19843         sleep 2
19844         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19845         echo "after restart: $after"
19846         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19847                 error "missing truncate?"
19848
19849         return 0
19850 }
19851 run_test 259 "crash at delayed truncate"
19852
19853 test_260() {
19854 #define OBD_FAIL_MDC_CLOSE               0x806
19855         $LCTL set_param fail_loc=0x80000806
19856         touch $DIR/$tfile
19857
19858 }
19859 run_test 260 "Check mdc_close fail"
19860
19861 ### Data-on-MDT sanity tests ###
19862 test_270a() {
19863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19864                 skip "Need MDS version at least 2.10.55 for DoM"
19865
19866         # create DoM file
19867         local dom=$DIR/$tdir/dom_file
19868         local tmp=$DIR/$tdir/tmp_file
19869
19870         mkdir -p $DIR/$tdir
19871
19872         # basic checks for DoM component creation
19873         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19874                 error "Can set MDT layout to non-first entry"
19875
19876         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19877                 error "Can define multiple entries as MDT layout"
19878
19879         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19880
19881         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19882         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19883         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19884
19885         local mdtidx=$($LFS getstripe -m $dom)
19886         local mdtname=MDT$(printf %04x $mdtidx)
19887         local facet=mds$((mdtidx + 1))
19888         local space_check=1
19889
19890         # Skip free space checks with ZFS
19891         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19892
19893         # write
19894         sync
19895         local size_tmp=$((65536 * 3))
19896         local mdtfree1=$(do_facet $facet \
19897                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19898
19899         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19900         # check also direct IO along write
19901         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19902         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19903         sync
19904         cmp $tmp $dom || error "file data is different"
19905         [ $(stat -c%s $dom) == $size_tmp ] ||
19906                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19907         if [ $space_check == 1 ]; then
19908                 local mdtfree2=$(do_facet $facet \
19909                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19910
19911                 # increase in usage from by $size_tmp
19912                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19913                         error "MDT free space wrong after write: " \
19914                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19915         fi
19916
19917         # truncate
19918         local size_dom=10000
19919
19920         $TRUNCATE $dom $size_dom
19921         [ $(stat -c%s $dom) == $size_dom ] ||
19922                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19923         if [ $space_check == 1 ]; then
19924                 mdtfree1=$(do_facet $facet \
19925                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19926                 # decrease in usage from $size_tmp to new $size_dom
19927                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19928                   $(((size_tmp - size_dom) / 1024)) ] ||
19929                         error "MDT free space is wrong after truncate: " \
19930                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19931         fi
19932
19933         # append
19934         cat $tmp >> $dom
19935         sync
19936         size_dom=$((size_dom + size_tmp))
19937         [ $(stat -c%s $dom) == $size_dom ] ||
19938                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19939         if [ $space_check == 1 ]; then
19940                 mdtfree2=$(do_facet $facet \
19941                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19942                 # increase in usage by $size_tmp from previous
19943                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19944                         error "MDT free space is wrong after append: " \
19945                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19946         fi
19947
19948         # delete
19949         rm $dom
19950         if [ $space_check == 1 ]; then
19951                 mdtfree1=$(do_facet $facet \
19952                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19953                 # decrease in usage by $size_dom from previous
19954                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19955                         error "MDT free space is wrong after removal: " \
19956                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19957         fi
19958
19959         # combined striping
19960         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19961                 error "Can't create DoM + OST striping"
19962
19963         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19964         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19965         # check also direct IO along write
19966         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19967         sync
19968         cmp $tmp $dom || error "file data is different"
19969         [ $(stat -c%s $dom) == $size_tmp ] ||
19970                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19971         rm $dom $tmp
19972
19973         return 0
19974 }
19975 run_test 270a "DoM: basic functionality tests"
19976
19977 test_270b() {
19978         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19979                 skip "Need MDS version at least 2.10.55"
19980
19981         local dom=$DIR/$tdir/dom_file
19982         local max_size=1048576
19983
19984         mkdir -p $DIR/$tdir
19985         $LFS setstripe -E $max_size -L mdt $dom
19986
19987         # truncate over the limit
19988         $TRUNCATE $dom $(($max_size + 1)) &&
19989                 error "successful truncate over the maximum size"
19990         # write over the limit
19991         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19992                 error "successful write over the maximum size"
19993         # append over the limit
19994         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19995         echo "12345" >> $dom && error "successful append over the maximum size"
19996         rm $dom
19997
19998         return 0
19999 }
20000 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20001
20002 test_270c() {
20003         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20004                 skip "Need MDS version at least 2.10.55"
20005
20006         mkdir -p $DIR/$tdir
20007         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20008
20009         # check files inherit DoM EA
20010         touch $DIR/$tdir/first
20011         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20012                 error "bad pattern"
20013         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20014                 error "bad stripe count"
20015         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20016                 error "bad stripe size"
20017
20018         # check directory inherits DoM EA and uses it as default
20019         mkdir $DIR/$tdir/subdir
20020         touch $DIR/$tdir/subdir/second
20021         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20022                 error "bad pattern in sub-directory"
20023         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20024                 error "bad stripe count in sub-directory"
20025         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20026                 error "bad stripe size in sub-directory"
20027         return 0
20028 }
20029 run_test 270c "DoM: DoM EA inheritance tests"
20030
20031 test_270d() {
20032         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20033                 skip "Need MDS version at least 2.10.55"
20034
20035         mkdir -p $DIR/$tdir
20036         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20037
20038         # inherit default DoM striping
20039         mkdir $DIR/$tdir/subdir
20040         touch $DIR/$tdir/subdir/f1
20041
20042         # change default directory striping
20043         $LFS setstripe -c 1 $DIR/$tdir/subdir
20044         touch $DIR/$tdir/subdir/f2
20045         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20046                 error "wrong default striping in file 2"
20047         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20048                 error "bad pattern in file 2"
20049         return 0
20050 }
20051 run_test 270d "DoM: change striping from DoM to RAID0"
20052
20053 test_270e() {
20054         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20055                 skip "Need MDS version at least 2.10.55"
20056
20057         mkdir -p $DIR/$tdir/dom
20058         mkdir -p $DIR/$tdir/norm
20059         DOMFILES=20
20060         NORMFILES=10
20061         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20062         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20063
20064         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20065         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20066
20067         # find DoM files by layout
20068         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20069         [ $NUM -eq  $DOMFILES ] ||
20070                 error "lfs find -L: found $NUM, expected $DOMFILES"
20071         echo "Test 1: lfs find 20 DOM files by layout: OK"
20072
20073         # there should be 1 dir with default DOM striping
20074         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20075         [ $NUM -eq  1 ] ||
20076                 error "lfs find -L: found $NUM, expected 1 dir"
20077         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20078
20079         # find DoM files by stripe size
20080         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20081         [ $NUM -eq  $DOMFILES ] ||
20082                 error "lfs find -S: found $NUM, expected $DOMFILES"
20083         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20084
20085         # find files by stripe offset except DoM files
20086         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20087         [ $NUM -eq  $NORMFILES ] ||
20088                 error "lfs find -i: found $NUM, expected $NORMFILES"
20089         echo "Test 5: lfs find no DOM files by stripe index: OK"
20090         return 0
20091 }
20092 run_test 270e "DoM: lfs find with DoM files test"
20093
20094 test_270f() {
20095         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20096                 skip "Need MDS version at least 2.10.55"
20097
20098         local mdtname=${FSNAME}-MDT0000-mdtlov
20099         local dom=$DIR/$tdir/dom_file
20100         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20101                                                 lod.$mdtname.dom_stripesize)
20102         local dom_limit=131072
20103
20104         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20105         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20106                                                 lod.$mdtname.dom_stripesize)
20107         [ ${dom_limit} -eq ${dom_current} ] ||
20108                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20109
20110         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20111         $LFS setstripe -d $DIR/$tdir
20112         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20113                 error "Can't set directory default striping"
20114
20115         # exceed maximum stripe size
20116         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20117                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20118         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20119                 error "Able to create DoM component size more than LOD limit"
20120
20121         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20122         dom_current=$(do_facet mds1 $LCTL get_param -n \
20123                                                 lod.$mdtname.dom_stripesize)
20124         [ 0 -eq ${dom_current} ] ||
20125                 error "Can't set zero DoM stripe limit"
20126         rm $dom
20127
20128         # attempt to create DoM file on server with disabled DoM should
20129         # remove DoM entry from layout and be succeed
20130         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20131                 error "Can't create DoM file (DoM is disabled)"
20132         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20133                 error "File has DoM component while DoM is disabled"
20134         rm $dom
20135
20136         # attempt to create DoM file with only DoM stripe should return error
20137         $LFS setstripe -E $dom_limit -L mdt $dom &&
20138                 error "Able to create DoM-only file while DoM is disabled"
20139
20140         # too low values to be aligned with smallest stripe size 64K
20141         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20142         dom_current=$(do_facet mds1 $LCTL get_param -n \
20143                                                 lod.$mdtname.dom_stripesize)
20144         [ 30000 -eq ${dom_current} ] &&
20145                 error "Can set too small DoM stripe limit"
20146
20147         # 64K is a minimal stripe size in Lustre, expect limit of that size
20148         [ 65536 -eq ${dom_current} ] ||
20149                 error "Limit is not set to 64K but ${dom_current}"
20150
20151         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20152         dom_current=$(do_facet mds1 $LCTL get_param -n \
20153                                                 lod.$mdtname.dom_stripesize)
20154         echo $dom_current
20155         [ 2147483648 -eq ${dom_current} ] &&
20156                 error "Can set too large DoM stripe limit"
20157
20158         do_facet mds1 $LCTL set_param -n \
20159                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20160         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20161                 error "Can't create DoM component size after limit change"
20162         do_facet mds1 $LCTL set_param -n \
20163                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20164         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20165                 error "Can't create DoM file after limit decrease"
20166         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20167                 error "Can create big DoM component after limit decrease"
20168         touch ${dom}_def ||
20169                 error "Can't create file with old default layout"
20170
20171         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20172         return 0
20173 }
20174 run_test 270f "DoM: maximum DoM stripe size checks"
20175
20176 test_270g() {
20177         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20178                 skip "Need MDS version at least 2.13.52"
20179         local dom=$DIR/$tdir/$tfile
20180
20181         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20182         local lodname=${FSNAME}-MDT0000-mdtlov
20183
20184         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20185         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20186         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20187         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20188
20189         local dom_limit=1024
20190         local dom_threshold="50%"
20191
20192         $LFS setstripe -d $DIR/$tdir
20193         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20194                 error "Can't set directory default striping"
20195
20196         do_facet mds1 $LCTL set_param -n \
20197                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20198         # set 0 threshold and create DOM file to change tunable stripesize
20199         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20200         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20201                 error "Failed to create $dom file"
20202         # now tunable dom_cur_stripesize should reach maximum
20203         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20204                                         lod.${lodname}.dom_stripesize_cur_kb)
20205         [[ $dom_current == $dom_limit ]] ||
20206                 error "Current DOM stripesize is not maximum"
20207         rm $dom
20208
20209         # set threshold for further tests
20210         do_facet mds1 $LCTL set_param -n \
20211                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20212         echo "DOM threshold is $dom_threshold free space"
20213         local dom_def
20214         local dom_set
20215         # Spoof bfree to exceed threshold
20216         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20217         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20218         for spfree in 40 20 0 15 30 55; do
20219                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20220                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20221                         error "Failed to create $dom file"
20222                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20223                                         lod.${lodname}.dom_stripesize_cur_kb)
20224                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20225                 [[ $dom_def != $dom_current ]] ||
20226                         error "Default stripe size was not changed"
20227                 if [[ $spfree > 0 ]] ; then
20228                         dom_set=$($LFS getstripe -S $dom)
20229                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20230                                 error "DOM component size is still old"
20231                 else
20232                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20233                                 error "DoM component is set with no free space"
20234                 fi
20235                 rm $dom
20236                 dom_current=$dom_def
20237         done
20238 }
20239 run_test 270g "DoM: default DoM stripe size depends on free space"
20240
20241 test_270h() {
20242         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20243                 skip "Need MDS version at least 2.13.53"
20244
20245         local mdtname=${FSNAME}-MDT0000-mdtlov
20246         local dom=$DIR/$tdir/$tfile
20247         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20248
20249         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20250         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20251
20252         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20253         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20254                 error "can't create OST file"
20255         # mirrored file with DOM entry in the second mirror
20256         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20257                 error "can't create mirror with DoM component"
20258
20259         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20260
20261         # DOM component in the middle and has other enries in the same mirror,
20262         # should succeed but lost DoM component
20263         $LFS setstripe --copy=${dom}_1 $dom ||
20264                 error "Can't create file from OST|DOM mirror layout"
20265         # check new file has no DoM layout after all
20266         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20267                 error "File has DoM component while DoM is disabled"
20268 }
20269 run_test 270h "DoM: DoM stripe removal when disabled on server"
20270
20271 test_271a() {
20272         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20273                 skip "Need MDS version at least 2.10.55"
20274
20275         local dom=$DIR/$tdir/dom
20276
20277         mkdir -p $DIR/$tdir
20278
20279         $LFS setstripe -E 1024K -L mdt $dom
20280
20281         lctl set_param -n mdc.*.stats=clear
20282         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20283         cat $dom > /dev/null
20284         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20285         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20286         ls $dom
20287         rm -f $dom
20288 }
20289 run_test 271a "DoM: data is cached for read after write"
20290
20291 test_271b() {
20292         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20293                 skip "Need MDS version at least 2.10.55"
20294
20295         local dom=$DIR/$tdir/dom
20296
20297         mkdir -p $DIR/$tdir
20298
20299         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20300
20301         lctl set_param -n mdc.*.stats=clear
20302         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20303         cancel_lru_locks mdc
20304         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20305         # second stat to check size is cached on client
20306         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20307         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20308         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20309         rm -f $dom
20310 }
20311 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20312
20313 test_271ba() {
20314         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20315                 skip "Need MDS version at least 2.10.55"
20316
20317         local dom=$DIR/$tdir/dom
20318
20319         mkdir -p $DIR/$tdir
20320
20321         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20322
20323         lctl set_param -n mdc.*.stats=clear
20324         lctl set_param -n osc.*.stats=clear
20325         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20326         cancel_lru_locks mdc
20327         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20328         # second stat to check size is cached on client
20329         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20330         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20331         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20332         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20333         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20334         rm -f $dom
20335 }
20336 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20337
20338
20339 get_mdc_stats() {
20340         local mdtidx=$1
20341         local param=$2
20342         local mdt=MDT$(printf %04x $mdtidx)
20343
20344         if [ -z $param ]; then
20345                 lctl get_param -n mdc.*$mdt*.stats
20346         else
20347                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20348         fi
20349 }
20350
20351 test_271c() {
20352         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20353                 skip "Need MDS version at least 2.10.55"
20354
20355         local dom=$DIR/$tdir/dom
20356
20357         mkdir -p $DIR/$tdir
20358
20359         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20360
20361         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20362         local facet=mds$((mdtidx + 1))
20363
20364         cancel_lru_locks mdc
20365         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20366         createmany -o $dom 1000
20367         lctl set_param -n mdc.*.stats=clear
20368         smalliomany -w $dom 1000 200
20369         get_mdc_stats $mdtidx
20370         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20371         # Each file has 1 open, 1 IO enqueues, total 2000
20372         # but now we have also +1 getxattr for security.capability, total 3000
20373         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20374         unlinkmany $dom 1000
20375
20376         cancel_lru_locks mdc
20377         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20378         createmany -o $dom 1000
20379         lctl set_param -n mdc.*.stats=clear
20380         smalliomany -w $dom 1000 200
20381         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20382         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20383         # for OPEN and IO lock.
20384         [ $((enq - enq_2)) -ge 1000 ] ||
20385                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20386         unlinkmany $dom 1000
20387         return 0
20388 }
20389 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20390
20391 cleanup_271def_tests() {
20392         trap 0
20393         rm -f $1
20394 }
20395
20396 test_271d() {
20397         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20398                 skip "Need MDS version at least 2.10.57"
20399
20400         local dom=$DIR/$tdir/dom
20401         local tmp=$TMP/$tfile
20402         trap "cleanup_271def_tests $tmp" EXIT
20403
20404         mkdir -p $DIR/$tdir
20405
20406         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20407
20408         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20409
20410         cancel_lru_locks mdc
20411         dd if=/dev/urandom of=$tmp bs=1000 count=1
20412         dd if=$tmp of=$dom bs=1000 count=1
20413         cancel_lru_locks mdc
20414
20415         cat /etc/hosts >> $tmp
20416         lctl set_param -n mdc.*.stats=clear
20417
20418         # append data to the same file it should update local page
20419         echo "Append to the same page"
20420         cat /etc/hosts >> $dom
20421         local num=$(get_mdc_stats $mdtidx ost_read)
20422         local ra=$(get_mdc_stats $mdtidx req_active)
20423         local rw=$(get_mdc_stats $mdtidx req_waittime)
20424
20425         [ -z $num ] || error "$num READ RPC occured"
20426         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20427         echo "... DONE"
20428
20429         # compare content
20430         cmp $tmp $dom || error "file miscompare"
20431
20432         cancel_lru_locks mdc
20433         lctl set_param -n mdc.*.stats=clear
20434
20435         echo "Open and read file"
20436         cat $dom > /dev/null
20437         local num=$(get_mdc_stats $mdtidx ost_read)
20438         local ra=$(get_mdc_stats $mdtidx req_active)
20439         local rw=$(get_mdc_stats $mdtidx req_waittime)
20440
20441         [ -z $num ] || error "$num READ RPC occured"
20442         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20443         echo "... DONE"
20444
20445         # compare content
20446         cmp $tmp $dom || error "file miscompare"
20447
20448         return 0
20449 }
20450 run_test 271d "DoM: read on open (1K file in reply buffer)"
20451
20452 test_271f() {
20453         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20454                 skip "Need MDS version at least 2.10.57"
20455
20456         local dom=$DIR/$tdir/dom
20457         local tmp=$TMP/$tfile
20458         trap "cleanup_271def_tests $tmp" EXIT
20459
20460         mkdir -p $DIR/$tdir
20461
20462         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20463
20464         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20465
20466         cancel_lru_locks mdc
20467         dd if=/dev/urandom of=$tmp bs=265000 count=1
20468         dd if=$tmp of=$dom bs=265000 count=1
20469         cancel_lru_locks mdc
20470         cat /etc/hosts >> $tmp
20471         lctl set_param -n mdc.*.stats=clear
20472
20473         echo "Append to the same page"
20474         cat /etc/hosts >> $dom
20475         local num=$(get_mdc_stats $mdtidx ost_read)
20476         local ra=$(get_mdc_stats $mdtidx req_active)
20477         local rw=$(get_mdc_stats $mdtidx req_waittime)
20478
20479         [ -z $num ] || error "$num READ RPC occured"
20480         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20481         echo "... DONE"
20482
20483         # compare content
20484         cmp $tmp $dom || error "file miscompare"
20485
20486         cancel_lru_locks mdc
20487         lctl set_param -n mdc.*.stats=clear
20488
20489         echo "Open and read file"
20490         cat $dom > /dev/null
20491         local num=$(get_mdc_stats $mdtidx ost_read)
20492         local ra=$(get_mdc_stats $mdtidx req_active)
20493         local rw=$(get_mdc_stats $mdtidx req_waittime)
20494
20495         [ -z $num ] && num=0
20496         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20497         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20498         echo "... DONE"
20499
20500         # compare content
20501         cmp $tmp $dom || error "file miscompare"
20502
20503         return 0
20504 }
20505 run_test 271f "DoM: read on open (200K file and read tail)"
20506
20507 test_271g() {
20508         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20509                 skip "Skipping due to old client or server version"
20510
20511         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20512         # to get layout
20513         $CHECKSTAT -t file $DIR1/$tfile
20514
20515         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20516         MULTIOP_PID=$!
20517         sleep 1
20518         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20519         $LCTL set_param fail_loc=0x80000314
20520         rm $DIR1/$tfile || error "Unlink fails"
20521         RC=$?
20522         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20523         [ $RC -eq 0 ] || error "Failed write to stale object"
20524 }
20525 run_test 271g "Discard DoM data vs client flush race"
20526
20527 test_272a() {
20528         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20529                 skip "Need MDS version at least 2.11.50"
20530
20531         local dom=$DIR/$tdir/dom
20532         mkdir -p $DIR/$tdir
20533
20534         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20535         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20536                 error "failed to write data into $dom"
20537         local old_md5=$(md5sum $dom)
20538
20539         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20540                 error "failed to migrate to the same DoM component"
20541
20542         local new_md5=$(md5sum $dom)
20543
20544         [ "$old_md5" == "$new_md5" ] ||
20545                 error "md5sum differ: $old_md5, $new_md5"
20546
20547         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20548                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20549 }
20550 run_test 272a "DoM migration: new layout with the same DOM component"
20551
20552 test_272b() {
20553         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20554                 skip "Need MDS version at least 2.11.50"
20555
20556         local dom=$DIR/$tdir/dom
20557         mkdir -p $DIR/$tdir
20558         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20559
20560         local mdtidx=$($LFS getstripe -m $dom)
20561         local mdtname=MDT$(printf %04x $mdtidx)
20562         local facet=mds$((mdtidx + 1))
20563
20564         local mdtfree1=$(do_facet $facet \
20565                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20566         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20567                 error "failed to write data into $dom"
20568         local old_md5=$(md5sum $dom)
20569         cancel_lru_locks mdc
20570         local mdtfree1=$(do_facet $facet \
20571                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20572
20573         $LFS migrate -c2 $dom ||
20574                 error "failed to migrate to the new composite layout"
20575         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20576                 error "MDT stripe was not removed"
20577
20578         cancel_lru_locks mdc
20579         local new_md5=$(md5sum $dom)
20580         [ "$old_md5" == "$new_md5" ] ||
20581                 error "$old_md5 != $new_md5"
20582
20583         # Skip free space checks with ZFS
20584         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20585                 local mdtfree2=$(do_facet $facet \
20586                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20587                 [ $mdtfree2 -gt $mdtfree1 ] ||
20588                         error "MDT space is not freed after migration"
20589         fi
20590         return 0
20591 }
20592 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20593
20594 test_272c() {
20595         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20596                 skip "Need MDS version at least 2.11.50"
20597
20598         local dom=$DIR/$tdir/$tfile
20599         mkdir -p $DIR/$tdir
20600         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20601
20602         local mdtidx=$($LFS getstripe -m $dom)
20603         local mdtname=MDT$(printf %04x $mdtidx)
20604         local facet=mds$((mdtidx + 1))
20605
20606         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20607                 error "failed to write data into $dom"
20608         local old_md5=$(md5sum $dom)
20609         cancel_lru_locks mdc
20610         local mdtfree1=$(do_facet $facet \
20611                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20612
20613         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20614                 error "failed to migrate to the new composite layout"
20615         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20616                 error "MDT stripe was not removed"
20617
20618         cancel_lru_locks mdc
20619         local new_md5=$(md5sum $dom)
20620         [ "$old_md5" == "$new_md5" ] ||
20621                 error "$old_md5 != $new_md5"
20622
20623         # Skip free space checks with ZFS
20624         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20625                 local mdtfree2=$(do_facet $facet \
20626                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20627                 [ $mdtfree2 -gt $mdtfree1 ] ||
20628                         error "MDS space is not freed after migration"
20629         fi
20630         return 0
20631 }
20632 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20633
20634 test_272d() {
20635         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20636                 skip "Need MDS version at least 2.12.55"
20637
20638         local dom=$DIR/$tdir/$tfile
20639         mkdir -p $DIR/$tdir
20640         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20641
20642         local mdtidx=$($LFS getstripe -m $dom)
20643         local mdtname=MDT$(printf %04x $mdtidx)
20644         local facet=mds$((mdtidx + 1))
20645
20646         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20647                 error "failed to write data into $dom"
20648         local old_md5=$(md5sum $dom)
20649         cancel_lru_locks mdc
20650         local mdtfree1=$(do_facet $facet \
20651                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20652
20653         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20654                 error "failed mirroring to the new composite layout"
20655         $LFS mirror resync $dom ||
20656                 error "failed mirror resync"
20657         $LFS mirror split --mirror-id 1 -d $dom ||
20658                 error "failed mirror split"
20659
20660         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20661                 error "MDT stripe was not removed"
20662
20663         cancel_lru_locks mdc
20664         local new_md5=$(md5sum $dom)
20665         [ "$old_md5" == "$new_md5" ] ||
20666                 error "$old_md5 != $new_md5"
20667
20668         # Skip free space checks with ZFS
20669         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20670                 local mdtfree2=$(do_facet $facet \
20671                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20672                 [ $mdtfree2 -gt $mdtfree1 ] ||
20673                         error "MDS space is not freed after DOM mirror deletion"
20674         fi
20675         return 0
20676 }
20677 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20678
20679 test_272e() {
20680         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20681                 skip "Need MDS version at least 2.12.55"
20682
20683         local dom=$DIR/$tdir/$tfile
20684         mkdir -p $DIR/$tdir
20685         $LFS setstripe -c 2 $dom
20686
20687         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20688                 error "failed to write data into $dom"
20689         local old_md5=$(md5sum $dom)
20690         cancel_lru_locks mdc
20691
20692         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20693                 error "failed mirroring to the DOM layout"
20694         $LFS mirror resync $dom ||
20695                 error "failed mirror resync"
20696         $LFS mirror split --mirror-id 1 -d $dom ||
20697                 error "failed mirror split"
20698
20699         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20700                 error "MDT stripe was not removed"
20701
20702         cancel_lru_locks mdc
20703         local new_md5=$(md5sum $dom)
20704         [ "$old_md5" == "$new_md5" ] ||
20705                 error "$old_md5 != $new_md5"
20706
20707         return 0
20708 }
20709 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20710
20711 test_272f() {
20712         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20713                 skip "Need MDS version at least 2.12.55"
20714
20715         local dom=$DIR/$tdir/$tfile
20716         mkdir -p $DIR/$tdir
20717         $LFS setstripe -c 2 $dom
20718
20719         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20720                 error "failed to write data into $dom"
20721         local old_md5=$(md5sum $dom)
20722         cancel_lru_locks mdc
20723
20724         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20725                 error "failed migrating to the DOM file"
20726
20727         cancel_lru_locks mdc
20728         local new_md5=$(md5sum $dom)
20729         [ "$old_md5" != "$new_md5" ] &&
20730                 error "$old_md5 != $new_md5"
20731
20732         return 0
20733 }
20734 run_test 272f "DoM migration: OST-striped file to DOM file"
20735
20736 test_273a() {
20737         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20738                 skip "Need MDS version at least 2.11.50"
20739
20740         # Layout swap cannot be done if either file has DOM component,
20741         # this will never be supported, migration should be used instead
20742
20743         local dom=$DIR/$tdir/$tfile
20744         mkdir -p $DIR/$tdir
20745
20746         $LFS setstripe -c2 ${dom}_plain
20747         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20748         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20749                 error "can swap layout with DoM component"
20750         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20751                 error "can swap layout with DoM component"
20752
20753         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20754         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20755                 error "can swap layout with DoM component"
20756         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20757                 error "can swap layout with DoM component"
20758         return 0
20759 }
20760 run_test 273a "DoM: layout swapping should fail with DOM"
20761
20762 test_275() {
20763         remote_ost_nodsh && skip "remote OST with nodsh"
20764         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20765                 skip "Need OST version >= 2.10.57"
20766
20767         local file=$DIR/$tfile
20768         local oss
20769
20770         oss=$(comma_list $(osts_nodes))
20771
20772         dd if=/dev/urandom of=$file bs=1M count=2 ||
20773                 error "failed to create a file"
20774         cancel_lru_locks osc
20775
20776         #lock 1
20777         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20778                 error "failed to read a file"
20779
20780 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20781         $LCTL set_param fail_loc=0x8000031f
20782
20783         cancel_lru_locks osc &
20784         sleep 1
20785
20786 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20787         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20788         #IO takes another lock, but matches the PENDING one
20789         #and places it to the IO RPC
20790         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20791                 error "failed to read a file with PENDING lock"
20792 }
20793 run_test 275 "Read on a canceled duplicate lock"
20794
20795 test_276() {
20796         remote_ost_nodsh && skip "remote OST with nodsh"
20797         local pid
20798
20799         do_facet ost1 "(while true; do \
20800                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20801                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20802         pid=$!
20803
20804         for LOOP in $(seq 20); do
20805                 stop ost1
20806                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20807         done
20808         kill -9 $pid
20809         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20810                 rm $TMP/sanity_276_pid"
20811 }
20812 run_test 276 "Race between mount and obd_statfs"
20813
20814 test_277() {
20815         $LCTL set_param ldlm.namespaces.*.lru_size=0
20816         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20817         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20818                         grep ^used_mb | awk '{print $2}')
20819         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20820         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20821                 oflag=direct conv=notrunc
20822         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20823                         grep ^used_mb | awk '{print $2}')
20824         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20825 }
20826 run_test 277 "Direct IO shall drop page cache"
20827
20828 test_278() {
20829         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20830         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20831         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20832                 skip "needs the same host for mdt1 mdt2" && return
20833
20834         local pid1
20835         local pid2
20836
20837 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20838         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20839         stop mds2 &
20840         pid2=$!
20841
20842         stop mds1
20843
20844         echo "Starting MDTs"
20845         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20846         wait $pid2
20847 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20848 #will return NULL
20849         do_facet mds2 $LCTL set_param fail_loc=0
20850
20851         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20852         wait_recovery_complete mds2
20853 }
20854 run_test 278 "Race starting MDS between MDTs stop/start"
20855
20856 test_280() {
20857         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20858                 skip "Need MGS version at least 2.13.52"
20859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20860         combined_mgs_mds || skip "needs combined MGS/MDT"
20861
20862         umount_client $MOUNT
20863 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20864         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20865
20866         mount_client $MOUNT &
20867         sleep 1
20868         stop mgs || error "stop mgs failed"
20869         #for a race mgs would crash
20870         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20871         mount_client $MOUNT || error "mount client failed"
20872 }
20873 run_test 280 "Race between MGS umount and client llog processing"
20874
20875 cleanup_test_300() {
20876         trap 0
20877         umask $SAVE_UMASK
20878 }
20879 test_striped_dir() {
20880         local mdt_index=$1
20881         local stripe_count
20882         local stripe_index
20883
20884         mkdir -p $DIR/$tdir
20885
20886         SAVE_UMASK=$(umask)
20887         trap cleanup_test_300 RETURN EXIT
20888
20889         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20890                                                 $DIR/$tdir/striped_dir ||
20891                 error "set striped dir error"
20892
20893         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20894         [ "$mode" = "755" ] || error "expect 755 got $mode"
20895
20896         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20897                 error "getdirstripe failed"
20898         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20899         if [ "$stripe_count" != "2" ]; then
20900                 error "1:stripe_count is $stripe_count, expect 2"
20901         fi
20902         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20903         if [ "$stripe_count" != "2" ]; then
20904                 error "2:stripe_count is $stripe_count, expect 2"
20905         fi
20906
20907         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20908         if [ "$stripe_index" != "$mdt_index" ]; then
20909                 error "stripe_index is $stripe_index, expect $mdt_index"
20910         fi
20911
20912         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20913                 error "nlink error after create striped dir"
20914
20915         mkdir $DIR/$tdir/striped_dir/a
20916         mkdir $DIR/$tdir/striped_dir/b
20917
20918         stat $DIR/$tdir/striped_dir/a ||
20919                 error "create dir under striped dir failed"
20920         stat $DIR/$tdir/striped_dir/b ||
20921                 error "create dir under striped dir failed"
20922
20923         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20924                 error "nlink error after mkdir"
20925
20926         rmdir $DIR/$tdir/striped_dir/a
20927         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20928                 error "nlink error after rmdir"
20929
20930         rmdir $DIR/$tdir/striped_dir/b
20931         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20932                 error "nlink error after rmdir"
20933
20934         chattr +i $DIR/$tdir/striped_dir
20935         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20936                 error "immutable flags not working under striped dir!"
20937         chattr -i $DIR/$tdir/striped_dir
20938
20939         rmdir $DIR/$tdir/striped_dir ||
20940                 error "rmdir striped dir error"
20941
20942         cleanup_test_300
20943
20944         true
20945 }
20946
20947 test_300a() {
20948         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20949                 skip "skipped for lustre < 2.7.0"
20950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20952
20953         test_striped_dir 0 || error "failed on striped dir on MDT0"
20954         test_striped_dir 1 || error "failed on striped dir on MDT0"
20955 }
20956 run_test 300a "basic striped dir sanity test"
20957
20958 test_300b() {
20959         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20960                 skip "skipped for lustre < 2.7.0"
20961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20962         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20963
20964         local i
20965         local mtime1
20966         local mtime2
20967         local mtime3
20968
20969         test_mkdir $DIR/$tdir || error "mkdir fail"
20970         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20971                 error "set striped dir error"
20972         for i in {0..9}; do
20973                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20974                 sleep 1
20975                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20976                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20977                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20978                 sleep 1
20979                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20980                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20981                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20982         done
20983         true
20984 }
20985 run_test 300b "check ctime/mtime for striped dir"
20986
20987 test_300c() {
20988         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20989                 skip "skipped for lustre < 2.7.0"
20990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20992
20993         local file_count
20994
20995         mkdir -p $DIR/$tdir
20996         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20997                 error "set striped dir error"
20998
20999         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21000                 error "chown striped dir failed"
21001
21002         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21003                 error "create 5k files failed"
21004
21005         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21006
21007         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21008
21009         rm -rf $DIR/$tdir
21010 }
21011 run_test 300c "chown && check ls under striped directory"
21012
21013 test_300d() {
21014         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21015                 skip "skipped for lustre < 2.7.0"
21016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21018
21019         local stripe_count
21020         local file
21021
21022         mkdir -p $DIR/$tdir
21023         $LFS setstripe -c 2 $DIR/$tdir
21024
21025         #local striped directory
21026         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21027                 error "set striped dir error"
21028         #look at the directories for debug purposes
21029         ls -l $DIR/$tdir
21030         $LFS getdirstripe $DIR/$tdir
21031         ls -l $DIR/$tdir/striped_dir
21032         $LFS getdirstripe $DIR/$tdir/striped_dir
21033         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21034                 error "create 10 files failed"
21035
21036         #remote striped directory
21037         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21038                 error "set striped dir error"
21039         #look at the directories for debug purposes
21040         ls -l $DIR/$tdir
21041         $LFS getdirstripe $DIR/$tdir
21042         ls -l $DIR/$tdir/remote_striped_dir
21043         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21044         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21045                 error "create 10 files failed"
21046
21047         for file in $(find $DIR/$tdir); do
21048                 stripe_count=$($LFS getstripe -c $file)
21049                 [ $stripe_count -eq 2 ] ||
21050                         error "wrong stripe $stripe_count for $file"
21051         done
21052
21053         rm -rf $DIR/$tdir
21054 }
21055 run_test 300d "check default stripe under striped directory"
21056
21057 test_300e() {
21058         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21059                 skip "Need MDS version at least 2.7.55"
21060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21062
21063         local stripe_count
21064         local file
21065
21066         mkdir -p $DIR/$tdir
21067
21068         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21069                 error "set striped dir error"
21070
21071         touch $DIR/$tdir/striped_dir/a
21072         touch $DIR/$tdir/striped_dir/b
21073         touch $DIR/$tdir/striped_dir/c
21074
21075         mkdir $DIR/$tdir/striped_dir/dir_a
21076         mkdir $DIR/$tdir/striped_dir/dir_b
21077         mkdir $DIR/$tdir/striped_dir/dir_c
21078
21079         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21080                 error "set striped adir under striped dir error"
21081
21082         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21083                 error "set striped bdir under striped dir error"
21084
21085         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21086                 error "set striped cdir under striped dir error"
21087
21088         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21089                 error "rename dir under striped dir fails"
21090
21091         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21092                 error "rename dir under different stripes fails"
21093
21094         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21095                 error "rename file under striped dir should succeed"
21096
21097         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21098                 error "rename dir under striped dir should succeed"
21099
21100         rm -rf $DIR/$tdir
21101 }
21102 run_test 300e "check rename under striped directory"
21103
21104 test_300f() {
21105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21106         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21107         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21108                 skip "Need MDS version at least 2.7.55"
21109
21110         local stripe_count
21111         local file
21112
21113         rm -rf $DIR/$tdir
21114         mkdir -p $DIR/$tdir
21115
21116         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21117                 error "set striped dir error"
21118
21119         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21120                 error "set striped dir error"
21121
21122         touch $DIR/$tdir/striped_dir/a
21123         mkdir $DIR/$tdir/striped_dir/dir_a
21124         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21125                 error "create striped dir under striped dir fails"
21126
21127         touch $DIR/$tdir/striped_dir1/b
21128         mkdir $DIR/$tdir/striped_dir1/dir_b
21129         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21130                 error "create striped dir under striped dir fails"
21131
21132         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21133                 error "rename dir under different striped dir should fail"
21134
21135         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21136                 error "rename striped dir under diff striped dir should fail"
21137
21138         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21139                 error "rename file under diff striped dirs fails"
21140
21141         rm -rf $DIR/$tdir
21142 }
21143 run_test 300f "check rename cross striped directory"
21144
21145 test_300_check_default_striped_dir()
21146 {
21147         local dirname=$1
21148         local default_count=$2
21149         local default_index=$3
21150         local stripe_count
21151         local stripe_index
21152         local dir_stripe_index
21153         local dir
21154
21155         echo "checking $dirname $default_count $default_index"
21156         $LFS setdirstripe -D -c $default_count -i $default_index \
21157                                 -t all_char $DIR/$tdir/$dirname ||
21158                 error "set default stripe on striped dir error"
21159         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21160         [ $stripe_count -eq $default_count ] ||
21161                 error "expect $default_count get $stripe_count for $dirname"
21162
21163         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21164         [ $stripe_index -eq $default_index ] ||
21165                 error "expect $default_index get $stripe_index for $dirname"
21166
21167         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21168                                                 error "create dirs failed"
21169
21170         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21171         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21172         for dir in $(find $DIR/$tdir/$dirname/*); do
21173                 stripe_count=$($LFS getdirstripe -c $dir)
21174                 [ $stripe_count -eq $default_count ] ||
21175                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21176                 error "stripe count $default_count != $stripe_count for $dir"
21177
21178                 stripe_index=$($LFS getdirstripe -i $dir)
21179                 [ $default_index -eq -1 ] ||
21180                         [ $stripe_index -eq $default_index ] ||
21181                         error "$stripe_index != $default_index for $dir"
21182
21183                 #check default stripe
21184                 stripe_count=$($LFS getdirstripe -D -c $dir)
21185                 [ $stripe_count -eq $default_count ] ||
21186                 error "default count $default_count != $stripe_count for $dir"
21187
21188                 stripe_index=$($LFS getdirstripe -D -i $dir)
21189                 [ $stripe_index -eq $default_index ] ||
21190                 error "default index $default_index != $stripe_index for $dir"
21191         done
21192         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21193 }
21194
21195 test_300g() {
21196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21197         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21198                 skip "Need MDS version at least 2.7.55"
21199
21200         local dir
21201         local stripe_count
21202         local stripe_index
21203
21204         mkdir $DIR/$tdir
21205         mkdir $DIR/$tdir/normal_dir
21206
21207         #Checking when client cache stripe index
21208         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21209         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21210                 error "create striped_dir failed"
21211
21212         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21213                 error "create dir0 fails"
21214         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21215         [ $stripe_index -eq 0 ] ||
21216                 error "dir0 expect index 0 got $stripe_index"
21217
21218         mkdir $DIR/$tdir/striped_dir/dir1 ||
21219                 error "create dir1 fails"
21220         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21221         [ $stripe_index -eq 1 ] ||
21222                 error "dir1 expect index 1 got $stripe_index"
21223
21224         #check default stripe count/stripe index
21225         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21226         test_300_check_default_striped_dir normal_dir 1 0
21227         test_300_check_default_striped_dir normal_dir 2 1
21228         test_300_check_default_striped_dir normal_dir 2 -1
21229
21230         #delete default stripe information
21231         echo "delete default stripeEA"
21232         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21233                 error "set default stripe on striped dir error"
21234
21235         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21236         for dir in $(find $DIR/$tdir/normal_dir/*); do
21237                 stripe_count=$($LFS getdirstripe -c $dir)
21238                 [ $stripe_count -eq 0 ] ||
21239                         error "expect 1 get $stripe_count for $dir"
21240                 stripe_index=$($LFS getdirstripe -i $dir)
21241                 [ $stripe_index -eq 0 ] ||
21242                         error "expect 0 get $stripe_index for $dir"
21243         done
21244 }
21245 run_test 300g "check default striped directory for normal directory"
21246
21247 test_300h() {
21248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21249         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21250                 skip "Need MDS version at least 2.7.55"
21251
21252         local dir
21253         local stripe_count
21254
21255         mkdir $DIR/$tdir
21256         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21257                 error "set striped dir error"
21258
21259         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21260         test_300_check_default_striped_dir striped_dir 1 0
21261         test_300_check_default_striped_dir striped_dir 2 1
21262         test_300_check_default_striped_dir striped_dir 2 -1
21263
21264         #delete default stripe information
21265         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21266                 error "set default stripe on striped dir error"
21267
21268         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21269         for dir in $(find $DIR/$tdir/striped_dir/*); do
21270                 stripe_count=$($LFS getdirstripe -c $dir)
21271                 [ $stripe_count -eq 0 ] ||
21272                         error "expect 1 get $stripe_count for $dir"
21273         done
21274 }
21275 run_test 300h "check default striped directory for striped directory"
21276
21277 test_300i() {
21278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21280         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21281                 skip "Need MDS version at least 2.7.55"
21282
21283         local stripe_count
21284         local file
21285
21286         mkdir $DIR/$tdir
21287
21288         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21289                 error "set striped dir error"
21290
21291         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21292                 error "create files under striped dir failed"
21293
21294         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21295                 error "set striped hashdir error"
21296
21297         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21298                 error "create dir0 under hash dir failed"
21299         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21300                 error "create dir1 under hash dir failed"
21301
21302         # unfortunately, we need to umount to clear dir layout cache for now
21303         # once we fully implement dir layout, we can drop this
21304         umount_client $MOUNT || error "umount failed"
21305         mount_client $MOUNT || error "mount failed"
21306
21307         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21308         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21309         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21310
21311         #set the stripe to be unknown hash type
21312         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21313         $LCTL set_param fail_loc=0x1901
21314         for ((i = 0; i < 10; i++)); do
21315                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21316                         error "stat f-$i failed"
21317                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21318         done
21319
21320         touch $DIR/$tdir/striped_dir/f0 &&
21321                 error "create under striped dir with unknown hash should fail"
21322
21323         $LCTL set_param fail_loc=0
21324
21325         umount_client $MOUNT || error "umount failed"
21326         mount_client $MOUNT || error "mount failed"
21327
21328         return 0
21329 }
21330 run_test 300i "client handle unknown hash type striped directory"
21331
21332 test_300j() {
21333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21335         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21336                 skip "Need MDS version at least 2.7.55"
21337
21338         local stripe_count
21339         local file
21340
21341         mkdir $DIR/$tdir
21342
21343         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21344         $LCTL set_param fail_loc=0x1702
21345         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21346                 error "set striped dir error"
21347
21348         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21349                 error "create files under striped dir failed"
21350
21351         $LCTL set_param fail_loc=0
21352
21353         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21354
21355         return 0
21356 }
21357 run_test 300j "test large update record"
21358
21359 test_300k() {
21360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21362         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21363                 skip "Need MDS version at least 2.7.55"
21364
21365         # this test needs a huge transaction
21366         local kb
21367         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21368              osd*.$FSNAME-MDT0000.kbytestotal")
21369         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21370
21371         local stripe_count
21372         local file
21373
21374         mkdir $DIR/$tdir
21375
21376         #define OBD_FAIL_LARGE_STRIPE   0x1703
21377         $LCTL set_param fail_loc=0x1703
21378         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21379                 error "set striped dir error"
21380         $LCTL set_param fail_loc=0
21381
21382         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21383                 error "getstripeddir fails"
21384         rm -rf $DIR/$tdir/striped_dir ||
21385                 error "unlink striped dir fails"
21386
21387         return 0
21388 }
21389 run_test 300k "test large striped directory"
21390
21391 test_300l() {
21392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21393         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21394         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21395                 skip "Need MDS version at least 2.7.55"
21396
21397         local stripe_index
21398
21399         test_mkdir -p $DIR/$tdir/striped_dir
21400         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21401                         error "chown $RUNAS_ID failed"
21402         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21403                 error "set default striped dir failed"
21404
21405         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21406         $LCTL set_param fail_loc=0x80000158
21407         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21408
21409         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21410         [ $stripe_index -eq 1 ] ||
21411                 error "expect 1 get $stripe_index for $dir"
21412 }
21413 run_test 300l "non-root user to create dir under striped dir with stale layout"
21414
21415 test_300m() {
21416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21417         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21418         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21419                 skip "Need MDS version at least 2.7.55"
21420
21421         mkdir -p $DIR/$tdir/striped_dir
21422         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21423                 error "set default stripes dir error"
21424
21425         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21426
21427         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21428         [ $stripe_count -eq 0 ] ||
21429                         error "expect 0 get $stripe_count for a"
21430
21431         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21432                 error "set default stripes dir error"
21433
21434         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21435
21436         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21437         [ $stripe_count -eq 0 ] ||
21438                         error "expect 0 get $stripe_count for b"
21439
21440         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21441                 error "set default stripes dir error"
21442
21443         mkdir $DIR/$tdir/striped_dir/c &&
21444                 error "default stripe_index is invalid, mkdir c should fails"
21445
21446         rm -rf $DIR/$tdir || error "rmdir fails"
21447 }
21448 run_test 300m "setstriped directory on single MDT FS"
21449
21450 cleanup_300n() {
21451         local list=$(comma_list $(mdts_nodes))
21452
21453         trap 0
21454         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21455 }
21456
21457 test_300n() {
21458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21460         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21461                 skip "Need MDS version at least 2.7.55"
21462         remote_mds_nodsh && skip "remote MDS with nodsh"
21463
21464         local stripe_index
21465         local list=$(comma_list $(mdts_nodes))
21466
21467         trap cleanup_300n RETURN EXIT
21468         mkdir -p $DIR/$tdir
21469         chmod 777 $DIR/$tdir
21470         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21471                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21472                 error "create striped dir succeeds with gid=0"
21473
21474         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21475         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21476                 error "create striped dir fails with gid=-1"
21477
21478         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21479         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21480                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21481                 error "set default striped dir succeeds with gid=0"
21482
21483
21484         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21485         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21486                 error "set default striped dir fails with gid=-1"
21487
21488
21489         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21490         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21491                                         error "create test_dir fails"
21492         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21493                                         error "create test_dir1 fails"
21494         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21495                                         error "create test_dir2 fails"
21496         cleanup_300n
21497 }
21498 run_test 300n "non-root user to create dir under striped dir with default EA"
21499
21500 test_300o() {
21501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21503         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21504                 skip "Need MDS version at least 2.7.55"
21505
21506         local numfree1
21507         local numfree2
21508
21509         mkdir -p $DIR/$tdir
21510
21511         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21512         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21513         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21514                 skip "not enough free inodes $numfree1 $numfree2"
21515         fi
21516
21517         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21518         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21519         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21520                 skip "not enough free space $numfree1 $numfree2"
21521         fi
21522
21523         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21524                 error "setdirstripe fails"
21525
21526         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21527                 error "create dirs fails"
21528
21529         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21530         ls $DIR/$tdir/striped_dir > /dev/null ||
21531                 error "ls striped dir fails"
21532         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21533                 error "unlink big striped dir fails"
21534 }
21535 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21536
21537 test_300p() {
21538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21539         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21540         remote_mds_nodsh && skip "remote MDS with nodsh"
21541
21542         mkdir -p $DIR/$tdir
21543
21544         #define OBD_FAIL_OUT_ENOSPC     0x1704
21545         do_facet mds2 lctl set_param fail_loc=0x80001704
21546         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21547                  && error "create striped directory should fail"
21548
21549         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21550
21551         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21552         true
21553 }
21554 run_test 300p "create striped directory without space"
21555
21556 test_300q() {
21557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21559
21560         local fd=$(free_fd)
21561         local cmd="exec $fd<$tdir"
21562         cd $DIR
21563         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21564         eval $cmd
21565         cmd="exec $fd<&-"
21566         trap "eval $cmd" EXIT
21567         cd $tdir || error "cd $tdir fails"
21568         rmdir  ../$tdir || error "rmdir $tdir fails"
21569         mkdir local_dir && error "create dir succeeds"
21570         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21571         eval $cmd
21572         return 0
21573 }
21574 run_test 300q "create remote directory under orphan directory"
21575
21576 test_300r() {
21577         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21578                 skip "Need MDS version at least 2.7.55" && return
21579         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21580
21581         mkdir $DIR/$tdir
21582
21583         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21584                 error "set striped dir error"
21585
21586         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21587                 error "getstripeddir fails"
21588
21589         local stripe_count
21590         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21591                       awk '/lmv_stripe_count:/ { print $2 }')
21592
21593         [ $MDSCOUNT -ne $stripe_count ] &&
21594                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21595
21596         rm -rf $DIR/$tdir/striped_dir ||
21597                 error "unlink striped dir fails"
21598 }
21599 run_test 300r "test -1 striped directory"
21600
21601 prepare_remote_file() {
21602         mkdir $DIR/$tdir/src_dir ||
21603                 error "create remote source failed"
21604
21605         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21606                  error "cp to remote source failed"
21607         touch $DIR/$tdir/src_dir/a
21608
21609         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21610                 error "create remote target dir failed"
21611
21612         touch $DIR/$tdir/tgt_dir/b
21613
21614         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21615                 error "rename dir cross MDT failed!"
21616
21617         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21618                 error "src_child still exists after rename"
21619
21620         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21621                 error "missing file(a) after rename"
21622
21623         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21624                 error "diff after rename"
21625 }
21626
21627 test_310a() {
21628         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21630
21631         local remote_file=$DIR/$tdir/tgt_dir/b
21632
21633         mkdir -p $DIR/$tdir
21634
21635         prepare_remote_file || error "prepare remote file failed"
21636
21637         #open-unlink file
21638         $OPENUNLINK $remote_file $remote_file ||
21639                 error "openunlink $remote_file failed"
21640         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21641 }
21642 run_test 310a "open unlink remote file"
21643
21644 test_310b() {
21645         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21647
21648         local remote_file=$DIR/$tdir/tgt_dir/b
21649
21650         mkdir -p $DIR/$tdir
21651
21652         prepare_remote_file || error "prepare remote file failed"
21653
21654         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21655         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21656         $CHECKSTAT -t file $remote_file || error "check file failed"
21657 }
21658 run_test 310b "unlink remote file with multiple links while open"
21659
21660 test_310c() {
21661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21662         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21663
21664         local remote_file=$DIR/$tdir/tgt_dir/b
21665
21666         mkdir -p $DIR/$tdir
21667
21668         prepare_remote_file || error "prepare remote file failed"
21669
21670         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21671         multiop_bg_pause $remote_file O_uc ||
21672                         error "mulitop failed for remote file"
21673         MULTIPID=$!
21674         $MULTIOP $DIR/$tfile Ouc
21675         kill -USR1 $MULTIPID
21676         wait $MULTIPID
21677 }
21678 run_test 310c "open-unlink remote file with multiple links"
21679
21680 #LU-4825
21681 test_311() {
21682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21683         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21684         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21685                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21686         remote_mds_nodsh && skip "remote MDS with nodsh"
21687
21688         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21689         local mdts=$(comma_list $(mdts_nodes))
21690
21691         mkdir -p $DIR/$tdir
21692         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21693         createmany -o $DIR/$tdir/$tfile. 1000
21694
21695         # statfs data is not real time, let's just calculate it
21696         old_iused=$((old_iused + 1000))
21697
21698         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21699                         osp.*OST0000*MDT0000.create_count")
21700         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21701                                 osp.*OST0000*MDT0000.max_create_count")
21702         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21703
21704         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21705         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21706         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21707
21708         unlinkmany $DIR/$tdir/$tfile. 1000
21709
21710         do_nodes $mdts "$LCTL set_param -n \
21711                         osp.*OST0000*.max_create_count=$max_count"
21712         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21713                 do_nodes $mdts "$LCTL set_param -n \
21714                                 osp.*OST0000*.create_count=$count"
21715         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21716                         grep "=0" && error "create_count is zero"
21717
21718         local new_iused
21719         for i in $(seq 120); do
21720                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21721                 # system may be too busy to destroy all objs in time, use
21722                 # a somewhat small value to not fail autotest
21723                 [ $((old_iused - new_iused)) -gt 400 ] && break
21724                 sleep 1
21725         done
21726
21727         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21728         [ $((old_iused - new_iused)) -gt 400 ] ||
21729                 error "objs not destroyed after unlink"
21730 }
21731 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21732
21733 zfs_oid_to_objid()
21734 {
21735         local ost=$1
21736         local objid=$2
21737
21738         local vdevdir=$(dirname $(facet_vdevice $ost))
21739         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21740         local zfs_zapid=$(do_facet $ost $cmd |
21741                           grep -w "/O/0/d$((objid%32))" -C 5 |
21742                           awk '/Object/{getline; print $1}')
21743         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21744                           awk "/$objid = /"'{printf $3}')
21745
21746         echo $zfs_objid
21747 }
21748
21749 zfs_object_blksz() {
21750         local ost=$1
21751         local objid=$2
21752
21753         local vdevdir=$(dirname $(facet_vdevice $ost))
21754         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21755         local blksz=$(do_facet $ost $cmd $objid |
21756                       awk '/dblk/{getline; printf $4}')
21757
21758         case "${blksz: -1}" in
21759                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21760                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21761                 *) ;;
21762         esac
21763
21764         echo $blksz
21765 }
21766
21767 test_312() { # LU-4856
21768         remote_ost_nodsh && skip "remote OST with nodsh"
21769         [ "$ost1_FSTYPE" = "zfs" ] ||
21770                 skip_env "the test only applies to zfs"
21771
21772         local max_blksz=$(do_facet ost1 \
21773                           $ZFS get -p recordsize $(facet_device ost1) |
21774                           awk '!/VALUE/{print $3}')
21775
21776         # to make life a little bit easier
21777         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21778         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21779
21780         local tf=$DIR/$tdir/$tfile
21781         touch $tf
21782         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21783
21784         # Get ZFS object id
21785         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21786         # block size change by sequential overwrite
21787         local bs
21788
21789         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21790                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21791
21792                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21793                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21794         done
21795         rm -f $tf
21796
21797         # block size change by sequential append write
21798         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21799         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21800         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21801         local count
21802
21803         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21804                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21805                         oflag=sync conv=notrunc
21806
21807                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21808                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21809                         error "blksz error, actual $blksz, " \
21810                                 "expected: 2 * $count * $PAGE_SIZE"
21811         done
21812         rm -f $tf
21813
21814         # random write
21815         touch $tf
21816         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21817         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21818
21819         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21820         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21821         [ $blksz -eq $PAGE_SIZE ] ||
21822                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21823
21824         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21825         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21826         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21827
21828         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21829         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21830         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21831 }
21832 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21833
21834 test_313() {
21835         remote_ost_nodsh && skip "remote OST with nodsh"
21836
21837         local file=$DIR/$tfile
21838
21839         rm -f $file
21840         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21841
21842         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21843         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21844         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21845                 error "write should failed"
21846         do_facet ost1 "$LCTL set_param fail_loc=0"
21847         rm -f $file
21848 }
21849 run_test 313 "io should fail after last_rcvd update fail"
21850
21851 test_314() {
21852         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21853
21854         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21855         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21856         rm -f $DIR/$tfile
21857         wait_delete_completed
21858         do_facet ost1 "$LCTL set_param fail_loc=0"
21859 }
21860 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21861
21862 test_315() { # LU-618
21863         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21864
21865         local file=$DIR/$tfile
21866         rm -f $file
21867
21868         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21869                 error "multiop file write failed"
21870         $MULTIOP $file oO_RDONLY:r4063232_c &
21871         PID=$!
21872
21873         sleep 2
21874
21875         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21876         kill -USR1 $PID
21877
21878         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21879         rm -f $file
21880 }
21881 run_test 315 "read should be accounted"
21882
21883 test_316() {
21884         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21885         large_xattr_enabled || skip_env "ea_inode feature disabled"
21886
21887         rm -rf $DIR/$tdir/d
21888         mkdir -p $DIR/$tdir/d
21889         chown nobody $DIR/$tdir/d
21890         touch $DIR/$tdir/d/file
21891
21892         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21893 }
21894 run_test 316 "lfs mv"
21895
21896 test_317() {
21897         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21898                 skip "Need MDS version at least 2.11.53"
21899         if [ "$ost1_FSTYPE" == "zfs" ]; then
21900                 skip "LU-10370: no implementation for ZFS"
21901         fi
21902
21903         local trunc_sz
21904         local grant_blk_size
21905
21906         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21907                         awk '/grant_block_size:/ { print $2; exit; }')
21908         #
21909         # Create File of size 5M. Truncate it to below size's and verify
21910         # blocks count.
21911         #
21912         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21913                 error "Create file $DIR/$tfile failed"
21914         stack_trap "rm -f $DIR/$tfile" EXIT
21915
21916         for trunc_sz in 2097152 4097 4000 509 0; do
21917                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21918                         error "truncate $tfile to $trunc_sz failed"
21919                 local sz=$(stat --format=%s $DIR/$tfile)
21920                 local blk=$(stat --format=%b $DIR/$tfile)
21921                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21922                                      grant_blk_size) * 8))
21923
21924                 if [[ $blk -ne $trunc_blk ]]; then
21925                         $(which stat) $DIR/$tfile
21926                         error "Expected Block $trunc_blk got $blk for $tfile"
21927                 fi
21928
21929                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21930                         error "Expected Size $trunc_sz got $sz for $tfile"
21931         done
21932
21933         #
21934         # sparse file test
21935         # Create file with a hole and write actual two blocks. Block count
21936         # must be 16.
21937         #
21938         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21939                 conv=fsync || error "Create file : $DIR/$tfile"
21940
21941         # Calculate the final truncate size.
21942         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21943
21944         #
21945         # truncate to size $trunc_sz bytes. Strip the last block
21946         # The block count must drop to 8
21947         #
21948         $TRUNCATE $DIR/$tfile $trunc_sz ||
21949                 error "truncate $tfile to $trunc_sz failed"
21950
21951         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21952         sz=$(stat --format=%s $DIR/$tfile)
21953         blk=$(stat --format=%b $DIR/$tfile)
21954
21955         if [[ $blk -ne $trunc_bsz ]]; then
21956                 $(which stat) $DIR/$tfile
21957                 error "Expected Block $trunc_bsz got $blk for $tfile"
21958         fi
21959
21960         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21961                 error "Expected Size $trunc_sz got $sz for $tfile"
21962 }
21963 run_test 317 "Verify blocks get correctly update after truncate"
21964
21965 test_318() {
21966         local old_max_active=$($LCTL get_param -n \
21967                             llite.*.max_read_ahead_async_active 2>/dev/null)
21968
21969         $LCTL set_param llite.*.max_read_ahead_async_active=256
21970         local max_active=$($LCTL get_param -n \
21971                            llite.*.max_read_ahead_async_active 2>/dev/null)
21972         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21973
21974         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21975                 error "set max_read_ahead_async_active should succeed"
21976
21977         $LCTL set_param llite.*.max_read_ahead_async_active=512
21978         max_active=$($LCTL get_param -n \
21979                      llite.*.max_read_ahead_async_active 2>/dev/null)
21980         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21981
21982         # restore @max_active
21983         [ $old_max_active -ne 0 ] && $LCTL set_param \
21984                 llite.*.max_read_ahead_async_active=$old_max_active
21985
21986         local old_threshold=$($LCTL get_param -n \
21987                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21988         local max_per_file_mb=$($LCTL get_param -n \
21989                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21990
21991         local invalid=$(($max_per_file_mb + 1))
21992         $LCTL set_param \
21993                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21994                         && error "set $invalid should fail"
21995
21996         local valid=$(($invalid - 1))
21997         $LCTL set_param \
21998                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21999                         error "set $valid should succeed"
22000         local threshold=$($LCTL get_param -n \
22001                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22002         [ $threshold -eq $valid ] || error \
22003                 "expect threshold $valid got $threshold"
22004         $LCTL set_param \
22005                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22006 }
22007 run_test 318 "Verify async readahead tunables"
22008
22009 test_319() {
22010         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22011
22012         local before=$(date +%s)
22013         local evict
22014         local mdir=$DIR/$tdir
22015         local file=$mdir/xxx
22016
22017         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22018         touch $file
22019
22020 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22021         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22022         $LFS mv -m1 $file &
22023
22024         sleep 1
22025         dd if=$file of=/dev/null
22026         wait
22027         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22028           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22029
22030         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22031 }
22032 run_test 319 "lost lease lock on migrate error"
22033
22034 test_398a() { # LU-4198
22035         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22036         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22037
22038         # request a new lock on client
22039         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22040
22041         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22042         local lock_count=$($LCTL get_param -n \
22043                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22044         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22045
22046         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22047
22048         # no lock cached, should use lockless IO and not enqueue new lock
22049         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22050         lock_count=$($LCTL get_param -n \
22051                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22052         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22053 }
22054 run_test 398a "direct IO should cancel lock otherwise lockless"
22055
22056 test_398b() { # LU-4198
22057         which fio || skip_env "no fio installed"
22058         $LFS setstripe -c -1 $DIR/$tfile
22059
22060         local size=12
22061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22062
22063         local njobs=4
22064         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22065         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22066                 --numjobs=$njobs --fallocate=none \
22067                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22068                 --filename=$DIR/$tfile &
22069         bg_pid=$!
22070
22071         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22072         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22073                 --numjobs=$njobs --fallocate=none \
22074                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22075                 --filename=$DIR/$tfile || true
22076         wait $bg_pid
22077
22078         rm -rf $DIR/$tfile
22079 }
22080 run_test 398b "DIO and buffer IO race"
22081
22082 test_398c() { # LU-4198
22083         which fio || skip_env "no fio installed"
22084
22085         saved_debug=$($LCTL get_param -n debug)
22086         $LCTL set_param debug=0
22087
22088         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22089         ((size /= 1024)) # by megabytes
22090         ((size /= 2)) # write half of the OST at most
22091         [ $size -gt 40 ] && size=40 #reduce test time anyway
22092
22093         $LFS setstripe -c 1 $DIR/$tfile
22094
22095         # it seems like ldiskfs reserves more space than necessary if the
22096         # writing blocks are not mapped, so it extends the file firstly
22097         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22098         cancel_lru_locks osc
22099
22100         # clear and verify rpc_stats later
22101         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22102
22103         local njobs=4
22104         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22105         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22106                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22107                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22108                 --filename=$DIR/$tfile
22109         [ $? -eq 0 ] || error "fio write error"
22110
22111         [ $($LCTL get_param -n \
22112          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22113                 error "Locks were requested while doing AIO"
22114
22115         # get the percentage of 1-page I/O
22116         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22117                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22118                 awk '{print $7}')
22119         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22120
22121         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22122         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22123                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22124                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22125                 --filename=$DIR/$tfile
22126         [ $? -eq 0 ] || error "fio mixed read write error"
22127
22128         echo "AIO with large block size ${size}M"
22129         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22130                 --numjobs=1 --fallocate=none --ioengine=libaio \
22131                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22132                 --filename=$DIR/$tfile
22133         [ $? -eq 0 ] || error "fio large block size failed"
22134
22135         rm -rf $DIR/$tfile
22136         $LCTL set_param debug="$saved_debug"
22137 }
22138 run_test 398c "run fio to test AIO"
22139
22140 test_398d() { #  LU-13846
22141         test -f aiocp || skip_env "no aiocp installed"
22142         local aio_file=$DIR/aio_file
22143
22144         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22145
22146         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22147         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22148
22149         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22150
22151         # make sure we don't crash and fail properly
22152         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22153                 error "aio not aligned with PAGE SIZE should fail"
22154
22155         rm -rf $DIR/$tfile $aio_file
22156 }
22157 run_test 398d "run aiocp to verify block size > stripe size"
22158
22159 test_fake_rw() {
22160         local read_write=$1
22161         if [ "$read_write" = "write" ]; then
22162                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22163         elif [ "$read_write" = "read" ]; then
22164                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22165         else
22166                 error "argument error"
22167         fi
22168
22169         # turn off debug for performance testing
22170         local saved_debug=$($LCTL get_param -n debug)
22171         $LCTL set_param debug=0
22172
22173         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22174
22175         # get ost1 size - $FSNAME-OST0000
22176         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22177         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22178         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22179
22180         if [ "$read_write" = "read" ]; then
22181                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22182         fi
22183
22184         local start_time=$(date +%s.%N)
22185         $dd_cmd bs=1M count=$blocks oflag=sync ||
22186                 error "real dd $read_write error"
22187         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22188
22189         if [ "$read_write" = "write" ]; then
22190                 rm -f $DIR/$tfile
22191         fi
22192
22193         # define OBD_FAIL_OST_FAKE_RW           0x238
22194         do_facet ost1 $LCTL set_param fail_loc=0x238
22195
22196         local start_time=$(date +%s.%N)
22197         $dd_cmd bs=1M count=$blocks oflag=sync ||
22198                 error "fake dd $read_write error"
22199         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22200
22201         if [ "$read_write" = "write" ]; then
22202                 # verify file size
22203                 cancel_lru_locks osc
22204                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22205                         error "$tfile size not $blocks MB"
22206         fi
22207         do_facet ost1 $LCTL set_param fail_loc=0
22208
22209         echo "fake $read_write $duration_fake vs. normal $read_write" \
22210                 "$duration in seconds"
22211         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22212                 error_not_in_vm "fake write is slower"
22213
22214         $LCTL set_param -n debug="$saved_debug"
22215         rm -f $DIR/$tfile
22216 }
22217 test_399a() { # LU-7655 for OST fake write
22218         remote_ost_nodsh && skip "remote OST with nodsh"
22219
22220         test_fake_rw write
22221 }
22222 run_test 399a "fake write should not be slower than normal write"
22223
22224 test_399b() { # LU-8726 for OST fake read
22225         remote_ost_nodsh && skip "remote OST with nodsh"
22226         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22227                 skip_env "ldiskfs only test"
22228         fi
22229
22230         test_fake_rw read
22231 }
22232 run_test 399b "fake read should not be slower than normal read"
22233
22234 test_400a() { # LU-1606, was conf-sanity test_74
22235         if ! which $CC > /dev/null 2>&1; then
22236                 skip_env "$CC is not installed"
22237         fi
22238
22239         local extra_flags=''
22240         local out=$TMP/$tfile
22241         local prefix=/usr/include/lustre
22242         local prog
22243
22244         # Oleg removes c files in his test rig so test if any c files exist
22245         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22246                 skip_env "Needed c test files are missing"
22247
22248         if ! [[ -d $prefix ]]; then
22249                 # Assume we're running in tree and fixup the include path.
22250                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22251                 extra_flags+=" -L$LUSTRE/utils/.lib"
22252         fi
22253
22254         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22255                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22256                         error "client api broken"
22257         done
22258         rm -f $out
22259 }
22260 run_test 400a "Lustre client api program can compile and link"
22261
22262 test_400b() { # LU-1606, LU-5011
22263         local header
22264         local out=$TMP/$tfile
22265         local prefix=/usr/include/linux/lustre
22266
22267         # We use a hard coded prefix so that this test will not fail
22268         # when run in tree. There are headers in lustre/include/lustre/
22269         # that are not packaged (like lustre_idl.h) and have more
22270         # complicated include dependencies (like config.h and lnet/types.h).
22271         # Since this test about correct packaging we just skip them when
22272         # they don't exist (see below) rather than try to fixup cppflags.
22273
22274         if ! which $CC > /dev/null 2>&1; then
22275                 skip_env "$CC is not installed"
22276         fi
22277
22278         for header in $prefix/*.h; do
22279                 if ! [[ -f "$header" ]]; then
22280                         continue
22281                 fi
22282
22283                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22284                         continue # lustre_ioctl.h is internal header
22285                 fi
22286
22287                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22288                         error "cannot compile '$header'"
22289         done
22290         rm -f $out
22291 }
22292 run_test 400b "packaged headers can be compiled"
22293
22294 test_401a() { #LU-7437
22295         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22296         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22297
22298         #count the number of parameters by "list_param -R"
22299         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22300         #count the number of parameters by listing proc files
22301         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22302         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22303         echo "proc_dirs='$proc_dirs'"
22304         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22305         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22306                       sort -u | wc -l)
22307
22308         [ $params -eq $procs ] ||
22309                 error "found $params parameters vs. $procs proc files"
22310
22311         # test the list_param -D option only returns directories
22312         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22313         #count the number of parameters by listing proc directories
22314         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22315                 sort -u | wc -l)
22316
22317         [ $params -eq $procs ] ||
22318                 error "found $params parameters vs. $procs proc files"
22319 }
22320 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22321
22322 test_401b() {
22323         # jobid_var may not allow arbitrary values, so use jobid_name
22324         # if available
22325         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22326                 local testname=jobid_name tmp='testing%p'
22327         else
22328                 local testname=jobid_var tmp=testing
22329         fi
22330
22331         local save=$($LCTL get_param -n $testname)
22332
22333         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22334                 error "no error returned when setting bad parameters"
22335
22336         local jobid_new=$($LCTL get_param -n foe $testname baz)
22337         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22338
22339         $LCTL set_param -n fog=bam $testname=$save bat=fog
22340         local jobid_old=$($LCTL get_param -n foe $testname bag)
22341         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22342 }
22343 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22344
22345 test_401c() {
22346         # jobid_var may not allow arbitrary values, so use jobid_name
22347         # if available
22348         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22349                 local testname=jobid_name
22350         else
22351                 local testname=jobid_var
22352         fi
22353
22354         local jobid_var_old=$($LCTL get_param -n $testname)
22355         local jobid_var_new
22356
22357         $LCTL set_param $testname= &&
22358                 error "no error returned for 'set_param a='"
22359
22360         jobid_var_new=$($LCTL get_param -n $testname)
22361         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22362                 error "$testname was changed by setting without value"
22363
22364         $LCTL set_param $testname &&
22365                 error "no error returned for 'set_param a'"
22366
22367         jobid_var_new=$($LCTL get_param -n $testname)
22368         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22369                 error "$testname was changed by setting without value"
22370 }
22371 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22372
22373 test_401d() {
22374         # jobid_var may not allow arbitrary values, so use jobid_name
22375         # if available
22376         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22377                 local testname=jobid_name new_value='foo=bar%p'
22378         else
22379                 local testname=jobid_var new_valuie=foo=bar
22380         fi
22381
22382         local jobid_var_old=$($LCTL get_param -n $testname)
22383         local jobid_var_new
22384
22385         $LCTL set_param $testname=$new_value ||
22386                 error "'set_param a=b' did not accept a value containing '='"
22387
22388         jobid_var_new=$($LCTL get_param -n $testname)
22389         [[ "$jobid_var_new" == "$new_value" ]] ||
22390                 error "'set_param a=b' failed on a value containing '='"
22391
22392         # Reset the $testname to test the other format
22393         $LCTL set_param $testname=$jobid_var_old
22394         jobid_var_new=$($LCTL get_param -n $testname)
22395         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22396                 error "failed to reset $testname"
22397
22398         $LCTL set_param $testname $new_value ||
22399                 error "'set_param a b' did not accept a value containing '='"
22400
22401         jobid_var_new=$($LCTL get_param -n $testname)
22402         [[ "$jobid_var_new" == "$new_value" ]] ||
22403                 error "'set_param a b' failed on a value containing '='"
22404
22405         $LCTL set_param $testname $jobid_var_old
22406         jobid_var_new=$($LCTL get_param -n $testname)
22407         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22408                 error "failed to reset $testname"
22409 }
22410 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22411
22412 test_402() {
22413         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22414         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22415                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22416         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22417                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22418                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22419         remote_mds_nodsh && skip "remote MDS with nodsh"
22420
22421         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22422 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22423         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22424         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22425                 echo "Touch failed - OK"
22426 }
22427 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22428
22429 test_403() {
22430         local file1=$DIR/$tfile.1
22431         local file2=$DIR/$tfile.2
22432         local tfile=$TMP/$tfile
22433
22434         rm -f $file1 $file2 $tfile
22435
22436         touch $file1
22437         ln $file1 $file2
22438
22439         # 30 sec OBD_TIMEOUT in ll_getattr()
22440         # right before populating st_nlink
22441         $LCTL set_param fail_loc=0x80001409
22442         stat -c %h $file1 > $tfile &
22443
22444         # create an alias, drop all locks and reclaim the dentry
22445         < $file2
22446         cancel_lru_locks mdc
22447         cancel_lru_locks osc
22448         sysctl -w vm.drop_caches=2
22449
22450         wait
22451
22452         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22453
22454         rm -f $tfile $file1 $file2
22455 }
22456 run_test 403 "i_nlink should not drop to zero due to aliasing"
22457
22458 test_404() { # LU-6601
22459         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22460                 skip "Need server version newer than 2.8.52"
22461         remote_mds_nodsh && skip "remote MDS with nodsh"
22462
22463         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22464                 awk '/osp .*-osc-MDT/ { print $4}')
22465
22466         local osp
22467         for osp in $mosps; do
22468                 echo "Deactivate: " $osp
22469                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22470                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22471                         awk -vp=$osp '$4 == p { print $2 }')
22472                 [ $stat = IN ] || {
22473                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22474                         error "deactivate error"
22475                 }
22476                 echo "Activate: " $osp
22477                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22478                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22479                         awk -vp=$osp '$4 == p { print $2 }')
22480                 [ $stat = UP ] || {
22481                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22482                         error "activate error"
22483                 }
22484         done
22485 }
22486 run_test 404 "validate manual {de}activated works properly for OSPs"
22487
22488 test_405() {
22489         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22490         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22491                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22492                         skip "Layout swap lock is not supported"
22493
22494         check_swap_layouts_support
22495         check_swap_layout_no_dom $DIR
22496
22497         test_mkdir $DIR/$tdir
22498         swap_lock_test -d $DIR/$tdir ||
22499                 error "One layout swap locked test failed"
22500 }
22501 run_test 405 "Various layout swap lock tests"
22502
22503 test_406() {
22504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22505         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22506         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22508         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22509                 skip "Need MDS version at least 2.8.50"
22510
22511         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22512         local test_pool=$TESTNAME
22513
22514         pool_add $test_pool || error "pool_add failed"
22515         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22516                 error "pool_add_targets failed"
22517
22518         save_layout_restore_at_exit $MOUNT
22519
22520         # parent set default stripe count only, child will stripe from both
22521         # parent and fs default
22522         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22523                 error "setstripe $MOUNT failed"
22524         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22525         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22526         for i in $(seq 10); do
22527                 local f=$DIR/$tdir/$tfile.$i
22528                 touch $f || error "touch failed"
22529                 local count=$($LFS getstripe -c $f)
22530                 [ $count -eq $OSTCOUNT ] ||
22531                         error "$f stripe count $count != $OSTCOUNT"
22532                 local offset=$($LFS getstripe -i $f)
22533                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22534                 local size=$($LFS getstripe -S $f)
22535                 [ $size -eq $((def_stripe_size * 2)) ] ||
22536                         error "$f stripe size $size != $((def_stripe_size * 2))"
22537                 local pool=$($LFS getstripe -p $f)
22538                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22539         done
22540
22541         # change fs default striping, delete parent default striping, now child
22542         # will stripe from new fs default striping only
22543         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22544                 error "change $MOUNT default stripe failed"
22545         $LFS setstripe -c 0 $DIR/$tdir ||
22546                 error "delete $tdir default stripe failed"
22547         for i in $(seq 11 20); do
22548                 local f=$DIR/$tdir/$tfile.$i
22549                 touch $f || error "touch $f failed"
22550                 local count=$($LFS getstripe -c $f)
22551                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22552                 local offset=$($LFS getstripe -i $f)
22553                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22554                 local size=$($LFS getstripe -S $f)
22555                 [ $size -eq $def_stripe_size ] ||
22556                         error "$f stripe size $size != $def_stripe_size"
22557                 local pool=$($LFS getstripe -p $f)
22558                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22559         done
22560
22561         unlinkmany $DIR/$tdir/$tfile. 1 20
22562
22563         local f=$DIR/$tdir/$tfile
22564         pool_remove_all_targets $test_pool $f
22565         pool_remove $test_pool $f
22566 }
22567 run_test 406 "DNE support fs default striping"
22568
22569 test_407() {
22570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22571         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22572                 skip "Need MDS version at least 2.8.55"
22573         remote_mds_nodsh && skip "remote MDS with nodsh"
22574
22575         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22576                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22577         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22578                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22579         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22580
22581         #define OBD_FAIL_DT_TXN_STOP    0x2019
22582         for idx in $(seq $MDSCOUNT); do
22583                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22584         done
22585         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22586         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22587                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22588         true
22589 }
22590 run_test 407 "transaction fail should cause operation fail"
22591
22592 test_408() {
22593         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22594
22595         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22596         lctl set_param fail_loc=0x8000040a
22597         # let ll_prepare_partial_page() fail
22598         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22599
22600         rm -f $DIR/$tfile
22601
22602         # create at least 100 unused inodes so that
22603         # shrink_icache_memory(0) should not return 0
22604         touch $DIR/$tfile-{0..100}
22605         rm -f $DIR/$tfile-{0..100}
22606         sync
22607
22608         echo 2 > /proc/sys/vm/drop_caches
22609 }
22610 run_test 408 "drop_caches should not hang due to page leaks"
22611
22612 test_409()
22613 {
22614         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22615
22616         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22617         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22618         touch $DIR/$tdir/guard || error "(2) Fail to create"
22619
22620         local PREFIX=$(str_repeat 'A' 128)
22621         echo "Create 1K hard links start at $(date)"
22622         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22623                 error "(3) Fail to hard link"
22624
22625         echo "Links count should be right although linkEA overflow"
22626         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22627         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22628         [ $linkcount -eq 1001 ] ||
22629                 error "(5) Unexpected hard links count: $linkcount"
22630
22631         echo "List all links start at $(date)"
22632         ls -l $DIR/$tdir/foo > /dev/null ||
22633                 error "(6) Fail to list $DIR/$tdir/foo"
22634
22635         echo "Unlink hard links start at $(date)"
22636         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22637                 error "(7) Fail to unlink"
22638         echo "Unlink hard links finished at $(date)"
22639 }
22640 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22641
22642 test_410()
22643 {
22644         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22645                 skip "Need client version at least 2.9.59"
22646         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22647                 skip "Need MODULES build"
22648
22649         # Create a file, and stat it from the kernel
22650         local testfile=$DIR/$tfile
22651         touch $testfile
22652
22653         local run_id=$RANDOM
22654         local my_ino=$(stat --format "%i" $testfile)
22655
22656         # Try to insert the module. This will always fail as the
22657         # module is designed to not be inserted.
22658         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22659             &> /dev/null
22660
22661         # Anything but success is a test failure
22662         dmesg | grep -q \
22663             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22664             error "no inode match"
22665 }
22666 run_test 410 "Test inode number returned from kernel thread"
22667
22668 cleanup_test411_cgroup() {
22669         trap 0
22670         rmdir "$1"
22671 }
22672
22673 test_411() {
22674         local cg_basedir=/sys/fs/cgroup/memory
22675         # LU-9966
22676         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22677                 skip "no setup for cgroup"
22678
22679         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22680                 error "test file creation failed"
22681         cancel_lru_locks osc
22682
22683         # Create a very small memory cgroup to force a slab allocation error
22684         local cgdir=$cg_basedir/osc_slab_alloc
22685         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22686         trap "cleanup_test411_cgroup $cgdir" EXIT
22687         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22688         echo 1M > $cgdir/memory.limit_in_bytes
22689
22690         # Should not LBUG, just be killed by oom-killer
22691         # dd will return 0 even allocation failure in some environment.
22692         # So don't check return value
22693         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22694         cleanup_test411_cgroup $cgdir
22695
22696         return 0
22697 }
22698 run_test 411 "Slab allocation error with cgroup does not LBUG"
22699
22700 test_412() {
22701         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22702         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22703                 skip "Need server version at least 2.10.55"
22704         fi
22705
22706         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22707                 error "mkdir failed"
22708         $LFS getdirstripe $DIR/$tdir
22709         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22710         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22711                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22712         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22713         [ $stripe_count -eq 2 ] ||
22714                 error "expect 2 get $stripe_count"
22715 }
22716 run_test 412 "mkdir on specific MDTs"
22717
22718 test_qos_mkdir() {
22719         local mkdir_cmd=$1
22720         local stripe_count=$2
22721         local mdts=$(comma_list $(mdts_nodes))
22722
22723         local testdir
22724         local lmv_qos_prio_free
22725         local lmv_qos_threshold_rr
22726         local lmv_qos_maxage
22727         local lod_qos_prio_free
22728         local lod_qos_threshold_rr
22729         local lod_qos_maxage
22730         local count
22731         local i
22732
22733         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22734         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22735         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22736                 head -n1)
22737         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22738         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22739         stack_trap "$LCTL set_param \
22740                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22741         stack_trap "$LCTL set_param \
22742                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22743         stack_trap "$LCTL set_param \
22744                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22745
22746         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22747                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22748         lod_qos_prio_free=${lod_qos_prio_free%%%}
22749         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22750                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22751         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22752         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22753                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22754         stack_trap "do_nodes $mdts $LCTL set_param \
22755                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22756         stack_trap "do_nodes $mdts $LCTL set_param \
22757                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22758                 EXIT
22759         stack_trap "do_nodes $mdts $LCTL set_param \
22760                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22761
22762         echo
22763         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22764
22765         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22766         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22767
22768         testdir=$DIR/$tdir-s$stripe_count/rr
22769
22770         for i in $(seq $((100 * MDSCOUNT))); do
22771                 eval $mkdir_cmd $testdir/subdir$i ||
22772                         error "$mkdir_cmd subdir$i failed"
22773         done
22774
22775         for i in $(seq $MDSCOUNT); do
22776                 count=$($LFS getdirstripe -i $testdir/* |
22777                                 grep ^$((i - 1))$ | wc -l)
22778                 echo "$count directories created on MDT$((i - 1))"
22779                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22780
22781                 if [ $stripe_count -gt 1 ]; then
22782                         count=$($LFS getdirstripe $testdir/* |
22783                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22784                         echo "$count stripes created on MDT$((i - 1))"
22785                         # deviation should < 5% of average
22786                         [ $count -lt $((95 * stripe_count)) ] ||
22787                         [ $count -gt $((105 * stripe_count)) ] &&
22788                                 error "stripes are not evenly distributed"
22789                 fi
22790         done
22791
22792         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22793         do_nodes $mdts $LCTL set_param \
22794                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22795
22796         echo
22797         echo "Check for uneven MDTs: "
22798
22799         local ffree
22800         local bavail
22801         local max
22802         local min
22803         local max_index
22804         local min_index
22805         local tmp
22806
22807         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22808         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22809         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22810
22811         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22812         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22813         max_index=0
22814         min_index=0
22815         for ((i = 1; i < ${#ffree[@]}; i++)); do
22816                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22817                 if [ $tmp -gt $max ]; then
22818                         max=$tmp
22819                         max_index=$i
22820                 fi
22821                 if [ $tmp -lt $min ]; then
22822                         min=$tmp
22823                         min_index=$i
22824                 fi
22825         done
22826
22827         [ ${ffree[min_index]} -eq 0 ] &&
22828                 skip "no free files in MDT$min_index"
22829         [ ${ffree[min_index]} -gt 100000000 ] &&
22830                 skip "too much free files in MDT$min_index"
22831
22832         # Check if we need to generate uneven MDTs
22833         local threshold=50
22834         local diff=$(((max - min) * 100 / min))
22835         local value="$(generate_string 1024)"
22836
22837         while [ $diff -lt $threshold ]; do
22838                 # generate uneven MDTs, create till $threshold% diff
22839                 echo -n "weight diff=$diff% must be > $threshold% ..."
22840                 count=$((${ffree[min_index]} / 10))
22841                 # 50 sec per 10000 files in vm
22842                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22843                         skip "$count files to create"
22844                 echo "Fill MDT$min_index with $count files"
22845                 [ -d $DIR/$tdir-MDT$min_index ] ||
22846                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22847                         error "mkdir $tdir-MDT$min_index failed"
22848                 for i in $(seq $count); do
22849                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22850                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22851                                 error "create f$j_$i failed"
22852                         setfattr -n user.413b -v $value \
22853                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22854                                 error "setfattr f$j_$i failed"
22855                 done
22856
22857                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22858                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22859                 max=$(((${ffree[max_index]} >> 8) * \
22860                         (${bavail[max_index]} * bsize >> 16)))
22861                 min=$(((${ffree[min_index]} >> 8) * \
22862                         (${bavail[min_index]} * bsize >> 16)))
22863                 diff=$(((max - min) * 100 / min))
22864         done
22865
22866         echo "MDT filesfree available: ${ffree[@]}"
22867         echo "MDT blocks available: ${bavail[@]}"
22868         echo "weight diff=$diff%"
22869
22870         echo
22871         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22872
22873         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22874         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22875         # decrease statfs age, so that it can be updated in time
22876         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22877         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22878
22879         sleep 1
22880
22881         testdir=$DIR/$tdir-s$stripe_count/qos
22882
22883         for i in $(seq $((100 * MDSCOUNT))); do
22884                 eval $mkdir_cmd $testdir/subdir$i ||
22885                         error "$mkdir_cmd subdir$i failed"
22886         done
22887
22888         for i in $(seq $MDSCOUNT); do
22889                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22890                         wc -l)
22891                 echo "$count directories created on MDT$((i - 1))"
22892
22893                 if [ $stripe_count -gt 1 ]; then
22894                         count=$($LFS getdirstripe $testdir/* |
22895                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22896                         echo "$count stripes created on MDT$((i - 1))"
22897                 fi
22898         done
22899
22900         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22901         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22902
22903         # D-value should > 10% of averge
22904         [ $((max - min)) -lt 10 ] &&
22905                 error "subdirs shouldn't be evenly distributed"
22906
22907         # ditto
22908         if [ $stripe_count -gt 1 ]; then
22909                 max=$($LFS getdirstripe $testdir/* |
22910                         grep -P "^\s+$max_index\t" | wc -l)
22911                 min=$($LFS getdirstripe $testdir/* |
22912                         grep -P "^\s+$min_index\t" | wc -l)
22913                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22914                         error "stripes shouldn't be evenly distributed"|| true
22915         fi
22916 }
22917
22918 test_413a() {
22919         [ $MDSCOUNT -lt 2 ] &&
22920                 skip "We need at least 2 MDTs for this test"
22921
22922         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22923                 skip "Need server version at least 2.12.52"
22924
22925         local stripe_count
22926
22927         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22928                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22929                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22930                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22931                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22932         done
22933 }
22934 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22935
22936 test_413b() {
22937         [ $MDSCOUNT -lt 2 ] &&
22938                 skip "We need at least 2 MDTs for this test"
22939
22940         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22941                 skip "Need server version at least 2.12.52"
22942
22943         local stripe_count
22944
22945         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22946                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22947                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22948                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22949                 $LFS setdirstripe -D -c $stripe_count \
22950                         $DIR/$tdir-s$stripe_count/rr ||
22951                         error "setdirstripe failed"
22952                 $LFS setdirstripe -D -c $stripe_count \
22953                         $DIR/$tdir-s$stripe_count/qos ||
22954                         error "setdirstripe failed"
22955                 test_qos_mkdir "mkdir" $stripe_count
22956         done
22957 }
22958 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22959
22960 test_414() {
22961 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22962         $LCTL set_param fail_loc=0x80000521
22963         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22964         rm -f $DIR/$tfile
22965 }
22966 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22967
22968 test_415() {
22969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22970         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22971                 skip "Need server version at least 2.11.52"
22972
22973         # LU-11102
22974         local total
22975         local setattr_pid
22976         local start_time
22977         local end_time
22978         local duration
22979
22980         total=500
22981         # this test may be slow on ZFS
22982         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22983
22984         # though this test is designed for striped directory, let's test normal
22985         # directory too since lock is always saved as CoS lock.
22986         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22987         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22988
22989         (
22990                 while true; do
22991                         touch $DIR/$tdir
22992                 done
22993         ) &
22994         setattr_pid=$!
22995
22996         start_time=$(date +%s)
22997         for i in $(seq $total); do
22998                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22999                         > /dev/null
23000         done
23001         end_time=$(date +%s)
23002         duration=$((end_time - start_time))
23003
23004         kill -9 $setattr_pid
23005
23006         echo "rename $total files took $duration sec"
23007         [ $duration -lt 100 ] || error "rename took $duration sec"
23008 }
23009 run_test 415 "lock revoke is not missing"
23010
23011 test_416() {
23012         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23013                 skip "Need server version at least 2.11.55"
23014
23015         # define OBD_FAIL_OSD_TXN_START    0x19a
23016         do_facet mds1 lctl set_param fail_loc=0x19a
23017
23018         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23019
23020         true
23021 }
23022 run_test 416 "transaction start failure won't cause system hung"
23023
23024 cleanup_417() {
23025         trap 0
23026         do_nodes $(comma_list $(mdts_nodes)) \
23027                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23028         do_nodes $(comma_list $(mdts_nodes)) \
23029                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23030         do_nodes $(comma_list $(mdts_nodes)) \
23031                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23032 }
23033
23034 test_417() {
23035         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23036         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23037                 skip "Need MDS version at least 2.11.56"
23038
23039         trap cleanup_417 RETURN EXIT
23040
23041         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23042         do_nodes $(comma_list $(mdts_nodes)) \
23043                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23044         $LFS migrate -m 0 $DIR/$tdir.1 &&
23045                 error "migrate dir $tdir.1 should fail"
23046
23047         do_nodes $(comma_list $(mdts_nodes)) \
23048                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23049         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23050                 error "create remote dir $tdir.2 should fail"
23051
23052         do_nodes $(comma_list $(mdts_nodes)) \
23053                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23054         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23055                 error "create striped dir $tdir.3 should fail"
23056         true
23057 }
23058 run_test 417 "disable remote dir, striped dir and dir migration"
23059
23060 # Checks that the outputs of df [-i] and lfs df [-i] match
23061 #
23062 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23063 check_lfs_df() {
23064         local dir=$2
23065         local inodes
23066         local df_out
23067         local lfs_df_out
23068         local count
23069         local passed=false
23070
23071         # blocks or inodes
23072         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23073
23074         for count in {1..100}; do
23075                 cancel_lru_locks
23076                 sync; sleep 0.2
23077
23078                 # read the lines of interest
23079                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23080                         error "df $inodes $dir | tail -n +2 failed"
23081                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23082                         error "lfs df $inodes $dir | grep summary: failed"
23083
23084                 # skip first substrings of each output as they are different
23085                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23086                 # compare the two outputs
23087                 passed=true
23088                 for i in {1..5}; do
23089                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23090                 done
23091                 $passed && break
23092         done
23093
23094         if ! $passed; then
23095                 df -P $inodes $dir
23096                 echo
23097                 lfs df $inodes $dir
23098                 error "df and lfs df $1 output mismatch: "      \
23099                       "df ${inodes}: ${df_out[*]}, "            \
23100                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23101         fi
23102 }
23103
23104 test_418() {
23105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23106
23107         local dir=$DIR/$tdir
23108         local numfiles=$((RANDOM % 4096 + 2))
23109         local numblocks=$((RANDOM % 256 + 1))
23110
23111         wait_delete_completed
23112         test_mkdir $dir
23113
23114         # check block output
23115         check_lfs_df blocks $dir
23116         # check inode output
23117         check_lfs_df inodes $dir
23118
23119         # create a single file and retest
23120         echo "Creating a single file and testing"
23121         createmany -o $dir/$tfile- 1 &>/dev/null ||
23122                 error "creating 1 file in $dir failed"
23123         check_lfs_df blocks $dir
23124         check_lfs_df inodes $dir
23125
23126         # create a random number of files
23127         echo "Creating $((numfiles - 1)) files and testing"
23128         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23129                 error "creating $((numfiles - 1)) files in $dir failed"
23130
23131         # write a random number of blocks to the first test file
23132         echo "Writing $numblocks 4K blocks and testing"
23133         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23134                 count=$numblocks &>/dev/null ||
23135                 error "dd to $dir/${tfile}-0 failed"
23136
23137         # retest
23138         check_lfs_df blocks $dir
23139         check_lfs_df inodes $dir
23140
23141         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23142                 error "unlinking $numfiles files in $dir failed"
23143 }
23144 run_test 418 "df and lfs df outputs match"
23145
23146 test_419()
23147 {
23148         local dir=$DIR/$tdir
23149
23150         mkdir -p $dir
23151         touch $dir/file
23152
23153         cancel_lru_locks mdc
23154
23155         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23156         $LCTL set_param fail_loc=0x1410
23157         cat $dir/file
23158         $LCTL set_param fail_loc=0
23159         rm -rf $dir
23160 }
23161 run_test 419 "Verify open file by name doesn't crash kernel"
23162
23163 test_420()
23164 {
23165         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23166                 skip "Need MDS version at least 2.12.53"
23167
23168         local SAVE_UMASK=$(umask)
23169         local dir=$DIR/$tdir
23170         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23171
23172         mkdir -p $dir
23173         umask 0000
23174         mkdir -m03777 $dir/testdir
23175         ls -dn $dir/testdir
23176         # Need to remove trailing '.' when SELinux is enabled
23177         local dirperms=$(ls -dn $dir/testdir |
23178                          awk '{ sub(/\.$/, "", $1); print $1}')
23179         [ $dirperms == "drwxrwsrwt" ] ||
23180                 error "incorrect perms on $dir/testdir"
23181
23182         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23183                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23184         ls -n $dir/testdir/testfile
23185         local fileperms=$(ls -n $dir/testdir/testfile |
23186                           awk '{ sub(/\.$/, "", $1); print $1}')
23187         [ $fileperms == "-rwxr-xr-x" ] ||
23188                 error "incorrect perms on $dir/testdir/testfile"
23189
23190         umask $SAVE_UMASK
23191 }
23192 run_test 420 "clear SGID bit on non-directories for non-members"
23193
23194 test_421a() {
23195         local cnt
23196         local fid1
23197         local fid2
23198
23199         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23200                 skip "Need MDS version at least 2.12.54"
23201
23202         test_mkdir $DIR/$tdir
23203         createmany -o $DIR/$tdir/f 3
23204         cnt=$(ls -1 $DIR/$tdir | wc -l)
23205         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23206
23207         fid1=$(lfs path2fid $DIR/$tdir/f1)
23208         fid2=$(lfs path2fid $DIR/$tdir/f2)
23209         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23210
23211         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23212         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23213
23214         cnt=$(ls -1 $DIR/$tdir | wc -l)
23215         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23216
23217         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23218         createmany -o $DIR/$tdir/f 3
23219         cnt=$(ls -1 $DIR/$tdir | wc -l)
23220         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23221
23222         fid1=$(lfs path2fid $DIR/$tdir/f1)
23223         fid2=$(lfs path2fid $DIR/$tdir/f2)
23224         echo "remove using fsname $FSNAME"
23225         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23226
23227         cnt=$(ls -1 $DIR/$tdir | wc -l)
23228         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23229 }
23230 run_test 421a "simple rm by fid"
23231
23232 test_421b() {
23233         local cnt
23234         local FID1
23235         local FID2
23236
23237         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23238                 skip "Need MDS version at least 2.12.54"
23239
23240         test_mkdir $DIR/$tdir
23241         createmany -o $DIR/$tdir/f 3
23242         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23243         MULTIPID=$!
23244
23245         FID1=$(lfs path2fid $DIR/$tdir/f1)
23246         FID2=$(lfs path2fid $DIR/$tdir/f2)
23247         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23248
23249         kill -USR1 $MULTIPID
23250         wait
23251
23252         cnt=$(ls $DIR/$tdir | wc -l)
23253         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23254 }
23255 run_test 421b "rm by fid on open file"
23256
23257 test_421c() {
23258         local cnt
23259         local FIDS
23260
23261         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23262                 skip "Need MDS version at least 2.12.54"
23263
23264         test_mkdir $DIR/$tdir
23265         createmany -o $DIR/$tdir/f 3
23266         touch $DIR/$tdir/$tfile
23267         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23268         cnt=$(ls -1 $DIR/$tdir | wc -l)
23269         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23270
23271         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23272         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23273
23274         cnt=$(ls $DIR/$tdir | wc -l)
23275         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23276 }
23277 run_test 421c "rm by fid against hardlinked files"
23278
23279 test_421d() {
23280         local cnt
23281         local FIDS
23282
23283         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23284                 skip "Need MDS version at least 2.12.54"
23285
23286         test_mkdir $DIR/$tdir
23287         createmany -o $DIR/$tdir/f 4097
23288         cnt=$(ls -1 $DIR/$tdir | wc -l)
23289         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23290
23291         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23292         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23293
23294         cnt=$(ls $DIR/$tdir | wc -l)
23295         rm -rf $DIR/$tdir
23296         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23297 }
23298 run_test 421d "rmfid en masse"
23299
23300 test_421e() {
23301         local cnt
23302         local FID
23303
23304         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23305         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23306                 skip "Need MDS version at least 2.12.54"
23307
23308         mkdir -p $DIR/$tdir
23309         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23310         createmany -o $DIR/$tdir/striped_dir/f 512
23311         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23312         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23313
23314         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23315                 sed "s/[/][^:]*://g")
23316         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23317
23318         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23319         rm -rf $DIR/$tdir
23320         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23321 }
23322 run_test 421e "rmfid in DNE"
23323
23324 test_421f() {
23325         local cnt
23326         local FID
23327
23328         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23329                 skip "Need MDS version at least 2.12.54"
23330
23331         test_mkdir $DIR/$tdir
23332         touch $DIR/$tdir/f
23333         cnt=$(ls -1 $DIR/$tdir | wc -l)
23334         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23335
23336         FID=$(lfs path2fid $DIR/$tdir/f)
23337         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23338         # rmfid should fail
23339         cnt=$(ls -1 $DIR/$tdir | wc -l)
23340         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23341
23342         chmod a+rw $DIR/$tdir
23343         ls -la $DIR/$tdir
23344         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23345         # rmfid should fail
23346         cnt=$(ls -1 $DIR/$tdir | wc -l)
23347         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23348
23349         rm -f $DIR/$tdir/f
23350         $RUNAS touch $DIR/$tdir/f
23351         FID=$(lfs path2fid $DIR/$tdir/f)
23352         echo "rmfid as root"
23353         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23354         cnt=$(ls -1 $DIR/$tdir | wc -l)
23355         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23356
23357         rm -f $DIR/$tdir/f
23358         $RUNAS touch $DIR/$tdir/f
23359         cnt=$(ls -1 $DIR/$tdir | wc -l)
23360         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23361         FID=$(lfs path2fid $DIR/$tdir/f)
23362         # rmfid w/o user_fid2path mount option should fail
23363         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23364         cnt=$(ls -1 $DIR/$tdir | wc -l)
23365         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23366
23367         umount_client $MOUNT || error "failed to umount client"
23368         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23369                 error "failed to mount client'"
23370
23371         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23372         # rmfid should succeed
23373         cnt=$(ls -1 $DIR/$tdir | wc -l)
23374         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23375
23376         # rmfid shouldn't allow to remove files due to dir's permission
23377         chmod a+rwx $DIR/$tdir
23378         touch $DIR/$tdir/f
23379         ls -la $DIR/$tdir
23380         FID=$(lfs path2fid $DIR/$tdir/f)
23381         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23382
23383         umount_client $MOUNT || error "failed to umount client"
23384         mount_client $MOUNT "$MOUNT_OPTS" ||
23385                 error "failed to mount client'"
23386
23387 }
23388 run_test 421f "rmfid checks permissions"
23389
23390 test_421g() {
23391         local cnt
23392         local FIDS
23393
23394         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23395         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23396                 skip "Need MDS version at least 2.12.54"
23397
23398         mkdir -p $DIR/$tdir
23399         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23400         createmany -o $DIR/$tdir/striped_dir/f 512
23401         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23402         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23403
23404         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23405                 sed "s/[/][^:]*://g")
23406
23407         rm -f $DIR/$tdir/striped_dir/f1*
23408         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23409         removed=$((512 - cnt))
23410
23411         # few files have been just removed, so we expect
23412         # rmfid to fail on their fids
23413         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23414         [ $removed != $errors ] && error "$errors != $removed"
23415
23416         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23417         rm -rf $DIR/$tdir
23418         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23419 }
23420 run_test 421g "rmfid to return errors properly"
23421
23422 test_422() {
23423         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23424         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23425         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23426         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23427         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23428
23429         local amc=$(at_max_get client)
23430         local amo=$(at_max_get mds1)
23431         local timeout=`lctl get_param -n timeout`
23432
23433         at_max_set 0 client
23434         at_max_set 0 mds1
23435
23436 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23437         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23438                         fail_val=$(((2*timeout + 10)*1000))
23439         touch $DIR/$tdir/d3/file &
23440         sleep 2
23441 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23442         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23443                         fail_val=$((2*timeout + 5))
23444         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23445         local pid=$!
23446         sleep 1
23447         kill -9 $pid
23448         sleep $((2 * timeout))
23449         echo kill $pid
23450         kill -9 $pid
23451         lctl mark touch
23452         touch $DIR/$tdir/d2/file3
23453         touch $DIR/$tdir/d2/file4
23454         touch $DIR/$tdir/d2/file5
23455
23456         wait
23457         at_max_set $amc client
23458         at_max_set $amo mds1
23459
23460         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23461         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23462                 error "Watchdog is always throttled"
23463 }
23464 run_test 422 "kill a process with RPC in progress"
23465
23466 stat_test() {
23467     df -h $MOUNT &
23468     df -h $MOUNT &
23469     df -h $MOUNT &
23470     df -h $MOUNT &
23471     df -h $MOUNT &
23472     df -h $MOUNT &
23473 }
23474
23475 test_423() {
23476     local _stats
23477     # ensure statfs cache is expired
23478     sleep 2;
23479
23480     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23481     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23482
23483     return 0
23484 }
23485 run_test 423 "statfs should return a right data"
23486
23487 test_424() {
23488 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23489         $LCTL set_param fail_loc=0x80000522
23490         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23491         rm -f $DIR/$tfile
23492 }
23493 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23494
23495 test_425() {
23496         test_mkdir -c -1 $DIR/$tdir
23497         $LFS setstripe -c -1 $DIR/$tdir
23498
23499         lru_resize_disable "" 100
23500         stack_trap "lru_resize_enable" EXIT
23501
23502         sleep 5
23503
23504         for i in $(seq $((MDSCOUNT * 125))); do
23505                 local t=$DIR/$tdir/$tfile_$i
23506
23507                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23508                         error_noexit "Create file $t"
23509         done
23510         stack_trap "rm -rf $DIR/$tdir" EXIT
23511
23512         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23513                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23514                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23515
23516                 [ $lock_count -le $lru_size ] ||
23517                         error "osc lock count $lock_count > lru size $lru_size"
23518         done
23519
23520         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23521                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23522                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23523
23524                 [ $lock_count -le $lru_size ] ||
23525                         error "mdc lock count $lock_count > lru size $lru_size"
23526         done
23527 }
23528 run_test 425 "lock count should not exceed lru size"
23529
23530 test_426() {
23531         splice-test -r $DIR/$tfile
23532         splice-test -rd $DIR/$tfile
23533         splice-test $DIR/$tfile
23534         splice-test -d $DIR/$tfile
23535 }
23536 run_test 426 "splice test on Lustre"
23537
23538 prep_801() {
23539         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23540         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23541                 skip "Need server version at least 2.9.55"
23542
23543         start_full_debug_logging
23544 }
23545
23546 post_801() {
23547         stop_full_debug_logging
23548 }
23549
23550 barrier_stat() {
23551         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23552                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23553                            awk '/The barrier for/ { print $7 }')
23554                 echo $st
23555         else
23556                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23557                 echo \'$st\'
23558         fi
23559 }
23560
23561 barrier_expired() {
23562         local expired
23563
23564         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23565                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23566                           awk '/will be expired/ { print $7 }')
23567         else
23568                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23569         fi
23570
23571         echo $expired
23572 }
23573
23574 test_801a() {
23575         prep_801
23576
23577         echo "Start barrier_freeze at: $(date)"
23578         #define OBD_FAIL_BARRIER_DELAY          0x2202
23579         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23580         # Do not reduce barrier time - See LU-11873
23581         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23582
23583         sleep 2
23584         local b_status=$(barrier_stat)
23585         echo "Got barrier status at: $(date)"
23586         [ "$b_status" = "'freezing_p1'" ] ||
23587                 error "(1) unexpected barrier status $b_status"
23588
23589         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23590         wait
23591         b_status=$(barrier_stat)
23592         [ "$b_status" = "'frozen'" ] ||
23593                 error "(2) unexpected barrier status $b_status"
23594
23595         local expired=$(barrier_expired)
23596         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23597         sleep $((expired + 3))
23598
23599         b_status=$(barrier_stat)
23600         [ "$b_status" = "'expired'" ] ||
23601                 error "(3) unexpected barrier status $b_status"
23602
23603         # Do not reduce barrier time - See LU-11873
23604         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23605                 error "(4) fail to freeze barrier"
23606
23607         b_status=$(barrier_stat)
23608         [ "$b_status" = "'frozen'" ] ||
23609                 error "(5) unexpected barrier status $b_status"
23610
23611         echo "Start barrier_thaw at: $(date)"
23612         #define OBD_FAIL_BARRIER_DELAY          0x2202
23613         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23614         do_facet mgs $LCTL barrier_thaw $FSNAME &
23615
23616         sleep 2
23617         b_status=$(barrier_stat)
23618         echo "Got barrier status at: $(date)"
23619         [ "$b_status" = "'thawing'" ] ||
23620                 error "(6) unexpected barrier status $b_status"
23621
23622         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23623         wait
23624         b_status=$(barrier_stat)
23625         [ "$b_status" = "'thawed'" ] ||
23626                 error "(7) unexpected barrier status $b_status"
23627
23628         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23629         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23630         do_facet mgs $LCTL barrier_freeze $FSNAME
23631
23632         b_status=$(barrier_stat)
23633         [ "$b_status" = "'failed'" ] ||
23634                 error "(8) unexpected barrier status $b_status"
23635
23636         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23637         do_facet mgs $LCTL barrier_thaw $FSNAME
23638
23639         post_801
23640 }
23641 run_test 801a "write barrier user interfaces and stat machine"
23642
23643 test_801b() {
23644         prep_801
23645
23646         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23647         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23648         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23649         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23650         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23651
23652         cancel_lru_locks mdc
23653
23654         # 180 seconds should be long enough
23655         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23656
23657         local b_status=$(barrier_stat)
23658         [ "$b_status" = "'frozen'" ] ||
23659                 error "(6) unexpected barrier status $b_status"
23660
23661         mkdir $DIR/$tdir/d0/d10 &
23662         mkdir_pid=$!
23663
23664         touch $DIR/$tdir/d1/f13 &
23665         touch_pid=$!
23666
23667         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23668         ln_pid=$!
23669
23670         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23671         mv_pid=$!
23672
23673         rm -f $DIR/$tdir/d4/f12 &
23674         rm_pid=$!
23675
23676         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23677
23678         # To guarantee taht the 'stat' is not blocked
23679         b_status=$(barrier_stat)
23680         [ "$b_status" = "'frozen'" ] ||
23681                 error "(8) unexpected barrier status $b_status"
23682
23683         # let above commands to run at background
23684         sleep 5
23685
23686         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23687         ps -p $touch_pid || error "(10) touch should be blocked"
23688         ps -p $ln_pid || error "(11) link should be blocked"
23689         ps -p $mv_pid || error "(12) rename should be blocked"
23690         ps -p $rm_pid || error "(13) unlink should be blocked"
23691
23692         b_status=$(barrier_stat)
23693         [ "$b_status" = "'frozen'" ] ||
23694                 error "(14) unexpected barrier status $b_status"
23695
23696         do_facet mgs $LCTL barrier_thaw $FSNAME
23697         b_status=$(barrier_stat)
23698         [ "$b_status" = "'thawed'" ] ||
23699                 error "(15) unexpected barrier status $b_status"
23700
23701         wait $mkdir_pid || error "(16) mkdir should succeed"
23702         wait $touch_pid || error "(17) touch should succeed"
23703         wait $ln_pid || error "(18) link should succeed"
23704         wait $mv_pid || error "(19) rename should succeed"
23705         wait $rm_pid || error "(20) unlink should succeed"
23706
23707         post_801
23708 }
23709 run_test 801b "modification will be blocked by write barrier"
23710
23711 test_801c() {
23712         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23713
23714         prep_801
23715
23716         stop mds2 || error "(1) Fail to stop mds2"
23717
23718         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23719
23720         local b_status=$(barrier_stat)
23721         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23722                 do_facet mgs $LCTL barrier_thaw $FSNAME
23723                 error "(2) unexpected barrier status $b_status"
23724         }
23725
23726         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23727                 error "(3) Fail to rescan barrier bitmap"
23728
23729         # Do not reduce barrier time - See LU-11873
23730         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23731
23732         b_status=$(barrier_stat)
23733         [ "$b_status" = "'frozen'" ] ||
23734                 error "(4) unexpected barrier status $b_status"
23735
23736         do_facet mgs $LCTL barrier_thaw $FSNAME
23737         b_status=$(barrier_stat)
23738         [ "$b_status" = "'thawed'" ] ||
23739                 error "(5) unexpected barrier status $b_status"
23740
23741         local devname=$(mdsdevname 2)
23742
23743         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23744
23745         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23746                 error "(7) Fail to rescan barrier bitmap"
23747
23748         post_801
23749 }
23750 run_test 801c "rescan barrier bitmap"
23751
23752 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23753 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23754 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23755 saved_MOUNT_OPTS=$MOUNT_OPTS
23756
23757 cleanup_802a() {
23758         trap 0
23759
23760         stopall
23761         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23762         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23763         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23764         MOUNT_OPTS=$saved_MOUNT_OPTS
23765         setupall
23766 }
23767
23768 test_802a() {
23769         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23770         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23771         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23772                 skip "Need server version at least 2.9.55"
23773
23774         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23775
23776         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23777
23778         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23779                 error "(2) Fail to copy"
23780
23781         trap cleanup_802a EXIT
23782
23783         # sync by force before remount as readonly
23784         sync; sync_all_data; sleep 3; sync_all_data
23785
23786         stopall
23787
23788         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23789         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23790         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23791
23792         echo "Mount the server as read only"
23793         setupall server_only || error "(3) Fail to start servers"
23794
23795         echo "Mount client without ro should fail"
23796         mount_client $MOUNT &&
23797                 error "(4) Mount client without 'ro' should fail"
23798
23799         echo "Mount client with ro should succeed"
23800         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23801         mount_client $MOUNT ||
23802                 error "(5) Mount client with 'ro' should succeed"
23803
23804         echo "Modify should be refused"
23805         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23806
23807         echo "Read should be allowed"
23808         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23809                 error "(7) Read should succeed under ro mode"
23810
23811         cleanup_802a
23812 }
23813 run_test 802a "simulate readonly device"
23814
23815 test_802b() {
23816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23817         remote_mds_nodsh && skip "remote MDS with nodsh"
23818
23819         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23820                 skip "readonly option not available"
23821
23822         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23823
23824         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23825                 error "(2) Fail to copy"
23826
23827         # write back all cached data before setting MDT to readonly
23828         cancel_lru_locks
23829         sync_all_data
23830
23831         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23832         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23833
23834         echo "Modify should be refused"
23835         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23836
23837         echo "Read should be allowed"
23838         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23839                 error "(7) Read should succeed under ro mode"
23840
23841         # disable readonly
23842         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23843 }
23844 run_test 802b "be able to set MDTs to readonly"
23845
23846 test_803() {
23847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23848         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23849                 skip "MDS needs to be newer than 2.10.54"
23850
23851         mkdir -p $DIR/$tdir
23852         # Create some objects on all MDTs to trigger related logs objects
23853         for idx in $(seq $MDSCOUNT); do
23854                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23855                         $DIR/$tdir/dir${idx} ||
23856                         error "Fail to create $DIR/$tdir/dir${idx}"
23857         done
23858
23859         sync; sleep 3
23860         wait_delete_completed # ensure old test cleanups are finished
23861         echo "before create:"
23862         $LFS df -i $MOUNT
23863         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23864
23865         for i in {1..10}; do
23866                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23867                         error "Fail to create $DIR/$tdir/foo$i"
23868         done
23869
23870         sync; sleep 3
23871         echo "after create:"
23872         $LFS df -i $MOUNT
23873         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23874
23875         # allow for an llog to be cleaned up during the test
23876         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23877                 error "before ($before_used) + 10 > after ($after_used)"
23878
23879         for i in {1..10}; do
23880                 rm -rf $DIR/$tdir/foo$i ||
23881                         error "Fail to remove $DIR/$tdir/foo$i"
23882         done
23883
23884         sleep 3 # avoid MDT return cached statfs
23885         wait_delete_completed
23886         echo "after unlink:"
23887         $LFS df -i $MOUNT
23888         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23889
23890         # allow for an llog to be created during the test
23891         [ $after_used -le $((before_used + 1)) ] ||
23892                 error "after ($after_used) > before ($before_used) + 1"
23893 }
23894 run_test 803 "verify agent object for remote object"
23895
23896 test_804() {
23897         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23898         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23899                 skip "MDS needs to be newer than 2.10.54"
23900         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23901
23902         mkdir -p $DIR/$tdir
23903         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23904                 error "Fail to create $DIR/$tdir/dir0"
23905
23906         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23907         local dev=$(mdsdevname 2)
23908
23909         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23910                 grep ${fid} || error "NOT found agent entry for dir0"
23911
23912         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23913                 error "Fail to create $DIR/$tdir/dir1"
23914
23915         touch $DIR/$tdir/dir1/foo0 ||
23916                 error "Fail to create $DIR/$tdir/dir1/foo0"
23917         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23918         local rc=0
23919
23920         for idx in $(seq $MDSCOUNT); do
23921                 dev=$(mdsdevname $idx)
23922                 do_facet mds${idx} \
23923                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23924                         grep ${fid} && rc=$idx
23925         done
23926
23927         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23928                 error "Fail to rename foo0 to foo1"
23929         if [ $rc -eq 0 ]; then
23930                 for idx in $(seq $MDSCOUNT); do
23931                         dev=$(mdsdevname $idx)
23932                         do_facet mds${idx} \
23933                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23934                         grep ${fid} && rc=$idx
23935                 done
23936         fi
23937
23938         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23939                 error "Fail to rename foo1 to foo2"
23940         if [ $rc -eq 0 ]; then
23941                 for idx in $(seq $MDSCOUNT); do
23942                         dev=$(mdsdevname $idx)
23943                         do_facet mds${idx} \
23944                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23945                         grep ${fid} && rc=$idx
23946                 done
23947         fi
23948
23949         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23950
23951         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23952                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23953         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23954                 error "Fail to rename foo2 to foo0"
23955         unlink $DIR/$tdir/dir1/foo0 ||
23956                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23957         rm -rf $DIR/$tdir/dir0 ||
23958                 error "Fail to rm $DIR/$tdir/dir0"
23959
23960         for idx in $(seq $MDSCOUNT); do
23961                 dev=$(mdsdevname $idx)
23962                 rc=0
23963
23964                 stop mds${idx}
23965                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23966                         rc=$?
23967                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23968                         error "mount mds$idx failed"
23969                 df $MOUNT > /dev/null 2>&1
23970
23971                 # e2fsck should not return error
23972                 [ $rc -eq 0 ] ||
23973                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23974         done
23975 }
23976 run_test 804 "verify agent entry for remote entry"
23977
23978 cleanup_805() {
23979         do_facet $SINGLEMDS zfs set quota=$old $fsset
23980         unlinkmany $DIR/$tdir/f- 1000000
23981         trap 0
23982 }
23983
23984 test_805() {
23985         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23986         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23987         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23988                 skip "netfree not implemented before 0.7"
23989         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23990                 skip "Need MDS version at least 2.10.57"
23991
23992         local fsset
23993         local freekb
23994         local usedkb
23995         local old
23996         local quota
23997         local pref="osd-zfs.$FSNAME-MDT0000."
23998
23999         # limit available space on MDS dataset to meet nospace issue
24000         # quickly. then ZFS 0.7.2 can use reserved space if asked
24001         # properly (using netfree flag in osd_declare_destroy()
24002         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24003         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24004                 gawk '{print $3}')
24005         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24006         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24007         let "usedkb=usedkb-freekb"
24008         let "freekb=freekb/2"
24009         if let "freekb > 5000"; then
24010                 let "freekb=5000"
24011         fi
24012         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24013         trap cleanup_805 EXIT
24014         mkdir $DIR/$tdir
24015         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24016                 error "Can't set PFL layout"
24017         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24018         rm -rf $DIR/$tdir || error "not able to remove"
24019         do_facet $SINGLEMDS zfs set quota=$old $fsset
24020         trap 0
24021 }
24022 run_test 805 "ZFS can remove from full fs"
24023
24024 # Size-on-MDS test
24025 check_lsom_data()
24026 {
24027         local file=$1
24028         local size=$($LFS getsom -s $file)
24029         local expect=$(stat -c %s $file)
24030
24031         [[ $size == $expect ]] ||
24032                 error "$file expected size: $expect, got: $size"
24033
24034         local blocks=$($LFS getsom -b $file)
24035         expect=$(stat -c %b $file)
24036         [[ $blocks == $expect ]] ||
24037                 error "$file expected blocks: $expect, got: $blocks"
24038 }
24039
24040 check_lsom_size()
24041 {
24042         local size=$($LFS getsom -s $1)
24043         local expect=$2
24044
24045         [[ $size == $expect ]] ||
24046                 error "$file expected size: $expect, got: $size"
24047 }
24048
24049 test_806() {
24050         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24051                 skip "Need MDS version at least 2.11.52"
24052
24053         local bs=1048576
24054
24055         touch $DIR/$tfile || error "touch $tfile failed"
24056
24057         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24058         save_lustre_params client "llite.*.xattr_cache" > $save
24059         lctl set_param llite.*.xattr_cache=0
24060         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24061
24062         # single-threaded write
24063         echo "Test SOM for single-threaded write"
24064         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24065                 error "write $tfile failed"
24066         check_lsom_size $DIR/$tfile $bs
24067
24068         local num=32
24069         local size=$(($num * $bs))
24070         local offset=0
24071         local i
24072
24073         echo "Test SOM for single client multi-threaded($num) write"
24074         $TRUNCATE $DIR/$tfile 0
24075         for ((i = 0; i < $num; i++)); do
24076                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24077                 local pids[$i]=$!
24078                 offset=$((offset + $bs))
24079         done
24080         for (( i=0; i < $num; i++ )); do
24081                 wait ${pids[$i]}
24082         done
24083         check_lsom_size $DIR/$tfile $size
24084
24085         $TRUNCATE $DIR/$tfile 0
24086         for ((i = 0; i < $num; i++)); do
24087                 offset=$((offset - $bs))
24088                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24089                 local pids[$i]=$!
24090         done
24091         for (( i=0; i < $num; i++ )); do
24092                 wait ${pids[$i]}
24093         done
24094         check_lsom_size $DIR/$tfile $size
24095
24096         # multi-client writes
24097         num=$(get_node_count ${CLIENTS//,/ })
24098         size=$(($num * $bs))
24099         offset=0
24100         i=0
24101
24102         echo "Test SOM for multi-client ($num) writes"
24103         $TRUNCATE $DIR/$tfile 0
24104         for client in ${CLIENTS//,/ }; do
24105                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24106                 local pids[$i]=$!
24107                 i=$((i + 1))
24108                 offset=$((offset + $bs))
24109         done
24110         for (( i=0; i < $num; i++ )); do
24111                 wait ${pids[$i]}
24112         done
24113         check_lsom_size $DIR/$tfile $offset
24114
24115         i=0
24116         $TRUNCATE $DIR/$tfile 0
24117         for client in ${CLIENTS//,/ }; do
24118                 offset=$((offset - $bs))
24119                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24120                 local pids[$i]=$!
24121                 i=$((i + 1))
24122         done
24123         for (( i=0; i < $num; i++ )); do
24124                 wait ${pids[$i]}
24125         done
24126         check_lsom_size $DIR/$tfile $size
24127
24128         # verify truncate
24129         echo "Test SOM for truncate"
24130         $TRUNCATE $DIR/$tfile 1048576
24131         check_lsom_size $DIR/$tfile 1048576
24132         $TRUNCATE $DIR/$tfile 1234
24133         check_lsom_size $DIR/$tfile 1234
24134
24135         # verify SOM blocks count
24136         echo "Verify SOM block count"
24137         $TRUNCATE $DIR/$tfile 0
24138         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24139                 error "failed to write file $tfile"
24140         check_lsom_data $DIR/$tfile
24141 }
24142 run_test 806 "Verify Lazy Size on MDS"
24143
24144 test_807() {
24145         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24146         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24147                 skip "Need MDS version at least 2.11.52"
24148
24149         # Registration step
24150         changelog_register || error "changelog_register failed"
24151         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24152         changelog_users $SINGLEMDS | grep -q $cl_user ||
24153                 error "User $cl_user not found in changelog_users"
24154
24155         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24156         save_lustre_params client "llite.*.xattr_cache" > $save
24157         lctl set_param llite.*.xattr_cache=0
24158         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24159
24160         rm -rf $DIR/$tdir || error "rm $tdir failed"
24161         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24162         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24163         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24164         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24165                 error "truncate $tdir/trunc failed"
24166
24167         local bs=1048576
24168         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24169                 error "write $tfile failed"
24170
24171         # multi-client wirtes
24172         local num=$(get_node_count ${CLIENTS//,/ })
24173         local offset=0
24174         local i=0
24175
24176         echo "Test SOM for multi-client ($num) writes"
24177         touch $DIR/$tfile || error "touch $tfile failed"
24178         $TRUNCATE $DIR/$tfile 0
24179         for client in ${CLIENTS//,/ }; do
24180                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24181                 local pids[$i]=$!
24182                 i=$((i + 1))
24183                 offset=$((offset + $bs))
24184         done
24185         for (( i=0; i < $num; i++ )); do
24186                 wait ${pids[$i]}
24187         done
24188
24189         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24190         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24191         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24192         check_lsom_data $DIR/$tdir/trunc
24193         check_lsom_data $DIR/$tdir/single_dd
24194         check_lsom_data $DIR/$tfile
24195
24196         rm -rf $DIR/$tdir
24197         # Deregistration step
24198         changelog_deregister || error "changelog_deregister failed"
24199 }
24200 run_test 807 "verify LSOM syncing tool"
24201
24202 check_som_nologged()
24203 {
24204         local lines=$($LFS changelog $FSNAME-MDT0000 |
24205                 grep 'x=trusted.som' | wc -l)
24206         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24207 }
24208
24209 test_808() {
24210         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24211                 skip "Need MDS version at least 2.11.55"
24212
24213         # Registration step
24214         changelog_register || error "changelog_register failed"
24215
24216         touch $DIR/$tfile || error "touch $tfile failed"
24217         check_som_nologged
24218
24219         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24220                 error "write $tfile failed"
24221         check_som_nologged
24222
24223         $TRUNCATE $DIR/$tfile 1234
24224         check_som_nologged
24225
24226         $TRUNCATE $DIR/$tfile 1048576
24227         check_som_nologged
24228
24229         # Deregistration step
24230         changelog_deregister || error "changelog_deregister failed"
24231 }
24232 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24233
24234 check_som_nodata()
24235 {
24236         $LFS getsom $1
24237         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24238 }
24239
24240 test_809() {
24241         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24242                 skip "Need MDS version at least 2.11.56"
24243
24244         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24245                 error "failed to create DoM-only file $DIR/$tfile"
24246         touch $DIR/$tfile || error "touch $tfile failed"
24247         check_som_nodata $DIR/$tfile
24248
24249         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24250                 error "write $tfile failed"
24251         check_som_nodata $DIR/$tfile
24252
24253         $TRUNCATE $DIR/$tfile 1234
24254         check_som_nodata $DIR/$tfile
24255
24256         $TRUNCATE $DIR/$tfile 4097
24257         check_som_nodata $DIR/$file
24258 }
24259 run_test 809 "Verify no SOM xattr store for DoM-only files"
24260
24261 test_810() {
24262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24263         $GSS && skip_env "could not run with gss"
24264         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24265                 skip "OST < 2.12.58 doesn't align checksum"
24266
24267         set_checksums 1
24268         stack_trap "set_checksums $ORIG_CSUM" EXIT
24269         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24270
24271         local csum
24272         local before
24273         local after
24274         for csum in $CKSUM_TYPES; do
24275                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24276                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24277                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24278                         eval set -- $i
24279                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24280                         before=$(md5sum $DIR/$tfile)
24281                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24282                         after=$(md5sum $DIR/$tfile)
24283                         [ "$before" == "$after" ] ||
24284                                 error "$csum: $before != $after bs=$1 seek=$2"
24285                 done
24286         done
24287 }
24288 run_test 810 "partial page writes on ZFS (LU-11663)"
24289
24290 test_812a() {
24291         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24292                 skip "OST < 2.12.51 doesn't support this fail_loc"
24293
24294         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24295         # ensure ost1 is connected
24296         stat $DIR/$tfile >/dev/null || error "can't stat"
24297         wait_osc_import_state client ost1 FULL
24298         # no locks, no reqs to let the connection idle
24299         cancel_lru_locks osc
24300
24301         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24302 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24303         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24304         wait_osc_import_state client ost1 CONNECTING
24305         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24306
24307         stat $DIR/$tfile >/dev/null || error "can't stat file"
24308 }
24309 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24310
24311 test_812b() { # LU-12378
24312         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24313                 skip "OST < 2.12.51 doesn't support this fail_loc"
24314
24315         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24316         # ensure ost1 is connected
24317         stat $DIR/$tfile >/dev/null || error "can't stat"
24318         wait_osc_import_state client ost1 FULL
24319         # no locks, no reqs to let the connection idle
24320         cancel_lru_locks osc
24321
24322         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24323 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24324         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24325         wait_osc_import_state client ost1 CONNECTING
24326         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24327
24328         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24329         wait_osc_import_state client ost1 IDLE
24330 }
24331 run_test 812b "do not drop no resend request for idle connect"
24332
24333 test_813() {
24334         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24335         [ -z "$file_heat_sav" ] && skip "no file heat support"
24336
24337         local readsample
24338         local writesample
24339         local readbyte
24340         local writebyte
24341         local readsample1
24342         local writesample1
24343         local readbyte1
24344         local writebyte1
24345
24346         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24347         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24348
24349         $LCTL set_param -n llite.*.file_heat=1
24350         echo "Turn on file heat"
24351         echo "Period second: $period_second, Decay percentage: $decay_pct"
24352
24353         echo "QQQQ" > $DIR/$tfile
24354         echo "QQQQ" > $DIR/$tfile
24355         echo "QQQQ" > $DIR/$tfile
24356         cat $DIR/$tfile > /dev/null
24357         cat $DIR/$tfile > /dev/null
24358         cat $DIR/$tfile > /dev/null
24359         cat $DIR/$tfile > /dev/null
24360
24361         local out=$($LFS heat_get $DIR/$tfile)
24362
24363         $LFS heat_get $DIR/$tfile
24364         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24365         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24366         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24367         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24368
24369         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24370         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24371         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24372         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24373
24374         sleep $((period_second + 3))
24375         echo "Sleep $((period_second + 3)) seconds..."
24376         # The recursion formula to calculate the heat of the file f is as
24377         # follow:
24378         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24379         # Where Hi is the heat value in the period between time points i*I and
24380         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24381         # to the weight of Ci.
24382         out=$($LFS heat_get $DIR/$tfile)
24383         $LFS heat_get $DIR/$tfile
24384         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24385         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24386         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24387         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24388
24389         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24390                 error "read sample ($readsample) is wrong"
24391         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24392                 error "write sample ($writesample) is wrong"
24393         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24394                 error "read bytes ($readbyte) is wrong"
24395         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24396                 error "write bytes ($writebyte) is wrong"
24397
24398         echo "QQQQ" > $DIR/$tfile
24399         echo "QQQQ" > $DIR/$tfile
24400         echo "QQQQ" > $DIR/$tfile
24401         cat $DIR/$tfile > /dev/null
24402         cat $DIR/$tfile > /dev/null
24403         cat $DIR/$tfile > /dev/null
24404         cat $DIR/$tfile > /dev/null
24405
24406         sleep $((period_second + 3))
24407         echo "Sleep $((period_second + 3)) seconds..."
24408
24409         out=$($LFS heat_get $DIR/$tfile)
24410         $LFS heat_get $DIR/$tfile
24411         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24412         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24413         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24414         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24415
24416         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24417                 4 * $decay_pct) / 100") -eq 1 ] ||
24418                 error "read sample ($readsample1) is wrong"
24419         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24420                 3 * $decay_pct) / 100") -eq 1 ] ||
24421                 error "write sample ($writesample1) is wrong"
24422         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24423                 20 * $decay_pct) / 100") -eq 1 ] ||
24424                 error "read bytes ($readbyte1) is wrong"
24425         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24426                 15 * $decay_pct) / 100") -eq 1 ] ||
24427                 error "write bytes ($writebyte1) is wrong"
24428
24429         echo "Turn off file heat for the file $DIR/$tfile"
24430         $LFS heat_set -o $DIR/$tfile
24431
24432         echo "QQQQ" > $DIR/$tfile
24433         echo "QQQQ" > $DIR/$tfile
24434         echo "QQQQ" > $DIR/$tfile
24435         cat $DIR/$tfile > /dev/null
24436         cat $DIR/$tfile > /dev/null
24437         cat $DIR/$tfile > /dev/null
24438         cat $DIR/$tfile > /dev/null
24439
24440         out=$($LFS heat_get $DIR/$tfile)
24441         $LFS heat_get $DIR/$tfile
24442         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24443         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24444         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24445         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24446
24447         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24448         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24449         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24450         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24451
24452         echo "Trun on file heat for the file $DIR/$tfile"
24453         $LFS heat_set -O $DIR/$tfile
24454
24455         echo "QQQQ" > $DIR/$tfile
24456         echo "QQQQ" > $DIR/$tfile
24457         echo "QQQQ" > $DIR/$tfile
24458         cat $DIR/$tfile > /dev/null
24459         cat $DIR/$tfile > /dev/null
24460         cat $DIR/$tfile > /dev/null
24461         cat $DIR/$tfile > /dev/null
24462
24463         out=$($LFS heat_get $DIR/$tfile)
24464         $LFS heat_get $DIR/$tfile
24465         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24466         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24467         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24468         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24469
24470         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24471         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24472         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24473         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24474
24475         $LFS heat_set -c $DIR/$tfile
24476         $LCTL set_param -n llite.*.file_heat=0
24477         echo "Turn off file heat support for the Lustre filesystem"
24478
24479         echo "QQQQ" > $DIR/$tfile
24480         echo "QQQQ" > $DIR/$tfile
24481         echo "QQQQ" > $DIR/$tfile
24482         cat $DIR/$tfile > /dev/null
24483         cat $DIR/$tfile > /dev/null
24484         cat $DIR/$tfile > /dev/null
24485         cat $DIR/$tfile > /dev/null
24486
24487         out=$($LFS heat_get $DIR/$tfile)
24488         $LFS heat_get $DIR/$tfile
24489         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24490         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24491         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24492         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24493
24494         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24495         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24496         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24497         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24498
24499         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24500         rm -f $DIR/$tfile
24501 }
24502 run_test 813 "File heat verfication"
24503
24504 test_814()
24505 {
24506         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24507         echo -n y >> $DIR/$tfile
24508         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24509         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24510 }
24511 run_test 814 "sparse cp works as expected (LU-12361)"
24512
24513 test_815()
24514 {
24515         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24516         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24517 }
24518 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24519
24520 test_816() {
24521         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24522         # ensure ost1 is connected
24523         stat $DIR/$tfile >/dev/null || error "can't stat"
24524         wait_osc_import_state client ost1 FULL
24525         # no locks, no reqs to let the connection idle
24526         cancel_lru_locks osc
24527         lru_resize_disable osc
24528         local before
24529         local now
24530         before=$($LCTL get_param -n \
24531                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24532
24533         wait_osc_import_state client ost1 IDLE
24534         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24535         now=$($LCTL get_param -n \
24536               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24537         [ $before == $now ] || error "lru_size changed $before != $now"
24538 }
24539 run_test 816 "do not reset lru_resize on idle reconnect"
24540
24541 cleanup_817() {
24542         umount $tmpdir
24543         exportfs -u localhost:$DIR/nfsexp
24544         rm -rf $DIR/nfsexp
24545 }
24546
24547 test_817() {
24548         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24549
24550         mkdir -p $DIR/nfsexp
24551         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24552                 error "failed to export nfs"
24553
24554         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24555         stack_trap cleanup_817 EXIT
24556
24557         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24558                 error "failed to mount nfs to $tmpdir"
24559
24560         cp /bin/true $tmpdir
24561         $DIR/nfsexp/true || error "failed to execute 'true' command"
24562 }
24563 run_test 817 "nfsd won't cache write lock for exec file"
24564
24565 test_818() {
24566         mkdir $DIR/$tdir
24567         $LFS setstripe -c1 -i0 $DIR/$tfile
24568         $LFS setstripe -c1 -i1 $DIR/$tfile
24569         stop $SINGLEMDS
24570         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24571         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24572         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24573                 error "start $SINGLEMDS failed"
24574         rm -rf $DIR/$tdir
24575 }
24576 run_test 818 "unlink with failed llog"
24577
24578 test_819a() {
24579         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24580         cancel_lru_locks osc
24581         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24582         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24583         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24584         rm -f $TDIR/$tfile
24585 }
24586 run_test 819a "too big niobuf in read"
24587
24588 test_819b() {
24589         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24590         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24591         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24592         cancel_lru_locks osc
24593         sleep 1
24594         rm -f $TDIR/$tfile
24595 }
24596 run_test 819b "too big niobuf in write"
24597
24598
24599 function test_820_start_ost() {
24600         sleep 5
24601
24602         for num in $(seq $OSTCOUNT); do
24603                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24604         done
24605 }
24606
24607 test_820() {
24608         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24609
24610         mkdir $DIR/$tdir
24611         umount_client $MOUNT || error "umount failed"
24612         for num in $(seq $OSTCOUNT); do
24613                 stop ost$num
24614         done
24615
24616         # mount client with no active OSTs
24617         # so that the client can't initialize max LOV EA size
24618         # from OSC notifications
24619         mount_client $MOUNT || error "mount failed"
24620         # delay OST starting to keep this 0 max EA size for a while
24621         test_820_start_ost &
24622
24623         # create a directory on MDS2
24624         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24625                 error "Failed to create directory"
24626         # open intent should update default EA size
24627         # see mdc_update_max_ea_from_body()
24628         # notice this is the very first RPC to MDS2
24629         cp /etc/services $DIR/$tdir/mds2 ||
24630                 error "Failed to copy files to mds$n"
24631 }
24632 run_test 820 "update max EA from open intent"
24633
24634 #
24635 # tests that do cleanup/setup should be run at the end
24636 #
24637
24638 test_900() {
24639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24640         local ls
24641
24642         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24643         $LCTL set_param fail_loc=0x903
24644
24645         cancel_lru_locks MGC
24646
24647         FAIL_ON_ERROR=true cleanup
24648         FAIL_ON_ERROR=true setup
24649 }
24650 run_test 900 "umount should not race with any mgc requeue thread"
24651
24652 # LUS-6253/LU-11185
24653 test_901() {
24654         local oldc
24655         local newc
24656         local olds
24657         local news
24658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24659
24660         # some get_param have a bug to handle dot in param name
24661         cancel_lru_locks MGC
24662         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24663         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24664         umount_client $MOUNT || error "umount failed"
24665         mount_client $MOUNT || error "mount failed"
24666         cancel_lru_locks MGC
24667         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24668         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24669
24670         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24671         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24672
24673         return 0
24674 }
24675 run_test 901 "don't leak a mgc lock on client umount"
24676
24677 # LU-13377
24678 test_902() {
24679         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24680                 skip "client does not have LU-13377 fix"
24681         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24682         $LCTL set_param fail_loc=0x1415
24683         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24684         cancel_lru_locks osc
24685         rm -f $DIR/$tfile
24686 }
24687 run_test 902 "test short write doesn't hang lustre"
24688
24689 complete $SECONDS
24690 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24691 check_and_cleanup_lustre
24692 if [ "$I_MOUNTED" != "yes" ]; then
24693         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24694 fi
24695 exit_status