Whamcloud - gitweb
LU-13665 tests: skip sanity subtests for new features
[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_24G () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1450
1451         local ino1
1452         local ino2
1453
1454         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1455         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1456         touch $DIR/$tdir-0/f1 || error "touch f1"
1457         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1458         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1459         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1460         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1461         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1462 }
1463 run_test 24G "migrate symlink in rename"
1464
1465 test_25a() {
1466         echo '== symlink sanity ============================================='
1467
1468         test_mkdir $DIR/d25
1469         ln -s d25 $DIR/s25
1470         touch $DIR/s25/foo ||
1471                 error "File creation in symlinked directory failed"
1472 }
1473 run_test 25a "create file in symlinked directory ==============="
1474
1475 test_25b() {
1476         [ ! -d $DIR/d25 ] && test_25a
1477         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1478 }
1479 run_test 25b "lookup file in symlinked directory ==============="
1480
1481 test_26a() {
1482         test_mkdir $DIR/d26
1483         test_mkdir $DIR/d26/d26-2
1484         ln -s d26/d26-2 $DIR/s26
1485         touch $DIR/s26/foo || error "File creation failed"
1486 }
1487 run_test 26a "multiple component symlink ======================="
1488
1489 test_26b() {
1490         test_mkdir -p $DIR/$tdir/d26-2
1491         ln -s $tdir/d26-2/foo $DIR/s26-2
1492         touch $DIR/s26-2 || error "File creation failed"
1493 }
1494 run_test 26b "multiple component symlink at end of lookup ======"
1495
1496 test_26c() {
1497         test_mkdir $DIR/d26.2
1498         touch $DIR/d26.2/foo
1499         ln -s d26.2 $DIR/s26.2-1
1500         ln -s s26.2-1 $DIR/s26.2-2
1501         ln -s s26.2-2 $DIR/s26.2-3
1502         chmod 0666 $DIR/s26.2-3/foo
1503 }
1504 run_test 26c "chain of symlinks"
1505
1506 # recursive symlinks (bug 439)
1507 test_26d() {
1508         ln -s d26-3/foo $DIR/d26-3
1509 }
1510 run_test 26d "create multiple component recursive symlink"
1511
1512 test_26e() {
1513         [ ! -h $DIR/d26-3 ] && test_26d
1514         rm $DIR/d26-3
1515 }
1516 run_test 26e "unlink multiple component recursive symlink"
1517
1518 # recursive symlinks (bug 7022)
1519 test_26f() {
1520         test_mkdir $DIR/$tdir
1521         test_mkdir $DIR/$tdir/$tfile
1522         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1523         test_mkdir -p lndir/bar1
1524         test_mkdir $DIR/$tdir/$tfile/$tfile
1525         cd $tfile                || error "cd $tfile failed"
1526         ln -s .. dotdot          || error "ln dotdot failed"
1527         ln -s dotdot/lndir lndir || error "ln lndir failed"
1528         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1529         output=`ls $tfile/$tfile/lndir/bar1`
1530         [ "$output" = bar1 ] && error "unexpected output"
1531         rm -r $tfile             || error "rm $tfile failed"
1532         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1533 }
1534 run_test 26f "rm -r of a directory which has recursive symlink"
1535
1536 test_27a() {
1537         test_mkdir $DIR/$tdir
1538         $LFS getstripe $DIR/$tdir
1539         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1540         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1541         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1542 }
1543 run_test 27a "one stripe file"
1544
1545 test_27b() {
1546         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1547
1548         test_mkdir $DIR/$tdir
1549         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1550         $LFS getstripe -c $DIR/$tdir/$tfile
1551         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1552                 error "two-stripe file doesn't have two stripes"
1553
1554         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1555 }
1556 run_test 27b "create and write to two stripe file"
1557
1558 # 27c family tests specific striping, setstripe -o
1559 test_27ca() {
1560         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1561         test_mkdir -p $DIR/$tdir
1562         local osts="1"
1563
1564         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1565         $LFS getstripe -i $DIR/$tdir/$tfile
1566         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1567                 error "stripe not on specified OST"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27ca "one stripe on specified OST"
1572
1573 test_27cb() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         test_mkdir -p $DIR/$tdir
1576         local osts="1,0"
1577         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1578         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1579         echo "$getstripe"
1580
1581         # Strip getstripe output to a space separated list of OSTs
1582         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1583                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1584         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1585                 error "stripes not on specified OSTs"
1586
1587         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1588 }
1589 run_test 27cb "two stripes on specified OSTs"
1590
1591 test_27cc() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1594                 skip "server does not support overstriping"
1595
1596         test_mkdir -p $DIR/$tdir
1597         local osts="0,0"
1598         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1599         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1600         echo "$getstripe"
1601
1602         # Strip getstripe output to a space separated list of OSTs
1603         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1604                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1605         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1606                 error "stripes not on specified OSTs"
1607
1608         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1609 }
1610 run_test 27cc "two stripes on the same OST"
1611
1612 test_27cd() {
1613         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1614         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1615                 skip "server does not support overstriping"
1616         test_mkdir -p $DIR/$tdir
1617         local osts="0,1,1,0"
1618         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1619         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1620         echo "$getstripe"
1621
1622         # Strip getstripe output to a space separated list of OSTs
1623         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1624                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1625         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1626                 error "stripes not on specified OSTs"
1627
1628         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1629 }
1630 run_test 27cd "four stripes on two OSTs"
1631
1632 test_27ce() {
1633         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1634                 skip_env "too many osts, skipping"
1635         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1636                 skip "server does not support overstriping"
1637         # We do one more stripe than we have OSTs
1638         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1639                 skip_env "ea_inode feature disabled"
1640
1641         test_mkdir -p $DIR/$tdir
1642         local osts=""
1643         for i in $(seq 0 $OSTCOUNT);
1644         do
1645                 osts=$osts"0"
1646                 if [ $i -ne $OSTCOUNT ]; then
1647                         osts=$osts","
1648                 fi
1649         done
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27ce "more stripes than OSTs with -o"
1663
1664 test_27cf() {
1665         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1666         local pid=0
1667
1668         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1669         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1670         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1671         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1672                 error "failed to set $osp_proc=0"
1673
1674         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1675         pid=$!
1676         sleep 1
1677         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1678         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1679                 error "failed to set $osp_proc=1"
1680         wait $pid
1681         [[ $pid -ne 0 ]] ||
1682                 error "should return error due to $osp_proc=0"
1683 }
1684 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1685
1686 test_27d() {
1687         test_mkdir $DIR/$tdir
1688         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1689                 error "setstripe failed"
1690         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1691         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1692 }
1693 run_test 27d "create file with default settings"
1694
1695 test_27e() {
1696         # LU-5839 adds check for existed layout before setting it
1697         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1698                 skip "Need MDS version at least 2.7.56"
1699
1700         test_mkdir $DIR/$tdir
1701         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1702         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1703         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1704 }
1705 run_test 27e "setstripe existing file (should return error)"
1706
1707 test_27f() {
1708         test_mkdir $DIR/$tdir
1709         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1710                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1711         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1712                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1713         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1714         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1715 }
1716 run_test 27f "setstripe with bad stripe size (should return error)"
1717
1718 test_27g() {
1719         test_mkdir $DIR/$tdir
1720         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1721         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1722                 error "$DIR/$tdir/$tfile has object"
1723 }
1724 run_test 27g "$LFS getstripe with no objects"
1725
1726 test_27ga() {
1727         test_mkdir $DIR/$tdir
1728         touch $DIR/$tdir/$tfile || error "touch failed"
1729         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1730         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1731         local rc=$?
1732         (( rc == 2 )) || error "getstripe did not return ENOENT"
1733 }
1734 run_test 27ga "$LFS getstripe with missing file (should return error)"
1735
1736 test_27i() {
1737         test_mkdir $DIR/$tdir
1738         touch $DIR/$tdir/$tfile || error "touch failed"
1739         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1740                 error "missing objects"
1741 }
1742 run_test 27i "$LFS getstripe with some objects"
1743
1744 test_27j() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1747                 error "setstripe failed" || true
1748 }
1749 run_test 27j "setstripe with bad stripe offset (should return error)"
1750
1751 test_27k() { # bug 2844
1752         test_mkdir $DIR/$tdir
1753         local file=$DIR/$tdir/$tfile
1754         local ll_max_blksize=$((4 * 1024 * 1024))
1755         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1756         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1757         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1758         dd if=/dev/zero of=$file bs=4k count=1
1759         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1760         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1761 }
1762 run_test 27k "limit i_blksize for broken user apps"
1763
1764 test_27l() {
1765         mcreate $DIR/$tfile || error "creating file"
1766         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1767                 error "setstripe should have failed" || true
1768 }
1769 run_test 27l "check setstripe permissions (should return error)"
1770
1771 test_27m() {
1772         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1773
1774         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1775                 skip_env "multiple clients -- skipping"
1776
1777         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1778                    head -n1)
1779         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1780                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1781         fi
1782         trap simple_cleanup_common EXIT
1783         test_mkdir $DIR/$tdir
1784         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1785         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1786                 error "dd should fill OST0"
1787         i=2
1788         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1789                 i=$((i + 1))
1790                 [ $i -gt 256 ] && break
1791         done
1792         i=$((i + 1))
1793         touch $DIR/$tdir/$tfile.$i
1794         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1795             awk '{print $1}'| grep -w "0") ] &&
1796                 error "OST0 was full but new created file still use it"
1797         i=$((i + 1))
1798         touch $DIR/$tdir/$tfile.$i
1799         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1800             awk '{print $1}'| grep -w "0") ] &&
1801                 error "OST0 was full but new created file still use it"
1802         simple_cleanup_common
1803 }
1804 run_test 27m "create file while OST0 was full"
1805
1806 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1807 # if the OST isn't full anymore.
1808 reset_enospc() {
1809         local ostidx=${1:-""}
1810         local delay
1811         local ready
1812         local get_prealloc
1813
1814         local list=$(comma_list $(osts_nodes))
1815         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1816
1817         do_nodes $list lctl set_param fail_loc=0
1818         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1819         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1820                 awk '{print $1 * 2;exit;}')
1821         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1822                         grep -v \"^0$\""
1823         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1824 }
1825
1826 __exhaust_precreations() {
1827         local OSTIDX=$1
1828         local FAILLOC=$2
1829         local FAILIDX=${3:-$OSTIDX}
1830         local ofacet=ost$((OSTIDX + 1))
1831
1832         test_mkdir -p -c1 $DIR/$tdir
1833         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1834         local mfacet=mds$((mdtidx + 1))
1835         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1836
1837         local OST=$(ostname_from_index $OSTIDX)
1838
1839         # on the mdt's osc
1840         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1841         local last_id=$(do_facet $mfacet lctl get_param -n \
1842                         osp.$mdtosc_proc1.prealloc_last_id)
1843         local next_id=$(do_facet $mfacet lctl get_param -n \
1844                         osp.$mdtosc_proc1.prealloc_next_id)
1845
1846         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1847         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1848
1849         test_mkdir -p $DIR/$tdir/${OST}
1850         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1851 #define OBD_FAIL_OST_ENOSPC              0x215
1852         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1853         echo "Creating to objid $last_id on ost $OST..."
1854         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1855         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1856         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1857 }
1858
1859 exhaust_precreations() {
1860         __exhaust_precreations $1 $2 $3
1861         sleep_maxage
1862 }
1863
1864 exhaust_all_precreations() {
1865         local i
1866         for (( i=0; i < OSTCOUNT; i++ )) ; do
1867                 __exhaust_precreations $i $1 -1
1868         done
1869         sleep_maxage
1870 }
1871
1872 test_27n() {
1873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1875         remote_mds_nodsh && skip "remote MDS with nodsh"
1876         remote_ost_nodsh && skip "remote OST with nodsh"
1877
1878         reset_enospc
1879         rm -f $DIR/$tdir/$tfile
1880         exhaust_precreations 0 0x80000215
1881         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1882         touch $DIR/$tdir/$tfile || error "touch failed"
1883         $LFS getstripe $DIR/$tdir/$tfile
1884         reset_enospc
1885 }
1886 run_test 27n "create file with some full OSTs"
1887
1888 test_27o() {
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         exhaust_all_precreations 0x215
1897
1898         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1899
1900         reset_enospc
1901         rm -rf $DIR/$tdir/*
1902 }
1903 run_test 27o "create file with all full OSTs (should error)"
1904
1905 test_27p() {
1906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1908         remote_mds_nodsh && skip "remote MDS with nodsh"
1909         remote_ost_nodsh && skip "remote OST with nodsh"
1910
1911         reset_enospc
1912         rm -f $DIR/$tdir/$tfile
1913         test_mkdir $DIR/$tdir
1914
1915         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1916         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1917         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1918
1919         exhaust_precreations 0 0x80000215
1920         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1921         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1922         $LFS getstripe $DIR/$tdir/$tfile
1923
1924         reset_enospc
1925 }
1926 run_test 27p "append to a truncated file with some full OSTs"
1927
1928 test_27q() {
1929         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1931         remote_mds_nodsh && skip "remote MDS with nodsh"
1932         remote_ost_nodsh && skip "remote OST with nodsh"
1933
1934         reset_enospc
1935         rm -f $DIR/$tdir/$tfile
1936
1937         test_mkdir $DIR/$tdir
1938         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1939         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1940                 error "truncate $DIR/$tdir/$tfile failed"
1941         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1942
1943         exhaust_all_precreations 0x215
1944
1945         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1946         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1947
1948         reset_enospc
1949 }
1950 run_test 27q "append to truncated file with all OSTs full (should error)"
1951
1952 test_27r() {
1953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1955         remote_mds_nodsh && skip "remote MDS with nodsh"
1956         remote_ost_nodsh && skip "remote OST with nodsh"
1957
1958         reset_enospc
1959         rm -f $DIR/$tdir/$tfile
1960         exhaust_precreations 0 0x80000215
1961
1962         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1963
1964         reset_enospc
1965 }
1966 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1967
1968 test_27s() { # bug 10725
1969         test_mkdir $DIR/$tdir
1970         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1971         local stripe_count=0
1972         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1973         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1974                 error "stripe width >= 2^32 succeeded" || true
1975
1976 }
1977 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1978
1979 test_27t() { # bug 10864
1980         WDIR=$(pwd)
1981         WLFS=$(which lfs)
1982         cd $DIR
1983         touch $tfile
1984         $WLFS getstripe $tfile
1985         cd $WDIR
1986 }
1987 run_test 27t "check that utils parse path correctly"
1988
1989 test_27u() { # bug 4900
1990         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992
1993         local index
1994         local list=$(comma_list $(mdts_nodes))
1995
1996 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1997         do_nodes $list $LCTL set_param fail_loc=0x139
1998         test_mkdir -p $DIR/$tdir
1999         trap simple_cleanup_common EXIT
2000         createmany -o $DIR/$tdir/t- 1000
2001         do_nodes $list $LCTL set_param fail_loc=0
2002
2003         TLOG=$TMP/$tfile.getstripe
2004         $LFS getstripe $DIR/$tdir > $TLOG
2005         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2006         unlinkmany $DIR/$tdir/t- 1000
2007         trap 0
2008         [[ $OBJS -gt 0 ]] &&
2009                 error "$OBJS objects created on OST-0. See $TLOG" ||
2010                 rm -f $TLOG
2011 }
2012 run_test 27u "skip object creation on OSC w/o objects"
2013
2014 test_27v() { # bug 4900
2015         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2017         remote_mds_nodsh && skip "remote MDS with nodsh"
2018         remote_ost_nodsh && skip "remote OST with nodsh"
2019
2020         exhaust_all_precreations 0x215
2021         reset_enospc
2022
2023         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2024
2025         touch $DIR/$tdir/$tfile
2026         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2027         # all except ost1
2028         for (( i=1; i < OSTCOUNT; i++ )); do
2029                 do_facet ost$i lctl set_param fail_loc=0x705
2030         done
2031         local START=`date +%s`
2032         createmany -o $DIR/$tdir/$tfile 32
2033
2034         local FINISH=`date +%s`
2035         local TIMEOUT=`lctl get_param -n timeout`
2036         local PROCESS=$((FINISH - START))
2037         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2038                error "$FINISH - $START >= $TIMEOUT / 2"
2039         sleep $((TIMEOUT / 2 - PROCESS))
2040         reset_enospc
2041 }
2042 run_test 27v "skip object creation on slow OST"
2043
2044 test_27w() { # bug 10997
2045         test_mkdir $DIR/$tdir
2046         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2047         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2048                 error "stripe size $size != 65536" || true
2049         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2050                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2051 }
2052 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2053
2054 test_27wa() {
2055         [[ $OSTCOUNT -lt 2 ]] &&
2056                 skip_env "skipping multiple stripe count/offset test"
2057
2058         test_mkdir $DIR/$tdir
2059         for i in $(seq 1 $OSTCOUNT); do
2060                 offset=$((i - 1))
2061                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2062                         error "setstripe -c $i -i $offset failed"
2063                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2064                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2065                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2066                 [ $index -ne $offset ] &&
2067                         error "stripe offset $index != $offset" || true
2068         done
2069 }
2070 run_test 27wa "check $LFS setstripe -c -i options"
2071
2072 test_27x() {
2073         remote_ost_nodsh && skip "remote OST with nodsh"
2074         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2076
2077         OFFSET=$(($OSTCOUNT - 1))
2078         OSTIDX=0
2079         local OST=$(ostname_from_index $OSTIDX)
2080
2081         test_mkdir $DIR/$tdir
2082         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2083         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2084         sleep_maxage
2085         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2086         for i in $(seq 0 $OFFSET); do
2087                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2088                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2089                 error "OST0 was degraded but new created file still use it"
2090         done
2091         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2092 }
2093 run_test 27x "create files while OST0 is degraded"
2094
2095 test_27y() {
2096         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2097         remote_mds_nodsh && skip "remote MDS with nodsh"
2098         remote_ost_nodsh && skip "remote OST with nodsh"
2099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2100
2101         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2102         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2103                 osp.$mdtosc.prealloc_last_id)
2104         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2105                 osp.$mdtosc.prealloc_next_id)
2106         local fcount=$((last_id - next_id))
2107         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2108         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2109
2110         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2111                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2112         local OST_DEACTIVE_IDX=-1
2113         local OSC
2114         local OSTIDX
2115         local OST
2116
2117         for OSC in $MDS_OSCS; do
2118                 OST=$(osc_to_ost $OSC)
2119                 OSTIDX=$(index_from_ostuuid $OST)
2120                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2121                         OST_DEACTIVE_IDX=$OSTIDX
2122                 fi
2123                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2124                         echo $OSC "is Deactivated:"
2125                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2126                 fi
2127         done
2128
2129         OSTIDX=$(index_from_ostuuid $OST)
2130         test_mkdir $DIR/$tdir
2131         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2132
2133         for OSC in $MDS_OSCS; do
2134                 OST=$(osc_to_ost $OSC)
2135                 OSTIDX=$(index_from_ostuuid $OST)
2136                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2137                         echo $OST "is degraded:"
2138                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2139                                                 obdfilter.$OST.degraded=1
2140                 fi
2141         done
2142
2143         sleep_maxage
2144         createmany -o $DIR/$tdir/$tfile $fcount
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2150                         echo $OST "is recovered from degraded:"
2151                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2152                                                 obdfilter.$OST.degraded=0
2153                 else
2154                         do_facet $SINGLEMDS lctl --device %$OSC activate
2155                 fi
2156         done
2157
2158         # all osp devices get activated, hence -1 stripe count restored
2159         local stripe_count=0
2160
2161         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2162         # devices get activated.
2163         sleep_maxage
2164         $LFS setstripe -c -1 $DIR/$tfile
2165         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2166         rm -f $DIR/$tfile
2167         [ $stripe_count -ne $OSTCOUNT ] &&
2168                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2169         return 0
2170 }
2171 run_test 27y "create files while OST0 is degraded and the rest inactive"
2172
2173 check_seq_oid()
2174 {
2175         log "check file $1"
2176
2177         lmm_count=$($LFS getstripe -c $1)
2178         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2179         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2180
2181         local old_ifs="$IFS"
2182         IFS=$'[:]'
2183         fid=($($LFS path2fid $1))
2184         IFS="$old_ifs"
2185
2186         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2187         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2188
2189         # compare lmm_seq and lu_fid->f_seq
2190         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2191         # compare lmm_object_id and lu_fid->oid
2192         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2193
2194         # check the trusted.fid attribute of the OST objects of the file
2195         local have_obdidx=false
2196         local stripe_nr=0
2197         $LFS getstripe $1 | while read obdidx oid hex seq; do
2198                 # skip lines up to and including "obdidx"
2199                 [ -z "$obdidx" ] && break
2200                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2201                 $have_obdidx || continue
2202
2203                 local ost=$((obdidx + 1))
2204                 local dev=$(ostdevname $ost)
2205                 local oid_hex
2206
2207                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2208
2209                 seq=$(echo $seq | sed -e "s/^0x//g")
2210                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2211                         oid_hex=$(echo $oid)
2212                 else
2213                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2214                 fi
2215                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2216
2217                 local ff=""
2218                 #
2219                 # Don't unmount/remount the OSTs if we don't need to do that.
2220                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2221                 # update too, until that use mount/ll_decode_filter_fid/mount.
2222                 # Re-enable when debugfs will understand new filter_fid.
2223                 #
2224                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2225                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2226                                 $dev 2>/dev/null" | grep "parent=")
2227                 fi
2228                 if [ -z "$ff" ]; then
2229                         stop ost$ost
2230                         mount_fstype ost$ost
2231                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2232                                 $(facet_mntpt ost$ost)/$obj_file)
2233                         unmount_fstype ost$ost
2234                         start ost$ost $dev $OST_MOUNT_OPTS
2235                         clients_up
2236                 fi
2237
2238                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2239
2240                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2241
2242                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2243                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2244                 #
2245                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2246                 #       stripe_size=1048576 component_id=1 component_start=0 \
2247                 #       component_end=33554432
2248                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2249                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2250                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2251                 local ff_pstripe
2252                 if grep -q 'stripe=' <<<$ff; then
2253                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2254                 else
2255                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2256                         # into f_ver in this case.  See comment on ff_parent.
2257                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2258                 fi
2259
2260                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2261                 [ $ff_pseq = $lmm_seq ] ||
2262                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2263                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2264                 [ $ff_poid = $lmm_oid ] ||
2265                         error "FF parent OID $ff_poid != $lmm_oid"
2266                 (($ff_pstripe == $stripe_nr)) ||
2267                         error "FF stripe $ff_pstripe != $stripe_nr"
2268
2269                 stripe_nr=$((stripe_nr + 1))
2270                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2271                         continue
2272                 if grep -q 'stripe_count=' <<<$ff; then
2273                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2274                                             -e 's/ .*//' <<<$ff)
2275                         [ $lmm_count = $ff_scnt ] ||
2276                                 error "FF stripe count $lmm_count != $ff_scnt"
2277                 fi
2278         done
2279 }
2280
2281 test_27z() {
2282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2283         remote_ost_nodsh && skip "remote OST with nodsh"
2284
2285         test_mkdir $DIR/$tdir
2286         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2287                 { error "setstripe -c -1 failed"; return 1; }
2288         # We need to send a write to every object to get parent FID info set.
2289         # This _should_ also work for setattr, but does not currently.
2290         # touch $DIR/$tdir/$tfile-1 ||
2291         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2292                 { error "dd $tfile-1 failed"; return 2; }
2293         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2294                 { error "setstripe -c -1 failed"; return 3; }
2295         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2296                 { error "dd $tfile-2 failed"; return 4; }
2297
2298         # make sure write RPCs have been sent to OSTs
2299         sync; sleep 5; sync
2300
2301         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2302         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2303 }
2304 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2305
2306 test_27A() { # b=19102
2307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2308
2309         save_layout_restore_at_exit $MOUNT
2310         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2311         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2312                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2313         local default_size=$($LFS getstripe -S $MOUNT)
2314         local default_offset=$($LFS getstripe -i $MOUNT)
2315         local dsize=$(do_facet $SINGLEMDS \
2316                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2317         [ $default_size -eq $dsize ] ||
2318                 error "stripe size $default_size != $dsize"
2319         [ $default_offset -eq -1 ] ||
2320                 error "stripe offset $default_offset != -1"
2321 }
2322 run_test 27A "check filesystem-wide default LOV EA values"
2323
2324 test_27B() { # LU-2523
2325         test_mkdir $DIR/$tdir
2326         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2327         touch $DIR/$tdir/f0
2328         # open f1 with O_LOV_DELAY_CREATE
2329         # rename f0 onto f1
2330         # call setstripe ioctl on open file descriptor for f1
2331         # close
2332         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2333                 $DIR/$tdir/f0
2334
2335         rm -f $DIR/$tdir/f1
2336         # open f1 with O_LOV_DELAY_CREATE
2337         # unlink f1
2338         # call setstripe ioctl on open file descriptor for f1
2339         # close
2340         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2341
2342         # Allow multiop to fail in imitation of NFS's busted semantics.
2343         true
2344 }
2345 run_test 27B "call setstripe on open unlinked file/rename victim"
2346
2347 # 27C family tests full striping and overstriping
2348 test_27Ca() { #LU-2871
2349         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2350
2351         declare -a ost_idx
2352         local index
2353         local found
2354         local i
2355         local j
2356
2357         test_mkdir $DIR/$tdir
2358         cd $DIR/$tdir
2359         for i in $(seq 0 $((OSTCOUNT - 1))); do
2360                 # set stripe across all OSTs starting from OST$i
2361                 $LFS setstripe -i $i -c -1 $tfile$i
2362                 # get striping information
2363                 ost_idx=($($LFS getstripe $tfile$i |
2364                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2365                 echo ${ost_idx[@]}
2366
2367                 # check the layout
2368                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2369                         error "${#ost_idx[@]} != $OSTCOUNT"
2370
2371                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2372                         found=0
2373                         for j in $(echo ${ost_idx[@]}); do
2374                                 if [ $index -eq $j ]; then
2375                                         found=1
2376                                         break
2377                                 fi
2378                         done
2379                         [ $found = 1 ] ||
2380                                 error "Can not find $index in ${ost_idx[@]}"
2381                 done
2382         done
2383 }
2384 run_test 27Ca "check full striping across all OSTs"
2385
2386 test_27Cb() {
2387         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2388                 skip "server does not support overstriping"
2389         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2390                 skip_env "too many osts, skipping"
2391
2392         test_mkdir -p $DIR/$tdir
2393         local setcount=$(($OSTCOUNT * 2))
2394         [ $setcount -ge 160 ] || large_xattr_enabled ||
2395                 skip_env "ea_inode feature disabled"
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2405                 error "overstriped should be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409 }
2410 run_test 27Cb "more stripes than OSTs with -C"
2411
2412 test_27Cc() {
2413         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2414                 skip "server does not support overstriping"
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2416
2417         test_mkdir -p $DIR/$tdir
2418         local setcount=$(($OSTCOUNT - 1))
2419
2420         [ $setcount -ge 160 ] || large_xattr_enabled ||
2421                 skip_env "ea_inode feature disabled"
2422
2423         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2424                 error "setstripe failed"
2425
2426         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2427         [ $count -eq $setcount ] ||
2428                 error "stripe count $count, should be $setcount"
2429
2430         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2431                 error "overstriped should not be set in pattern"
2432
2433         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2434                 error "dd failed"
2435 }
2436 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2437
2438 test_27Cd() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2442         large_xattr_enabled || skip_env "ea_inode feature disabled"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$LOV_MAX_STRIPE_COUNT
2446
2447         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2448                 error "setstripe failed"
2449
2450         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2451         [ $count -eq $setcount ] ||
2452                 error "stripe count $count, should be $setcount"
2453
2454         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2455                 error "overstriped should be set in pattern"
2456
2457         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2458                 error "dd failed"
2459
2460         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2461 }
2462 run_test 27Cd "test maximum stripe count"
2463
2464 test_27Ce() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         test_mkdir -p $DIR/$tdir
2468
2469         pool_add $TESTNAME || error "Pool creation failed"
2470         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2471
2472         local setcount=8
2473
2474         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2475                 error "setstripe failed"
2476
2477         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2478         [ $count -eq $setcount ] ||
2479                 error "stripe count $count, should be $setcount"
2480
2481         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2482                 error "overstriped should be set in pattern"
2483
2484         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2485                 error "dd failed"
2486
2487         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2488 }
2489 run_test 27Ce "test pool with overstriping"
2490
2491 test_27Cf() {
2492         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2493                 skip "server does not support overstriping"
2494         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2495                 skip_env "too many osts, skipping"
2496
2497         test_mkdir -p $DIR/$tdir
2498
2499         local setcount=$(($OSTCOUNT * 2))
2500         [ $setcount -ge 160 ] || large_xattr_enabled ||
2501                 skip_env "ea_inode feature disabled"
2502
2503         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2504                 error "setstripe failed"
2505
2506         echo 1 > $DIR/$tdir/$tfile
2507
2508         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2509         [ $count -eq $setcount ] ||
2510                 error "stripe count $count, should be $setcount"
2511
2512         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2513                 error "overstriped should be set in pattern"
2514
2515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2516                 error "dd failed"
2517
2518         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2519 }
2520 run_test 27Cf "test default inheritance with overstriping"
2521
2522 test_27D() {
2523         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2524         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2525         remote_mds_nodsh && skip "remote MDS with nodsh"
2526
2527         local POOL=${POOL:-testpool}
2528         local first_ost=0
2529         local last_ost=$(($OSTCOUNT - 1))
2530         local ost_step=1
2531         local ost_list=$(seq $first_ost $ost_step $last_ost)
2532         local ost_range="$first_ost $last_ost $ost_step"
2533
2534         test_mkdir $DIR/$tdir
2535         pool_add $POOL || error "pool_add failed"
2536         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2537
2538         local skip27D
2539         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2540                 skip27D+="-s 29"
2541         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2542                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2543                         skip27D+=" -s 30,31"
2544         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2545           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2546                 skip27D+=" -s 32,33"
2547         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2548                 skip27D+=" -s 34"
2549         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2550                 error "llapi_layout_test failed"
2551
2552         destroy_test_pools || error "destroy test pools failed"
2553 }
2554 run_test 27D "validate llapi_layout API"
2555
2556 # Verify that default_easize is increased from its initial value after
2557 # accessing a widely striped file.
2558 test_27E() {
2559         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2560         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2561                 skip "client does not have LU-3338 fix"
2562
2563         # 72 bytes is the minimum space required to store striping
2564         # information for a file striped across one OST:
2565         # (sizeof(struct lov_user_md_v3) +
2566         #  sizeof(struct lov_user_ost_data_v1))
2567         local min_easize=72
2568         $LCTL set_param -n llite.*.default_easize $min_easize ||
2569                 error "lctl set_param failed"
2570         local easize=$($LCTL get_param -n llite.*.default_easize)
2571
2572         [ $easize -eq $min_easize ] ||
2573                 error "failed to set default_easize"
2574
2575         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2576                 error "setstripe failed"
2577         # In order to ensure stat() call actually talks to MDS we need to
2578         # do something drastic to this file to shake off all lock, e.g.
2579         # rename it (kills lookup lock forcing cache cleaning)
2580         mv $DIR/$tfile $DIR/${tfile}-1
2581         ls -l $DIR/${tfile}-1
2582         rm $DIR/${tfile}-1
2583
2584         easize=$($LCTL get_param -n llite.*.default_easize)
2585
2586         [ $easize -gt $min_easize ] ||
2587                 error "default_easize not updated"
2588 }
2589 run_test 27E "check that default extended attribute size properly increases"
2590
2591 test_27F() { # LU-5346/LU-7975
2592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2593         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2594         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2595                 skip "Need MDS version at least 2.8.51"
2596         remote_ost_nodsh && skip "remote OST with nodsh"
2597
2598         test_mkdir $DIR/$tdir
2599         rm -f $DIR/$tdir/f0
2600         $LFS setstripe -c 2 $DIR/$tdir
2601
2602         # stop all OSTs to reproduce situation for LU-7975 ticket
2603         for num in $(seq $OSTCOUNT); do
2604                 stop ost$num
2605         done
2606
2607         # open/create f0 with O_LOV_DELAY_CREATE
2608         # truncate f0 to a non-0 size
2609         # close
2610         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2611
2612         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2613         # open/write it again to force delayed layout creation
2614         cat /etc/hosts > $DIR/$tdir/f0 &
2615         catpid=$!
2616
2617         # restart OSTs
2618         for num in $(seq $OSTCOUNT); do
2619                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2620                         error "ost$num failed to start"
2621         done
2622
2623         wait $catpid || error "cat failed"
2624
2625         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2626         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2627                 error "wrong stripecount"
2628
2629 }
2630 run_test 27F "Client resend delayed layout creation with non-zero size"
2631
2632 test_27G() { #LU-10629
2633         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2634                 skip "Need MDS version at least 2.11.51"
2635         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2636         remote_mds_nodsh && skip "remote MDS with nodsh"
2637         local POOL=${POOL:-testpool}
2638         local ostrange="0 0 1"
2639
2640         test_mkdir $DIR/$tdir
2641         touch $DIR/$tdir/$tfile.nopool
2642         pool_add $POOL || error "pool_add failed"
2643         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2644         $LFS setstripe -p $POOL $DIR/$tdir
2645
2646         local pool=$($LFS getstripe -p $DIR/$tdir)
2647
2648         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2649         touch $DIR/$tdir/$tfile.default
2650         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2651         $LFS find $DIR/$tdir -type f --pool $POOL
2652         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2653         [[ "$found" == "2" ]] ||
2654                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2655
2656         $LFS setstripe -d $DIR/$tdir
2657
2658         pool=$($LFS getstripe -p -d $DIR/$tdir)
2659
2660         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2661 }
2662 run_test 27G "Clear OST pool from stripe"
2663
2664 test_27H() {
2665         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2666                 skip "Need MDS version newer than 2.11.54"
2667         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2668         test_mkdir $DIR/$tdir
2669         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2670         touch $DIR/$tdir/$tfile
2671         $LFS getstripe -c $DIR/$tdir/$tfile
2672         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2673                 error "two-stripe file doesn't have two stripes"
2674
2675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2676         $LFS getstripe -y $DIR/$tdir/$tfile
2677         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2678              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2679                 error "expected l_ost_idx: [02]$ not matched"
2680
2681         # make sure ost list has been cleared
2682         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2683         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2684                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2685         touch $DIR/$tdir/f3
2686         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2687 }
2688 run_test 27H "Set specific OSTs stripe"
2689
2690 test_27I() {
2691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2692         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2693         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2694                 skip "Need MDS version newer than 2.12.52"
2695         local pool=$TESTNAME
2696         local ostrange="1 1 1"
2697
2698         save_layout_restore_at_exit $MOUNT
2699         $LFS setstripe -c 2 -i 0 $MOUNT
2700         pool_add $pool || error "pool_add failed"
2701         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -p $pool $DIR/$tdir
2704         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2705         $LFS getstripe $DIR/$tdir/$tfile
2706 }
2707 run_test 27I "check that root dir striping does not break parent dir one"
2708
2709 test_27J() {
2710         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2711                 skip "Need MDS version newer than 2.12.51"
2712
2713         test_mkdir $DIR/$tdir
2714         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2715         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2716
2717         # create foreign file (raw way)
2718         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2719                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2720
2721         # verify foreign file (raw way)
2722         parse_foreign_file -f $DIR/$tdir/$tfile |
2723                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2724                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2725         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2726                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2727         parse_foreign_file -f $DIR/$tdir/$tfile |
2728                 grep "lov_foreign_size: 73" ||
2729                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2730         parse_foreign_file -f $DIR/$tdir/$tfile |
2731                 grep "lov_foreign_type: 1" ||
2732                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2733         parse_foreign_file -f $DIR/$tdir/$tfile |
2734                 grep "lov_foreign_flags: 0x0000DA08" ||
2735                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2736         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2737                 grep "lov_foreign_value: 0x" |
2738                 sed -e 's/lov_foreign_value: 0x//')
2739         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2740         [[ $lov = ${lov2// /} ]] ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2742
2743         # create foreign file (lfs + API)
2744         $LFS setstripe --foreign=daos --flags 0xda08 \
2745                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2746                 error "$DIR/$tdir/${tfile}2: create failed"
2747
2748         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2749                 grep "lfm_magic:.*0x0BD70BD0" ||
2750                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2751         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2752         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2753                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2754         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2755                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2756         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2757                 grep "lfm_flags:.*0x0000DA08" ||
2758                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2759         $LFS getstripe $DIR/$tdir/${tfile}2 |
2760                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2761                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2762
2763         # modify striping should fail
2764         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2765                 error "$DIR/$tdir/$tfile: setstripe should fail"
2766         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2767                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2768
2769         # R/W should fail
2770         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2771         cat $DIR/$tdir/${tfile}2 &&
2772                 error "$DIR/$tdir/${tfile}2: read should fail"
2773         cat /etc/passwd > $DIR/$tdir/$tfile &&
2774                 error "$DIR/$tdir/$tfile: write should fail"
2775         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2776                 error "$DIR/$tdir/${tfile}2: write should fail"
2777
2778         # chmod should work
2779         chmod 222 $DIR/$tdir/$tfile ||
2780                 error "$DIR/$tdir/$tfile: chmod failed"
2781         chmod 222 $DIR/$tdir/${tfile}2 ||
2782                 error "$DIR/$tdir/${tfile}2: chmod failed"
2783
2784         # chown should work
2785         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2786                 error "$DIR/$tdir/$tfile: chown failed"
2787         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2788                 error "$DIR/$tdir/${tfile}2: chown failed"
2789
2790         # rename should work
2791         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2792                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2793         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2794                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2795
2796         #remove foreign file
2797         rm $DIR/$tdir/${tfile}.new ||
2798                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2799         rm $DIR/$tdir/${tfile}2.new ||
2800                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2801 }
2802 run_test 27J "basic ops on file with foreign LOV"
2803
2804 test_27K() {
2805         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2806                 skip "Need MDS version newer than 2.12.49"
2807
2808         test_mkdir $DIR/$tdir
2809         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2810         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2811
2812         # create foreign dir (raw way)
2813         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2814                 error "create_foreign_dir FAILED"
2815
2816         # verify foreign dir (raw way)
2817         parse_foreign_dir -d $DIR/$tdir/$tdir |
2818                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2819                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2820         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2821                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2822         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2823                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2824         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2825                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2826         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2827                 grep "lmv_foreign_value: 0x" |
2828                 sed 's/lmv_foreign_value: 0x//')
2829         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2830                 sed 's/ //g')
2831         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2832
2833         # create foreign dir (lfs + API)
2834         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2835                 $DIR/$tdir/${tdir}2 ||
2836                 error "$DIR/$tdir/${tdir}2: create failed"
2837
2838         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2839                 grep "lfm_magic:.*0x0CD50CD0" ||
2840                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2841         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2842         # - sizeof(lfm_type) - sizeof(lfm_flags)
2843         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2844                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2845         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2846                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2847         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2848                 grep "lfm_flags:.*0x0000DA05" ||
2849                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2850         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2851                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2852                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2853
2854         # file create in dir should fail
2855         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2856         touch $DIR/$tdir/${tdir}2/$tfile &&
2857                 "$DIR/${tdir}2: file create should fail"
2858
2859         # chmod should work
2860         chmod 777 $DIR/$tdir/$tdir ||
2861                 error "$DIR/$tdir: chmod failed"
2862         chmod 777 $DIR/$tdir/${tdir}2 ||
2863                 error "$DIR/${tdir}2: chmod failed"
2864
2865         # chown should work
2866         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2867                 error "$DIR/$tdir: chown failed"
2868         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2869                 error "$DIR/${tdir}2: chown failed"
2870
2871         # rename should work
2872         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2873                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2874         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2875                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2876
2877         #remove foreign dir
2878         rmdir $DIR/$tdir/${tdir}.new ||
2879                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2880         rmdir $DIR/$tdir/${tdir}2.new ||
2881                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2882 }
2883 run_test 27K "basic ops on dir with foreign LMV"
2884
2885 test_27L() {
2886         remote_mds_nodsh && skip "remote MDS with nodsh"
2887
2888         local POOL=${POOL:-$TESTNAME}
2889
2890         pool_add $POOL || error "pool_add failed"
2891
2892         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2893                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2894                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2895 }
2896 run_test 27L "lfs pool_list gives correct pool name"
2897
2898 test_27M() {
2899         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2900                 skip "Need MDS version >= than 2.12.57"
2901         remote_mds_nodsh && skip "remote MDS with nodsh"
2902         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2903
2904         test_mkdir $DIR/$tdir
2905
2906         # Set default striping on directory
2907         $LFS setstripe -C 4 $DIR/$tdir
2908
2909         echo 1 > $DIR/$tdir/${tfile}.1
2910         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2911         local setcount=4
2912         [ $count -eq $setcount ] ||
2913                 error "(1) stripe count $count, should be $setcount"
2914
2915         # Capture existing append_stripe_count setting for restore
2916         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2917         local mdts=$(comma_list $(mdts_nodes))
2918         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2919
2920         local appendcount=$orig_count
2921         echo 1 >> $DIR/$tdir/${tfile}.2_append
2922         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2923         [ $count -eq $appendcount ] ||
2924                 error "(2)stripe count $count, should be $appendcount for append"
2925
2926         # Disable O_APPEND striping, verify it works
2927         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2928
2929         # Should now get the default striping, which is 4
2930         setcount=4
2931         echo 1 >> $DIR/$tdir/${tfile}.3_append
2932         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2933         [ $count -eq $setcount ] ||
2934                 error "(3) stripe count $count, should be $setcount"
2935
2936         # Try changing the stripe count for append files
2937         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2938
2939         # Append striping is now 2 (directory default is still 4)
2940         appendcount=2
2941         echo 1 >> $DIR/$tdir/${tfile}.4_append
2942         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2943         [ $count -eq $appendcount ] ||
2944                 error "(4) stripe count $count, should be $appendcount for append"
2945
2946         # Test append stripe count of -1
2947         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2948         appendcount=$OSTCOUNT
2949         echo 1 >> $DIR/$tdir/${tfile}.5
2950         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2951         [ $count -eq $appendcount ] ||
2952                 error "(5) stripe count $count, should be $appendcount for append"
2953
2954         # Set append striping back to default of 1
2955         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2956
2957         # Try a new default striping, PFL + DOM
2958         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2959
2960         # Create normal DOM file, DOM returns stripe count == 0
2961         setcount=0
2962         touch $DIR/$tdir/${tfile}.6
2963         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2964         [ $count -eq $setcount ] ||
2965                 error "(6) stripe count $count, should be $setcount"
2966
2967         # Show
2968         appendcount=1
2969         echo 1 >> $DIR/$tdir/${tfile}.7_append
2970         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2971         [ $count -eq $appendcount ] ||
2972                 error "(7) stripe count $count, should be $appendcount for append"
2973
2974         # Clean up DOM layout
2975         $LFS setstripe -d $DIR/$tdir
2976
2977         # Now test that append striping works when layout is from root
2978         $LFS setstripe -c 2 $MOUNT
2979         # Make a special directory for this
2980         mkdir $DIR/${tdir}/${tdir}.2
2981         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2982
2983         # Verify for normal file
2984         setcount=2
2985         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2986         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2987         [ $count -eq $setcount ] ||
2988                 error "(8) stripe count $count, should be $setcount"
2989
2990         appendcount=1
2991         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2992         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2993         [ $count -eq $appendcount ] ||
2994                 error "(9) stripe count $count, should be $appendcount for append"
2995
2996         # Now test O_APPEND striping with pools
2997         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2999
3000         # Create the pool
3001         pool_add $TESTNAME || error "pool creation failed"
3002         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3003
3004         echo 1 >> $DIR/$tdir/${tfile}.10_append
3005
3006         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3007         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3008
3009         # Check that count is still correct
3010         appendcount=1
3011         echo 1 >> $DIR/$tdir/${tfile}.11_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3013         [ $count -eq $appendcount ] ||
3014                 error "(11) stripe count $count, should be $appendcount for append"
3015
3016         # Disable O_APPEND stripe count, verify pool works separately
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3018
3019         echo 1 >> $DIR/$tdir/${tfile}.12_append
3020
3021         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3022         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3023
3024         # Remove pool setting, verify it's not applied
3025         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3026
3027         echo 1 >> $DIR/$tdir/${tfile}.13_append
3028
3029         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3030         [ "$pool" = "" ] || error "(13) pool found: $pool"
3031 }
3032 run_test 27M "test O_APPEND striping"
3033
3034 test_27N() {
3035         combined_mgs_mds && skip "needs separate MGS/MDT"
3036
3037         pool_add $TESTNAME || error "pool_add failed"
3038         do_facet mgs "$LCTL pool_list $FSNAME" |
3039                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3040                 error "lctl pool_list on MGS failed"
3041 }
3042 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3043
3044 # createtest also checks that device nodes are created and
3045 # then visible correctly (#2091)
3046 test_28() { # bug 2091
3047         test_mkdir $DIR/d28
3048         $CREATETEST $DIR/d28/ct || error "createtest failed"
3049 }
3050 run_test 28 "create/mknod/mkdir with bad file types ============"
3051
3052 test_29() {
3053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3054
3055         sync; sleep 1; sync # flush out any dirty pages from previous tests
3056         cancel_lru_locks
3057         test_mkdir $DIR/d29
3058         touch $DIR/d29/foo
3059         log 'first d29'
3060         ls -l $DIR/d29
3061
3062         declare -i LOCKCOUNTORIG=0
3063         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3064                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3065         done
3066         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3067
3068         declare -i LOCKUNUSEDCOUNTORIG=0
3069         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3070                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3071         done
3072
3073         log 'second d29'
3074         ls -l $DIR/d29
3075         log 'done'
3076
3077         declare -i LOCKCOUNTCURRENT=0
3078         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3079                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3080         done
3081
3082         declare -i LOCKUNUSEDCOUNTCURRENT=0
3083         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3084                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3085         done
3086
3087         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3088                 $LCTL set_param -n ldlm.dump_namespaces ""
3089                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3090                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3091                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3092                 return 2
3093         fi
3094         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3095                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3096                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3097                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3098                 return 3
3099         fi
3100 }
3101 run_test 29 "IT_GETATTR regression  ============================"
3102
3103 test_30a() { # was test_30
3104         cp $(which ls) $DIR || cp /bin/ls $DIR
3105         $DIR/ls / || error "Can't execute binary from lustre"
3106         rm $DIR/ls
3107 }
3108 run_test 30a "execute binary from Lustre (execve) =============="
3109
3110 test_30b() {
3111         cp `which ls` $DIR || cp /bin/ls $DIR
3112         chmod go+rx $DIR/ls
3113         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3114         rm $DIR/ls
3115 }
3116 run_test 30b "execute binary from Lustre as non-root ==========="
3117
3118 test_30c() { # b=22376
3119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3120
3121         cp $(which ls) $DIR || cp /bin/ls $DIR
3122         chmod a-rw $DIR/ls
3123         cancel_lru_locks mdc
3124         cancel_lru_locks osc
3125         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3126         rm -f $DIR/ls
3127 }
3128 run_test 30c "execute binary from Lustre without read perms ===="
3129
3130 test_30d() {
3131         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3132
3133         for i in {1..10}; do
3134                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3135                 local PID=$!
3136                 sleep 1
3137                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3138                 wait $PID || error "executing dd from Lustre failed"
3139                 rm -f $DIR/$tfile
3140         done
3141
3142         rm -f $DIR/dd
3143 }
3144 run_test 30d "execute binary from Lustre while clear locks"
3145
3146 test_31a() {
3147         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3148         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3149 }
3150 run_test 31a "open-unlink file =================================="
3151
3152 test_31b() {
3153         touch $DIR/f31 || error "touch $DIR/f31 failed"
3154         ln $DIR/f31 $DIR/f31b || error "ln failed"
3155         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3156         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3157 }
3158 run_test 31b "unlink file with multiple links while open ======="
3159
3160 test_31c() {
3161         touch $DIR/f31 || error "touch $DIR/f31 failed"
3162         ln $DIR/f31 $DIR/f31c || error "ln failed"
3163         multiop_bg_pause $DIR/f31 O_uc ||
3164                 error "multiop_bg_pause for $DIR/f31 failed"
3165         MULTIPID=$!
3166         $MULTIOP $DIR/f31c Ouc
3167         kill -USR1 $MULTIPID
3168         wait $MULTIPID
3169 }
3170 run_test 31c "open-unlink file with multiple links ============="
3171
3172 test_31d() {
3173         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3174         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3175 }
3176 run_test 31d "remove of open directory ========================="
3177
3178 test_31e() { # bug 2904
3179         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3180 }
3181 run_test 31e "remove of open non-empty directory ==============="
3182
3183 test_31f() { # bug 4554
3184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3185
3186         set -vx
3187         test_mkdir $DIR/d31f
3188         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3189         cp /etc/hosts $DIR/d31f
3190         ls -l $DIR/d31f
3191         $LFS getstripe $DIR/d31f/hosts
3192         multiop_bg_pause $DIR/d31f D_c || return 1
3193         MULTIPID=$!
3194
3195         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3196         test_mkdir $DIR/d31f
3197         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3198         cp /etc/hosts $DIR/d31f
3199         ls -l $DIR/d31f
3200         $LFS getstripe $DIR/d31f/hosts
3201         multiop_bg_pause $DIR/d31f D_c || return 1
3202         MULTIPID2=$!
3203
3204         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3205         wait $MULTIPID || error "first opendir $MULTIPID failed"
3206
3207         sleep 6
3208
3209         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3210         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3211         set +vx
3212 }
3213 run_test 31f "remove of open directory with open-unlink file ==="
3214
3215 test_31g() {
3216         echo "-- cross directory link --"
3217         test_mkdir -c1 $DIR/${tdir}ga
3218         test_mkdir -c1 $DIR/${tdir}gb
3219         touch $DIR/${tdir}ga/f
3220         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3221         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3222         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3223         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3224         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3225 }
3226 run_test 31g "cross directory link==============="
3227
3228 test_31h() {
3229         echo "-- cross directory link --"
3230         test_mkdir -c1 $DIR/${tdir}
3231         test_mkdir -c1 $DIR/${tdir}/dir
3232         touch $DIR/${tdir}/f
3233         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3234         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3235         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3236         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3237         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3238 }
3239 run_test 31h "cross directory link under child==============="
3240
3241 test_31i() {
3242         echo "-- cross directory link --"
3243         test_mkdir -c1 $DIR/$tdir
3244         test_mkdir -c1 $DIR/$tdir/dir
3245         touch $DIR/$tdir/dir/f
3246         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3247         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3248         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3249         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3250         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3251 }
3252 run_test 31i "cross directory link under parent==============="
3253
3254 test_31j() {
3255         test_mkdir -c1 -p $DIR/$tdir
3256         test_mkdir -c1 -p $DIR/$tdir/dir1
3257         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3258         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3259         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3260         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3261         return 0
3262 }
3263 run_test 31j "link for directory==============="
3264
3265 test_31k() {
3266         test_mkdir -c1 -p $DIR/$tdir
3267         touch $DIR/$tdir/s
3268         touch $DIR/$tdir/exist
3269         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3270         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3271         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3272         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3273         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3274         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3275         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3276         return 0
3277 }
3278 run_test 31k "link to file: the same, non-existing, dir==============="
3279
3280 test_31m() {
3281         mkdir $DIR/d31m
3282         touch $DIR/d31m/s
3283         mkdir $DIR/d31m2
3284         touch $DIR/d31m2/exist
3285         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3286         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3287         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3288         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3289         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3290         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3291         return 0
3292 }
3293 run_test 31m "link to file: the same, non-existing, dir==============="
3294
3295 test_31n() {
3296         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3297         nlink=$(stat --format=%h $DIR/$tfile)
3298         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3299         local fd=$(free_fd)
3300         local cmd="exec $fd<$DIR/$tfile"
3301         eval $cmd
3302         cmd="exec $fd<&-"
3303         trap "eval $cmd" EXIT
3304         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3305         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3306         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3307         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3308         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3309         eval $cmd
3310 }
3311 run_test 31n "check link count of unlinked file"
3312
3313 link_one() {
3314         local tempfile=$(mktemp $1_XXXXXX)
3315         mlink $tempfile $1 2> /dev/null &&
3316                 echo "$BASHPID: link $tempfile to $1 succeeded"
3317         munlink $tempfile
3318 }
3319
3320 test_31o() { # LU-2901
3321         test_mkdir $DIR/$tdir
3322         for LOOP in $(seq 100); do
3323                 rm -f $DIR/$tdir/$tfile*
3324                 for THREAD in $(seq 8); do
3325                         link_one $DIR/$tdir/$tfile.$LOOP &
3326                 done
3327                 wait
3328                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3329                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3330                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3331                         break || true
3332         done
3333 }
3334 run_test 31o "duplicate hard links with same filename"
3335
3336 test_31p() {
3337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3338
3339         test_mkdir $DIR/$tdir
3340         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3341         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3342
3343         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3344                 error "open unlink test1 failed"
3345         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3346                 error "open unlink test2 failed"
3347
3348         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3349                 error "test1 still exists"
3350         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3351                 error "test2 still exists"
3352 }
3353 run_test 31p "remove of open striped directory"
3354
3355 cleanup_test32_mount() {
3356         local rc=0
3357         trap 0
3358         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3359         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3360         losetup -d $loopdev || true
3361         rm -rf $DIR/$tdir
3362         return $rc
3363 }
3364
3365 test_32a() {
3366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3367
3368         echo "== more mountpoints and symlinks ================="
3369         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3370         trap cleanup_test32_mount EXIT
3371         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3372         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3373                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3374         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3375                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3376         cleanup_test32_mount
3377 }
3378 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3379
3380 test_32b() {
3381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3382
3383         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3384         trap cleanup_test32_mount EXIT
3385         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3386         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3387                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3388         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3389                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3390         cleanup_test32_mount
3391 }
3392 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3393
3394 test_32c() {
3395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3396
3397         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3398         trap cleanup_test32_mount EXIT
3399         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3400         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3401                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3402         test_mkdir -p $DIR/$tdir/d2/test_dir
3403         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3404                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3405         cleanup_test32_mount
3406 }
3407 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3408
3409 test_32d() {
3410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3411
3412         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3413         trap cleanup_test32_mount EXIT
3414         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3415         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3416                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3417         test_mkdir -p $DIR/$tdir/d2/test_dir
3418         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3419                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3420         cleanup_test32_mount
3421 }
3422 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3423
3424 test_32e() {
3425         rm -fr $DIR/$tdir
3426         test_mkdir -p $DIR/$tdir/tmp
3427         local tmp_dir=$DIR/$tdir/tmp
3428         ln -s $DIR/$tdir $tmp_dir/symlink11
3429         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3430         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3431         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3432 }
3433 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3434
3435 test_32f() {
3436         rm -fr $DIR/$tdir
3437         test_mkdir -p $DIR/$tdir/tmp
3438         local tmp_dir=$DIR/$tdir/tmp
3439         ln -s $DIR/$tdir $tmp_dir/symlink11
3440         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3441         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3442         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3443 }
3444 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3445
3446 test_32g() {
3447         local tmp_dir=$DIR/$tdir/tmp
3448         test_mkdir -p $tmp_dir
3449         test_mkdir $DIR/${tdir}2
3450         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3451         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3452         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3453         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3454         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3455         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3456 }
3457 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3458
3459 test_32h() {
3460         rm -fr $DIR/$tdir $DIR/${tdir}2
3461         tmp_dir=$DIR/$tdir/tmp
3462         test_mkdir -p $tmp_dir
3463         test_mkdir $DIR/${tdir}2
3464         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3465         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3466         ls $tmp_dir/symlink12 || error "listing symlink12"
3467         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3468 }
3469 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3470
3471 test_32i() {
3472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3473
3474         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3475         trap cleanup_test32_mount EXIT
3476         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3477         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3478                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3479         touch $DIR/$tdir/test_file
3480         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3481                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3482         cleanup_test32_mount
3483 }
3484 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3485
3486 test_32j() {
3487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3488
3489         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3490         trap cleanup_test32_mount EXIT
3491         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3492         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3493                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3494         touch $DIR/$tdir/test_file
3495         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3496                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3497         cleanup_test32_mount
3498 }
3499 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3500
3501 test_32k() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         rm -fr $DIR/$tdir
3505         trap cleanup_test32_mount EXIT
3506         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3507         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3508                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3509         test_mkdir -p $DIR/$tdir/d2
3510         touch $DIR/$tdir/d2/test_file || error "touch failed"
3511         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3512                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3513         cleanup_test32_mount
3514 }
3515 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3516
3517 test_32l() {
3518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3519
3520         rm -fr $DIR/$tdir
3521         trap cleanup_test32_mount EXIT
3522         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3523         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3524                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3525         test_mkdir -p $DIR/$tdir/d2
3526         touch $DIR/$tdir/d2/test_file || error "touch failed"
3527         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3528                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3529         cleanup_test32_mount
3530 }
3531 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3532
3533 test_32m() {
3534         rm -fr $DIR/d32m
3535         test_mkdir -p $DIR/d32m/tmp
3536         TMP_DIR=$DIR/d32m/tmp
3537         ln -s $DIR $TMP_DIR/symlink11
3538         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3539         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3540                 error "symlink11 not a link"
3541         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3542                 error "symlink01 not a link"
3543 }
3544 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3545
3546 test_32n() {
3547         rm -fr $DIR/d32n
3548         test_mkdir -p $DIR/d32n/tmp
3549         TMP_DIR=$DIR/d32n/tmp
3550         ln -s $DIR $TMP_DIR/symlink11
3551         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3552         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3553         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3554 }
3555 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3556
3557 test_32o() {
3558         touch $DIR/$tfile
3559         test_mkdir -p $DIR/d32o/tmp
3560         TMP_DIR=$DIR/d32o/tmp
3561         ln -s $DIR/$tfile $TMP_DIR/symlink12
3562         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3563         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3564                 error "symlink12 not a link"
3565         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3566         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3567                 error "$DIR/d32o/tmp/symlink12 not file type"
3568         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3569                 error "$DIR/d32o/symlink02 not file type"
3570 }
3571 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3572
3573 test_32p() {
3574         log 32p_1
3575         rm -fr $DIR/d32p
3576         log 32p_2
3577         rm -f $DIR/$tfile
3578         log 32p_3
3579         touch $DIR/$tfile
3580         log 32p_4
3581         test_mkdir -p $DIR/d32p/tmp
3582         log 32p_5
3583         TMP_DIR=$DIR/d32p/tmp
3584         log 32p_6
3585         ln -s $DIR/$tfile $TMP_DIR/symlink12
3586         log 32p_7
3587         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3588         log 32p_8
3589         cat $DIR/d32p/tmp/symlink12 ||
3590                 error "Can't open $DIR/d32p/tmp/symlink12"
3591         log 32p_9
3592         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3593         log 32p_10
3594 }
3595 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3596
3597 test_32q() {
3598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3599
3600         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3601         trap cleanup_test32_mount EXIT
3602         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3603         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3604         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3605                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3606         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3607         cleanup_test32_mount
3608 }
3609 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3610
3611 test_32r() {
3612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3613
3614         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3615         trap cleanup_test32_mount EXIT
3616         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3617         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3618         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3619                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3620         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3621         cleanup_test32_mount
3622 }
3623 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3624
3625 test_33aa() {
3626         rm -f $DIR/$tfile
3627         touch $DIR/$tfile
3628         chmod 444 $DIR/$tfile
3629         chown $RUNAS_ID $DIR/$tfile
3630         log 33_1
3631         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3632         log 33_2
3633 }
3634 run_test 33aa "write file with mode 444 (should return error)"
3635
3636 test_33a() {
3637         rm -fr $DIR/$tdir
3638         test_mkdir $DIR/$tdir
3639         chown $RUNAS_ID $DIR/$tdir
3640         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3641                 error "$RUNAS create $tdir/$tfile failed"
3642         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3643                 error "open RDWR" || true
3644 }
3645 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3646
3647 test_33b() {
3648         rm -fr $DIR/$tdir
3649         test_mkdir $DIR/$tdir
3650         chown $RUNAS_ID $DIR/$tdir
3651         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3652 }
3653 run_test 33b "test open file with malformed flags (No panic)"
3654
3655 test_33c() {
3656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3657         remote_ost_nodsh && skip "remote OST with nodsh"
3658
3659         local ostnum
3660         local ostname
3661         local write_bytes
3662         local all_zeros
3663
3664         all_zeros=:
3665         rm -fr $DIR/$tdir
3666         test_mkdir $DIR/$tdir
3667         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3668
3669         sync
3670         for ostnum in $(seq $OSTCOUNT); do
3671                 # test-framework's OST numbering is one-based, while Lustre's
3672                 # is zero-based
3673                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3674                 # Parsing llobdstat's output sucks; we could grep the /proc
3675                 # path, but that's likely to not be as portable as using the
3676                 # llobdstat utility.  So we parse lctl output instead.
3677                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3678                         obdfilter/$ostname/stats |
3679                         awk '/^write_bytes/ {print $7}' )
3680                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3681                 if (( ${write_bytes:-0} > 0 ))
3682                 then
3683                         all_zeros=false
3684                         break;
3685                 fi
3686         done
3687
3688         $all_zeros || return 0
3689
3690         # Write four bytes
3691         echo foo > $DIR/$tdir/bar
3692         # Really write them
3693         sync
3694
3695         # Total up write_bytes after writing.  We'd better find non-zeros.
3696         for ostnum in $(seq $OSTCOUNT); do
3697                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3698                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3699                         obdfilter/$ostname/stats |
3700                         awk '/^write_bytes/ {print $7}' )
3701                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3702                 if (( ${write_bytes:-0} > 0 ))
3703                 then
3704                         all_zeros=false
3705                         break;
3706                 fi
3707         done
3708
3709         if $all_zeros
3710         then
3711                 for ostnum in $(seq $OSTCOUNT); do
3712                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3713                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3714                         do_facet ost$ostnum lctl get_param -n \
3715                                 obdfilter/$ostname/stats
3716                 done
3717                 error "OST not keeping write_bytes stats (b22312)"
3718         fi
3719 }
3720 run_test 33c "test llobdstat and write_bytes"
3721
3722 test_33d() {
3723         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3725
3726         local MDTIDX=1
3727         local remote_dir=$DIR/$tdir/remote_dir
3728
3729         test_mkdir $DIR/$tdir
3730         $LFS mkdir -i $MDTIDX $remote_dir ||
3731                 error "create remote directory failed"
3732
3733         touch $remote_dir/$tfile
3734         chmod 444 $remote_dir/$tfile
3735         chown $RUNAS_ID $remote_dir/$tfile
3736
3737         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3738
3739         chown $RUNAS_ID $remote_dir
3740         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3741                                         error "create" || true
3742         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3743                                     error "open RDWR" || true
3744         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3745 }
3746 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3747
3748 test_33e() {
3749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3750
3751         mkdir $DIR/$tdir
3752
3753         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3754         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3755         mkdir $DIR/$tdir/local_dir
3756
3757         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3758         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3759         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3760
3761         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3762                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3763
3764         rmdir $DIR/$tdir/* || error "rmdir failed"
3765
3766         umask 777
3767         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3768         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3769         mkdir $DIR/$tdir/local_dir
3770
3771         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3772         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3773         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3774
3775         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3776                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3777
3778         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3779
3780         umask 000
3781         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3782         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3783         mkdir $DIR/$tdir/local_dir
3784
3785         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3786         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3787         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3788
3789         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3790                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3791 }
3792 run_test 33e "mkdir and striped directory should have same mode"
3793
3794 cleanup_33f() {
3795         trap 0
3796         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3797 }
3798
3799 test_33f() {
3800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3801         remote_mds_nodsh && skip "remote MDS with nodsh"
3802
3803         mkdir $DIR/$tdir
3804         chmod go+rwx $DIR/$tdir
3805         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3806         trap cleanup_33f EXIT
3807
3808         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3809                 error "cannot create striped directory"
3810
3811         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3812                 error "cannot create files in striped directory"
3813
3814         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3815                 error "cannot remove files in striped directory"
3816
3817         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3818                 error "cannot remove striped directory"
3819
3820         cleanup_33f
3821 }
3822 run_test 33f "nonroot user can create, access, and remove a striped directory"
3823
3824 test_33g() {
3825         mkdir -p $DIR/$tdir/dir2
3826
3827         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3828         echo $err
3829         [[ $err =~ "exists" ]] || error "Not exists error"
3830 }
3831 run_test 33g "nonroot user create already existing root created file"
3832
3833 test_33h() {
3834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3835         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3836                 skip "Need MDS version at least 2.13.50"
3837
3838         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3839                 error "mkdir $tdir failed"
3840         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3841
3842         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3843         local index2
3844
3845         for fname in $DIR/$tdir/$tfile.bak \
3846                      $DIR/$tdir/$tfile.SAV \
3847                      $DIR/$tdir/$tfile.orig \
3848                      $DIR/$tdir/$tfile~; do
3849                 touch $fname  || error "touch $fname failed"
3850                 index2=$($LFS getstripe -m $fname)
3851                 [ $index -eq $index2 ] ||
3852                         error "$fname MDT index mismatch $index != $index2"
3853         done
3854
3855         local failed=0
3856         for i in {1..250}; do
3857                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3858                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3859                         touch $fname  || error "touch $fname failed"
3860                         index2=$($LFS getstripe -m $fname)
3861                         if [[ $index != $index2 ]]; then
3862                                 failed=$((failed + 1))
3863                                 echo "$fname MDT index mismatch $index != $index2"
3864                         fi
3865                 done
3866         done
3867         echo "$failed MDT index mismatches"
3868         (( failed < 20 )) || error "MDT index mismatch $failed times"
3869
3870 }
3871 run_test 33h "temp file is located on the same MDT as target"
3872
3873 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3874 test_34a() {
3875         rm -f $DIR/f34
3876         $MCREATE $DIR/f34 || error "mcreate failed"
3877         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3878                 error "getstripe failed"
3879         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3880         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3881                 error "getstripe failed"
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884 }
3885 run_test 34a "truncate file that has not been opened ==========="
3886
3887 test_34b() {
3888         [ ! -f $DIR/f34 ] && test_34a
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891         $OPENFILE -f O_RDONLY $DIR/f34
3892         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3893                 error "getstripe failed"
3894         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3895                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3896 }
3897 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3898
3899 test_34c() {
3900         [ ! -f $DIR/f34 ] && test_34a
3901         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3902                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3903         $OPENFILE -f O_RDWR $DIR/f34
3904         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3905                 error "$LFS getstripe failed"
3906         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3907                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3908 }
3909 run_test 34c "O_RDWR opening file-with-size works =============="
3910
3911 test_34d() {
3912         [ ! -f $DIR/f34 ] && test_34a
3913         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3914                 error "dd failed"
3915         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3916                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3917         rm $DIR/f34
3918 }
3919 run_test 34d "write to sparse file ============================="
3920
3921 test_34e() {
3922         rm -f $DIR/f34e
3923         $MCREATE $DIR/f34e || error "mcreate failed"
3924         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3925         $CHECKSTAT -s 1000 $DIR/f34e ||
3926                 error "Size of $DIR/f34e not equal to 1000 bytes"
3927         $OPENFILE -f O_RDWR $DIR/f34e
3928         $CHECKSTAT -s 1000 $DIR/f34e ||
3929                 error "Size of $DIR/f34e not equal to 1000 bytes"
3930 }
3931 run_test 34e "create objects, some with size and some without =="
3932
3933 test_34f() { # bug 6242, 6243
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         SIZE34F=48000
3937         rm -f $DIR/f34f
3938         $MCREATE $DIR/f34f || error "mcreate failed"
3939         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3940         dd if=$DIR/f34f of=$TMP/f34f
3941         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3942         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3943         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3944         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3945         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3946 }
3947 run_test 34f "read from a file with no objects until EOF ======="
3948
3949 test_34g() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3953                 error "dd failed"
3954         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3955         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3956                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3957         cancel_lru_locks osc
3958         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3959                 error "wrong size after lock cancel"
3960
3961         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3962         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3963                 error "expanding truncate failed"
3964         cancel_lru_locks osc
3965         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3966                 error "wrong expanded size after lock cancel"
3967 }
3968 run_test 34g "truncate long file ==============================="
3969
3970 test_34h() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         local gid=10
3974         local sz=1000
3975
3976         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3977         sync # Flush the cache so that multiop below does not block on cache
3978              # flush when getting the group lock
3979         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3980         MULTIPID=$!
3981
3982         # Since just timed wait is not good enough, let's do a sync write
3983         # that way we are sure enough time for a roundtrip + processing
3984         # passed + 2 seconds of extra margin.
3985         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3986         rm $DIR/${tfile}-1
3987         sleep 2
3988
3989         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3990                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3991                 kill -9 $MULTIPID
3992         fi
3993         wait $MULTIPID
3994         local nsz=`stat -c %s $DIR/$tfile`
3995         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3996 }
3997 run_test 34h "ftruncate file under grouplock should not block"
3998
3999 test_35a() {
4000         cp /bin/sh $DIR/f35a
4001         chmod 444 $DIR/f35a
4002         chown $RUNAS_ID $DIR/f35a
4003         $RUNAS $DIR/f35a && error || true
4004         rm $DIR/f35a
4005 }
4006 run_test 35a "exec file with mode 444 (should return and not leak)"
4007
4008 test_36a() {
4009         rm -f $DIR/f36
4010         utime $DIR/f36 || error "utime failed for MDS"
4011 }
4012 run_test 36a "MDS utime check (mknod, utime)"
4013
4014 test_36b() {
4015         echo "" > $DIR/f36
4016         utime $DIR/f36 || error "utime failed for OST"
4017 }
4018 run_test 36b "OST utime check (open, utime)"
4019
4020 test_36c() {
4021         rm -f $DIR/d36/f36
4022         test_mkdir $DIR/d36
4023         chown $RUNAS_ID $DIR/d36
4024         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4025 }
4026 run_test 36c "non-root MDS utime check (mknod, utime)"
4027
4028 test_36d() {
4029         [ ! -d $DIR/d36 ] && test_36c
4030         echo "" > $DIR/d36/f36
4031         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4032 }
4033 run_test 36d "non-root OST utime check (open, utime)"
4034
4035 test_36e() {
4036         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4037
4038         test_mkdir $DIR/$tdir
4039         touch $DIR/$tdir/$tfile
4040         $RUNAS utime $DIR/$tdir/$tfile &&
4041                 error "utime worked, expected failure" || true
4042 }
4043 run_test 36e "utime on non-owned file (should return error)"
4044
4045 subr_36fh() {
4046         local fl="$1"
4047         local LANG_SAVE=$LANG
4048         local LC_LANG_SAVE=$LC_LANG
4049         export LANG=C LC_LANG=C # for date language
4050
4051         DATESTR="Dec 20  2000"
4052         test_mkdir $DIR/$tdir
4053         lctl set_param fail_loc=$fl
4054         date; date +%s
4055         cp /etc/hosts $DIR/$tdir/$tfile
4056         sync & # write RPC generated with "current" inode timestamp, but delayed
4057         sleep 1
4058         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4059         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4060         cancel_lru_locks $OSC
4061         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4062         date; date +%s
4063         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4064                 echo "BEFORE: $LS_BEFORE" && \
4065                 echo "AFTER : $LS_AFTER" && \
4066                 echo "WANT  : $DATESTR" && \
4067                 error "$DIR/$tdir/$tfile timestamps changed" || true
4068
4069         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4070 }
4071
4072 test_36f() {
4073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4074
4075         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4076         subr_36fh "0x80000214"
4077 }
4078 run_test 36f "utime on file racing with OST BRW write =========="
4079
4080 test_36g() {
4081         remote_ost_nodsh && skip "remote OST with nodsh"
4082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4083         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4084                 skip "Need MDS version at least 2.12.51"
4085
4086         local fmd_max_age
4087         local fmd
4088         local facet="ost1"
4089         local tgt="obdfilter"
4090
4091         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4092
4093         test_mkdir $DIR/$tdir
4094         fmd_max_age=$(do_facet $facet \
4095                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4096                 head -n 1")
4097
4098         echo "FMD max age: ${fmd_max_age}s"
4099         touch $DIR/$tdir/$tfile
4100         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4101                 gawk '{cnt=cnt+$1}  END{print cnt}')
4102         echo "FMD before: $fmd"
4103         [[ $fmd == 0 ]] &&
4104                 error "FMD wasn't create by touch"
4105         sleep $((fmd_max_age + 12))
4106         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4107                 gawk '{cnt=cnt+$1}  END{print cnt}')
4108         echo "FMD after: $fmd"
4109         [[ $fmd == 0 ]] ||
4110                 error "FMD wasn't expired by ping"
4111 }
4112 run_test 36g "FMD cache expiry ====================="
4113
4114 test_36h() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4118         subr_36fh "0x80000227"
4119 }
4120 run_test 36h "utime on file racing with OST BRW write =========="
4121
4122 test_36i() {
4123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4124
4125         test_mkdir $DIR/$tdir
4126         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4127
4128         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4129         local new_mtime=$((mtime + 200))
4130
4131         #change Modify time of striped dir
4132         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4133                         error "change mtime failed"
4134
4135         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4136
4137         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4138 }
4139 run_test 36i "change mtime on striped directory"
4140
4141 # test_37 - duplicate with tests 32q 32r
4142
4143 test_38() {
4144         local file=$DIR/$tfile
4145         touch $file
4146         openfile -f O_DIRECTORY $file
4147         local RC=$?
4148         local ENOTDIR=20
4149         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4150         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4151 }
4152 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4153
4154 test_39a() { # was test_39
4155         touch $DIR/$tfile
4156         touch $DIR/${tfile}2
4157 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4158 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4159 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4160         sleep 2
4161         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4162         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4163                 echo "mtime"
4164                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4165                 echo "atime"
4166                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4167                 echo "ctime"
4168                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4169                 error "O_TRUNC didn't change timestamps"
4170         fi
4171 }
4172 run_test 39a "mtime changed on create"
4173
4174 test_39b() {
4175         test_mkdir -c1 $DIR/$tdir
4176         cp -p /etc/passwd $DIR/$tdir/fopen
4177         cp -p /etc/passwd $DIR/$tdir/flink
4178         cp -p /etc/passwd $DIR/$tdir/funlink
4179         cp -p /etc/passwd $DIR/$tdir/frename
4180         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4181
4182         sleep 1
4183         echo "aaaaaa" >> $DIR/$tdir/fopen
4184         echo "aaaaaa" >> $DIR/$tdir/flink
4185         echo "aaaaaa" >> $DIR/$tdir/funlink
4186         echo "aaaaaa" >> $DIR/$tdir/frename
4187
4188         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4189         local link_new=`stat -c %Y $DIR/$tdir/flink`
4190         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4191         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4192
4193         cat $DIR/$tdir/fopen > /dev/null
4194         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4195         rm -f $DIR/$tdir/funlink2
4196         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4197
4198         for (( i=0; i < 2; i++ )) ; do
4199                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4200                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4201                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4202                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4203
4204                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4205                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4206                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4207                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4208
4209                 cancel_lru_locks $OSC
4210                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4211         done
4212 }
4213 run_test 39b "mtime change on open, link, unlink, rename  ======"
4214
4215 # this should be set to past
4216 TEST_39_MTIME=`date -d "1 year ago" +%s`
4217
4218 # bug 11063
4219 test_39c() {
4220         touch $DIR1/$tfile
4221         sleep 2
4222         local mtime0=`stat -c %Y $DIR1/$tfile`
4223
4224         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4225         local mtime1=`stat -c %Y $DIR1/$tfile`
4226         [ "$mtime1" = $TEST_39_MTIME ] || \
4227                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4228
4229         local d1=`date +%s`
4230         echo hello >> $DIR1/$tfile
4231         local d2=`date +%s`
4232         local mtime2=`stat -c %Y $DIR1/$tfile`
4233         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4234                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4235
4236         mv $DIR1/$tfile $DIR1/$tfile-1
4237
4238         for (( i=0; i < 2; i++ )) ; do
4239                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4240                 [ "$mtime2" = "$mtime3" ] || \
4241                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4242
4243                 cancel_lru_locks $OSC
4244                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4245         done
4246 }
4247 run_test 39c "mtime change on rename ==========================="
4248
4249 # bug 21114
4250 test_39d() {
4251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4252
4253         touch $DIR1/$tfile
4254         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4255
4256         for (( i=0; i < 2; i++ )) ; do
4257                 local mtime=`stat -c %Y $DIR1/$tfile`
4258                 [ $mtime = $TEST_39_MTIME ] || \
4259                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4260
4261                 cancel_lru_locks $OSC
4262                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4263         done
4264 }
4265 run_test 39d "create, utime, stat =============================="
4266
4267 # bug 21114
4268 test_39e() {
4269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4270
4271         touch $DIR1/$tfile
4272         local mtime1=`stat -c %Y $DIR1/$tfile`
4273
4274         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4275
4276         for (( i=0; i < 2; i++ )) ; do
4277                 local mtime2=`stat -c %Y $DIR1/$tfile`
4278                 [ $mtime2 = $TEST_39_MTIME ] || \
4279                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4280
4281                 cancel_lru_locks $OSC
4282                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4283         done
4284 }
4285 run_test 39e "create, stat, utime, stat ========================"
4286
4287 # bug 21114
4288 test_39f() {
4289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4290
4291         touch $DIR1/$tfile
4292         mtime1=`stat -c %Y $DIR1/$tfile`
4293
4294         sleep 2
4295         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4296
4297         for (( i=0; i < 2; i++ )) ; do
4298                 local mtime2=`stat -c %Y $DIR1/$tfile`
4299                 [ $mtime2 = $TEST_39_MTIME ] || \
4300                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4301
4302                 cancel_lru_locks $OSC
4303                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4304         done
4305 }
4306 run_test 39f "create, stat, sleep, utime, stat ================="
4307
4308 # bug 11063
4309 test_39g() {
4310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4311
4312         echo hello >> $DIR1/$tfile
4313         local mtime1=`stat -c %Y $DIR1/$tfile`
4314
4315         sleep 2
4316         chmod o+r $DIR1/$tfile
4317
4318         for (( i=0; i < 2; i++ )) ; do
4319                 local mtime2=`stat -c %Y $DIR1/$tfile`
4320                 [ "$mtime1" = "$mtime2" ] || \
4321                         error "lost mtime: $mtime2, should be $mtime1"
4322
4323                 cancel_lru_locks $OSC
4324                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4325         done
4326 }
4327 run_test 39g "write, chmod, stat ==============================="
4328
4329 # bug 11063
4330 test_39h() {
4331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4332
4333         touch $DIR1/$tfile
4334         sleep 1
4335
4336         local d1=`date`
4337         echo hello >> $DIR1/$tfile
4338         local mtime1=`stat -c %Y $DIR1/$tfile`
4339
4340         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4341         local d2=`date`
4342         if [ "$d1" != "$d2" ]; then
4343                 echo "write and touch not within one second"
4344         else
4345                 for (( i=0; i < 2; i++ )) ; do
4346                         local mtime2=`stat -c %Y $DIR1/$tfile`
4347                         [ "$mtime2" = $TEST_39_MTIME ] || \
4348                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4349
4350                         cancel_lru_locks $OSC
4351                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4352                 done
4353         fi
4354 }
4355 run_test 39h "write, utime within one second, stat ============="
4356
4357 test_39i() {
4358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4359
4360         touch $DIR1/$tfile
4361         sleep 1
4362
4363         echo hello >> $DIR1/$tfile
4364         local mtime1=`stat -c %Y $DIR1/$tfile`
4365
4366         mv $DIR1/$tfile $DIR1/$tfile-1
4367
4368         for (( i=0; i < 2; i++ )) ; do
4369                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4370
4371                 [ "$mtime1" = "$mtime2" ] || \
4372                         error "lost mtime: $mtime2, should be $mtime1"
4373
4374                 cancel_lru_locks $OSC
4375                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4376         done
4377 }
4378 run_test 39i "write, rename, stat =============================="
4379
4380 test_39j() {
4381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4382
4383         start_full_debug_logging
4384         touch $DIR1/$tfile
4385         sleep 1
4386
4387         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4388         lctl set_param fail_loc=0x80000412
4389         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4390                 error "multiop failed"
4391         local multipid=$!
4392         local mtime1=`stat -c %Y $DIR1/$tfile`
4393
4394         mv $DIR1/$tfile $DIR1/$tfile-1
4395
4396         kill -USR1 $multipid
4397         wait $multipid || error "multiop close failed"
4398
4399         for (( i=0; i < 2; i++ )) ; do
4400                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4401                 [ "$mtime1" = "$mtime2" ] ||
4402                         error "mtime is lost on close: $mtime2, " \
4403                               "should be $mtime1"
4404
4405                 cancel_lru_locks
4406                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4407         done
4408         lctl set_param fail_loc=0
4409         stop_full_debug_logging
4410 }
4411 run_test 39j "write, rename, close, stat ======================="
4412
4413 test_39k() {
4414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4415
4416         touch $DIR1/$tfile
4417         sleep 1
4418
4419         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4420         local multipid=$!
4421         local mtime1=`stat -c %Y $DIR1/$tfile`
4422
4423         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4424
4425         kill -USR1 $multipid
4426         wait $multipid || error "multiop close failed"
4427
4428         for (( i=0; i < 2; i++ )) ; do
4429                 local mtime2=`stat -c %Y $DIR1/$tfile`
4430
4431                 [ "$mtime2" = $TEST_39_MTIME ] || \
4432                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4433
4434                 cancel_lru_locks
4435                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4436         done
4437 }
4438 run_test 39k "write, utime, close, stat ========================"
4439
4440 # this should be set to future
4441 TEST_39_ATIME=`date -d "1 year" +%s`
4442
4443 test_39l() {
4444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4445         remote_mds_nodsh && skip "remote MDS with nodsh"
4446
4447         local atime_diff=$(do_facet $SINGLEMDS \
4448                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4449         rm -rf $DIR/$tdir
4450         mkdir -p $DIR/$tdir
4451
4452         # test setting directory atime to future
4453         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4454         local atime=$(stat -c %X $DIR/$tdir)
4455         [ "$atime" = $TEST_39_ATIME ] ||
4456                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4457
4458         # test setting directory atime from future to now
4459         local now=$(date +%s)
4460         touch -a -d @$now $DIR/$tdir
4461
4462         atime=$(stat -c %X $DIR/$tdir)
4463         [ "$atime" -eq "$now"  ] ||
4464                 error "atime is not updated from future: $atime, $now"
4465
4466         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4467         sleep 3
4468
4469         # test setting directory atime when now > dir atime + atime_diff
4470         local d1=$(date +%s)
4471         ls $DIR/$tdir
4472         local d2=$(date +%s)
4473         cancel_lru_locks mdc
4474         atime=$(stat -c %X $DIR/$tdir)
4475         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4476                 error "atime is not updated  : $atime, should be $d2"
4477
4478         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4479         sleep 3
4480
4481         # test not setting directory atime when now < dir atime + atime_diff
4482         ls $DIR/$tdir
4483         cancel_lru_locks mdc
4484         atime=$(stat -c %X $DIR/$tdir)
4485         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4486                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4487
4488         do_facet $SINGLEMDS \
4489                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4490 }
4491 run_test 39l "directory atime update ==========================="
4492
4493 test_39m() {
4494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4495
4496         touch $DIR1/$tfile
4497         sleep 2
4498         local far_past_mtime=$(date -d "May 29 1953" +%s)
4499         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4500
4501         touch -m -d @$far_past_mtime $DIR1/$tfile
4502         touch -a -d @$far_past_atime $DIR1/$tfile
4503
4504         for (( i=0; i < 2; i++ )) ; do
4505                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4506                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4507                         error "atime or mtime set incorrectly"
4508
4509                 cancel_lru_locks $OSC
4510                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4511         done
4512 }
4513 run_test 39m "test atime and mtime before 1970"
4514
4515 test_39n() { # LU-3832
4516         remote_mds_nodsh && skip "remote MDS with nodsh"
4517
4518         local atime_diff=$(do_facet $SINGLEMDS \
4519                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4520         local atime0
4521         local atime1
4522         local atime2
4523
4524         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4525
4526         rm -rf $DIR/$tfile
4527         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4528         atime0=$(stat -c %X $DIR/$tfile)
4529
4530         sleep 5
4531         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4532         atime1=$(stat -c %X $DIR/$tfile)
4533
4534         sleep 5
4535         cancel_lru_locks mdc
4536         cancel_lru_locks osc
4537         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4538         atime2=$(stat -c %X $DIR/$tfile)
4539
4540         do_facet $SINGLEMDS \
4541                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4542
4543         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4544         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4545 }
4546 run_test 39n "check that O_NOATIME is honored"
4547
4548 test_39o() {
4549         TESTDIR=$DIR/$tdir/$tfile
4550         [ -e $TESTDIR ] && rm -rf $TESTDIR
4551         mkdir -p $TESTDIR
4552         cd $TESTDIR
4553         links1=2
4554         ls
4555         mkdir a b
4556         ls
4557         links2=$(stat -c %h .)
4558         [ $(($links1 + 2)) != $links2 ] &&
4559                 error "wrong links count $(($links1 + 2)) != $links2"
4560         rmdir b
4561         links3=$(stat -c %h .)
4562         [ $(($links1 + 1)) != $links3 ] &&
4563                 error "wrong links count $links1 != $links3"
4564         return 0
4565 }
4566 run_test 39o "directory cached attributes updated after create"
4567
4568 test_39p() {
4569         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4570
4571         local MDTIDX=1
4572         TESTDIR=$DIR/$tdir/$tdir
4573         [ -e $TESTDIR ] && rm -rf $TESTDIR
4574         test_mkdir -p $TESTDIR
4575         cd $TESTDIR
4576         links1=2
4577         ls
4578         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4579         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4580         ls
4581         links2=$(stat -c %h .)
4582         [ $(($links1 + 2)) != $links2 ] &&
4583                 error "wrong links count $(($links1 + 2)) != $links2"
4584         rmdir remote_dir2
4585         links3=$(stat -c %h .)
4586         [ $(($links1 + 1)) != $links3 ] &&
4587                 error "wrong links count $links1 != $links3"
4588         return 0
4589 }
4590 run_test 39p "remote directory cached attributes updated after create ========"
4591
4592 test_39r() {
4593         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4594                 skip "no atime update on old OST"
4595         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4596                 skip_env "ldiskfs only test"
4597         fi
4598
4599         local saved_adiff
4600         saved_adiff=$(do_facet ost1 \
4601                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4602         stack_trap "do_facet ost1 \
4603                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4604
4605         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4606
4607         $LFS setstripe -i 0 $DIR/$tfile
4608         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4609                 error "can't write initial file"
4610         cancel_lru_locks osc
4611
4612         # exceed atime_diff and access file
4613         sleep 6
4614         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4615
4616         local atime_cli=$(stat -c %X $DIR/$tfile)
4617         echo "client atime: $atime_cli"
4618         # allow atime update to be written to device
4619         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4620         sleep 5
4621
4622         local ostdev=$(ostdevname 1)
4623         local fid=($(lfs getstripe -y $DIR/$tfile |
4624                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4625         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4626         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4627
4628         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4629         local atime_ost=$(do_facet ost1 "$cmd" |&
4630                           awk -F'[: ]' '/atime:/ { print $4 }')
4631         (( atime_cli == atime_ost )) ||
4632                 error "atime on client $atime_cli != ost $atime_ost"
4633 }
4634 run_test 39r "lazy atime update on OST"
4635
4636 test_39q() { # LU-8041
4637         local testdir=$DIR/$tdir
4638         mkdir -p $testdir
4639         multiop_bg_pause $testdir D_c || error "multiop failed"
4640         local multipid=$!
4641         cancel_lru_locks mdc
4642         kill -USR1 $multipid
4643         local atime=$(stat -c %X $testdir)
4644         [ "$atime" -ne 0 ] || error "atime is zero"
4645 }
4646 run_test 39q "close won't zero out atime"
4647
4648 test_40() {
4649         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4650         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4651                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4652         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4653                 error "$tfile is not 4096 bytes in size"
4654 }
4655 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4656
4657 test_41() {
4658         # bug 1553
4659         small_write $DIR/f41 18
4660 }
4661 run_test 41 "test small file write + fstat ====================="
4662
4663 count_ost_writes() {
4664         lctl get_param -n ${OSC}.*.stats |
4665                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4666                         END { printf("%0.0f", writes) }'
4667 }
4668
4669 # decent default
4670 WRITEBACK_SAVE=500
4671 DIRTY_RATIO_SAVE=40
4672 MAX_DIRTY_RATIO=50
4673 BG_DIRTY_RATIO_SAVE=10
4674 MAX_BG_DIRTY_RATIO=25
4675
4676 start_writeback() {
4677         trap 0
4678         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4679         # dirty_ratio, dirty_background_ratio
4680         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4681                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4682                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4683                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4684         else
4685                 # if file not here, we are a 2.4 kernel
4686                 kill -CONT `pidof kupdated`
4687         fi
4688 }
4689
4690 stop_writeback() {
4691         # setup the trap first, so someone cannot exit the test at the
4692         # exact wrong time and mess up a machine
4693         trap start_writeback EXIT
4694         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4695         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4696                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4697                 sysctl -w vm.dirty_writeback_centisecs=0
4698                 sysctl -w vm.dirty_writeback_centisecs=0
4699                 # save and increase /proc/sys/vm/dirty_ratio
4700                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4701                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4702                 # save and increase /proc/sys/vm/dirty_background_ratio
4703                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4704                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4705         else
4706                 # if file not here, we are a 2.4 kernel
4707                 kill -STOP `pidof kupdated`
4708         fi
4709 }
4710
4711 # ensure that all stripes have some grant before we test client-side cache
4712 setup_test42() {
4713         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4714                 dd if=/dev/zero of=$i bs=4k count=1
4715                 rm $i
4716         done
4717 }
4718
4719 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4720 # file truncation, and file removal.
4721 test_42a() {
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723
4724         setup_test42
4725         cancel_lru_locks $OSC
4726         stop_writeback
4727         sync; sleep 1; sync # just to be safe
4728         BEFOREWRITES=`count_ost_writes`
4729         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4730         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4731         AFTERWRITES=`count_ost_writes`
4732         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4733                 error "$BEFOREWRITES < $AFTERWRITES"
4734         start_writeback
4735 }
4736 run_test 42a "ensure that we don't flush on close"
4737
4738 test_42b() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         setup_test42
4742         cancel_lru_locks $OSC
4743         stop_writeback
4744         sync
4745         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4746         BEFOREWRITES=$(count_ost_writes)
4747         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4748         AFTERWRITES=$(count_ost_writes)
4749         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4750                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4751         fi
4752         BEFOREWRITES=$(count_ost_writes)
4753         sync || error "sync: $?"
4754         AFTERWRITES=$(count_ost_writes)
4755         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4756                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4757         fi
4758         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4759         start_writeback
4760         return 0
4761 }
4762 run_test 42b "test destroy of file with cached dirty data ======"
4763
4764 # if these tests just want to test the effect of truncation,
4765 # they have to be very careful.  consider:
4766 # - the first open gets a {0,EOF}PR lock
4767 # - the first write conflicts and gets a {0, count-1}PW
4768 # - the rest of the writes are under {count,EOF}PW
4769 # - the open for truncate tries to match a {0,EOF}PR
4770 #   for the filesize and cancels the PWs.
4771 # any number of fixes (don't get {0,EOF} on open, match
4772 # composite locks, do smarter file size management) fix
4773 # this, but for now we want these tests to verify that
4774 # the cancellation with truncate intent works, so we
4775 # start the file with a full-file pw lock to match against
4776 # until the truncate.
4777 trunc_test() {
4778         test=$1
4779         file=$DIR/$test
4780         offset=$2
4781         cancel_lru_locks $OSC
4782         stop_writeback
4783         # prime the file with 0,EOF PW to match
4784         touch $file
4785         $TRUNCATE $file 0
4786         sync; sync
4787         # now the real test..
4788         dd if=/dev/zero of=$file bs=1024 count=100
4789         BEFOREWRITES=`count_ost_writes`
4790         $TRUNCATE $file $offset
4791         cancel_lru_locks $OSC
4792         AFTERWRITES=`count_ost_writes`
4793         start_writeback
4794 }
4795
4796 test_42c() {
4797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4798
4799         trunc_test 42c 1024
4800         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4801                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4802         rm $file
4803 }
4804 run_test 42c "test partial truncate of file with cached dirty data"
4805
4806 test_42d() {
4807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4808
4809         trunc_test 42d 0
4810         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4811                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4812         rm $file
4813 }
4814 run_test 42d "test complete truncate of file with cached dirty data"
4815
4816 test_42e() { # bug22074
4817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4818
4819         local TDIR=$DIR/${tdir}e
4820         local pages=16 # hardcoded 16 pages, don't change it.
4821         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4822         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4823         local max_dirty_mb
4824         local warmup_files
4825
4826         test_mkdir $DIR/${tdir}e
4827         $LFS setstripe -c 1 $TDIR
4828         createmany -o $TDIR/f $files
4829
4830         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4831
4832         # we assume that with $OSTCOUNT files, at least one of them will
4833         # be allocated on OST0.
4834         warmup_files=$((OSTCOUNT * max_dirty_mb))
4835         createmany -o $TDIR/w $warmup_files
4836
4837         # write a large amount of data into one file and sync, to get good
4838         # avail_grant number from OST.
4839         for ((i=0; i<$warmup_files; i++)); do
4840                 idx=$($LFS getstripe -i $TDIR/w$i)
4841                 [ $idx -ne 0 ] && continue
4842                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4843                 break
4844         done
4845         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4846         sync
4847         $LCTL get_param $proc_osc0/cur_dirty_bytes
4848         $LCTL get_param $proc_osc0/cur_grant_bytes
4849
4850         # create as much dirty pages as we can while not to trigger the actual
4851         # RPCs directly. but depends on the env, VFS may trigger flush during this
4852         # period, hopefully we are good.
4853         for ((i=0; i<$warmup_files; i++)); do
4854                 idx=$($LFS getstripe -i $TDIR/w$i)
4855                 [ $idx -ne 0 ] && continue
4856                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4857         done
4858         $LCTL get_param $proc_osc0/cur_dirty_bytes
4859         $LCTL get_param $proc_osc0/cur_grant_bytes
4860
4861         # perform the real test
4862         $LCTL set_param $proc_osc0/rpc_stats 0
4863         for ((;i<$files; i++)); do
4864                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4865                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4866         done
4867         sync
4868         $LCTL get_param $proc_osc0/rpc_stats
4869
4870         local percent=0
4871         local have_ppr=false
4872         $LCTL get_param $proc_osc0/rpc_stats |
4873                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4874                         # skip lines until we are at the RPC histogram data
4875                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4876                         $have_ppr || continue
4877
4878                         # we only want the percent stat for < 16 pages
4879                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4880
4881                         percent=$((percent + WPCT))
4882                         if [[ $percent -gt 15 ]]; then
4883                                 error "less than 16-pages write RPCs" \
4884                                       "$percent% > 15%"
4885                                 break
4886                         fi
4887                 done
4888         rm -rf $TDIR
4889 }
4890 run_test 42e "verify sub-RPC writes are not done synchronously"
4891
4892 test_43A() { # was test_43
4893         test_mkdir $DIR/$tdir
4894         cp -p /bin/ls $DIR/$tdir/$tfile
4895         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4896         pid=$!
4897         # give multiop a chance to open
4898         sleep 1
4899
4900         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4901         kill -USR1 $pid
4902         # Wait for multiop to exit
4903         wait $pid
4904 }
4905 run_test 43A "execution of file opened for write should return -ETXTBSY"
4906
4907 test_43a() {
4908         test_mkdir $DIR/$tdir
4909         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4910         $DIR/$tdir/sleep 60 &
4911         SLEEP_PID=$!
4912         # Make sure exec of $tdir/sleep wins race with truncate
4913         sleep 1
4914         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4915         kill $SLEEP_PID
4916 }
4917 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4918
4919 test_43b() {
4920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4921
4922         test_mkdir $DIR/$tdir
4923         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4924         $DIR/$tdir/sleep 60 &
4925         SLEEP_PID=$!
4926         # Make sure exec of $tdir/sleep wins race with truncate
4927         sleep 1
4928         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4929         kill $SLEEP_PID
4930 }
4931 run_test 43b "truncate of file being executed should return -ETXTBSY"
4932
4933 test_43c() {
4934         local testdir="$DIR/$tdir"
4935         test_mkdir $testdir
4936         cp $SHELL $testdir/
4937         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4938                 ( cd $testdir && md5sum -c )
4939 }
4940 run_test 43c "md5sum of copy into lustre"
4941
4942 test_44A() { # was test_44
4943         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4944
4945         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4946         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4947 }
4948 run_test 44A "zero length read from a sparse stripe"
4949
4950 test_44a() {
4951         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4952                 awk '{ print $2 }')
4953         [ -z "$nstripe" ] && skip "can't get stripe info"
4954         [[ $nstripe -gt $OSTCOUNT ]] &&
4955                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4956
4957         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4958                 awk '{ print $2 }')
4959         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4960                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4961                         awk '{ print $2 }')
4962         fi
4963
4964         OFFSETS="0 $((stride/2)) $((stride-1))"
4965         for offset in $OFFSETS; do
4966                 for i in $(seq 0 $((nstripe-1))); do
4967                         local GLOBALOFFSETS=""
4968                         # size in Bytes
4969                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4970                         local myfn=$DIR/d44a-$size
4971                         echo "--------writing $myfn at $size"
4972                         ll_sparseness_write $myfn $size ||
4973                                 error "ll_sparseness_write"
4974                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4975                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4976                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4977
4978                         for j in $(seq 0 $((nstripe-1))); do
4979                                 # size in Bytes
4980                                 size=$((((j + $nstripe )*$stride + $offset)))
4981                                 ll_sparseness_write $myfn $size ||
4982                                         error "ll_sparseness_write"
4983                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4984                         done
4985                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4986                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4987                         rm -f $myfn
4988                 done
4989         done
4990 }
4991 run_test 44a "test sparse pwrite ==============================="
4992
4993 dirty_osc_total() {
4994         tot=0
4995         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4996                 tot=$(($tot + $d))
4997         done
4998         echo $tot
4999 }
5000 do_dirty_record() {
5001         before=`dirty_osc_total`
5002         echo executing "\"$*\""
5003         eval $*
5004         after=`dirty_osc_total`
5005         echo before $before, after $after
5006 }
5007 test_45() {
5008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5009
5010         f="$DIR/f45"
5011         # Obtain grants from OST if it supports it
5012         echo blah > ${f}_grant
5013         stop_writeback
5014         sync
5015         do_dirty_record "echo blah > $f"
5016         [[ $before -eq $after ]] && error "write wasn't cached"
5017         do_dirty_record "> $f"
5018         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5019         do_dirty_record "echo blah > $f"
5020         [[ $before -eq $after ]] && error "write wasn't cached"
5021         do_dirty_record "sync"
5022         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5023         do_dirty_record "echo blah > $f"
5024         [[ $before -eq $after ]] && error "write wasn't cached"
5025         do_dirty_record "cancel_lru_locks osc"
5026         [[ $before -gt $after ]] ||
5027                 error "lock cancellation didn't lower dirty count"
5028         start_writeback
5029 }
5030 run_test 45 "osc io page accounting ============================"
5031
5032 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5033 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5034 # objects offset and an assert hit when an rpc was built with 1023's mapped
5035 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5036 test_46() {
5037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5038
5039         f="$DIR/f46"
5040         stop_writeback
5041         sync
5042         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5043         sync
5044         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5045         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5046         sync
5047         start_writeback
5048 }
5049 run_test 46 "dirtying a previously written page ================"
5050
5051 # test_47 is removed "Device nodes check" is moved to test_28
5052
5053 test_48a() { # bug 2399
5054         [ "$mds1_FSTYPE" = "zfs" ] &&
5055         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5056                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5057
5058         test_mkdir $DIR/$tdir
5059         cd $DIR/$tdir
5060         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5061         test_mkdir $DIR/$tdir
5062         touch foo || error "'touch foo' failed after recreating cwd"
5063         test_mkdir bar
5064         touch .foo || error "'touch .foo' failed after recreating cwd"
5065         test_mkdir .bar
5066         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5067         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5068         cd . || error "'cd .' failed after recreating cwd"
5069         mkdir . && error "'mkdir .' worked after recreating cwd"
5070         rmdir . && error "'rmdir .' worked after recreating cwd"
5071         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5072         cd .. || error "'cd ..' failed after recreating cwd"
5073 }
5074 run_test 48a "Access renamed working dir (should return errors)="
5075
5076 test_48b() { # bug 2399
5077         rm -rf $DIR/$tdir
5078         test_mkdir $DIR/$tdir
5079         cd $DIR/$tdir
5080         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5081         touch foo && error "'touch foo' worked after removing cwd"
5082         mkdir foo && error "'mkdir foo' worked after removing cwd"
5083         touch .foo && error "'touch .foo' worked after removing cwd"
5084         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5085         ls . > /dev/null && error "'ls .' worked after removing cwd"
5086         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5087         mkdir . && error "'mkdir .' worked after removing cwd"
5088         rmdir . && error "'rmdir .' worked after removing cwd"
5089         ln -s . foo && error "'ln -s .' worked after removing cwd"
5090         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5091 }
5092 run_test 48b "Access removed working dir (should return errors)="
5093
5094 test_48c() { # bug 2350
5095         #lctl set_param debug=-1
5096         #set -vx
5097         rm -rf $DIR/$tdir
5098         test_mkdir -p $DIR/$tdir/dir
5099         cd $DIR/$tdir/dir
5100         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5101         $TRACE touch foo && error "touch foo worked after removing cwd"
5102         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5103         touch .foo && error "touch .foo worked after removing cwd"
5104         mkdir .foo && error "mkdir .foo worked after removing cwd"
5105         $TRACE ls . && error "'ls .' worked after removing cwd"
5106         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5107         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5108         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5109         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5110         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5111 }
5112 run_test 48c "Access removed working subdir (should return errors)"
5113
5114 test_48d() { # bug 2350
5115         #lctl set_param debug=-1
5116         #set -vx
5117         rm -rf $DIR/$tdir
5118         test_mkdir -p $DIR/$tdir/dir
5119         cd $DIR/$tdir/dir
5120         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5121         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5122         $TRACE touch foo && error "'touch foo' worked after removing parent"
5123         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5124         touch .foo && error "'touch .foo' worked after removing parent"
5125         mkdir .foo && error "mkdir .foo worked after removing parent"
5126         $TRACE ls . && error "'ls .' worked after removing parent"
5127         $TRACE ls .. && error "'ls ..' worked after removing parent"
5128         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5129         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5130         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5131         true
5132 }
5133 run_test 48d "Access removed parent subdir (should return errors)"
5134
5135 test_48e() { # bug 4134
5136         #lctl set_param debug=-1
5137         #set -vx
5138         rm -rf $DIR/$tdir
5139         test_mkdir -p $DIR/$tdir/dir
5140         cd $DIR/$tdir/dir
5141         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5142         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5143         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5144         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5145         # On a buggy kernel addition of "touch foo" after cd .. will
5146         # produce kernel oops in lookup_hash_it
5147         touch ../foo && error "'cd ..' worked after recreate parent"
5148         cd $DIR
5149         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5150 }
5151 run_test 48e "Access to recreated parent subdir (should return errors)"
5152
5153 test_48f() {
5154         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5155                 skip "need MDS >= 2.13.55"
5156         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5157         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5158                 skip "needs different host for mdt1 mdt2"
5159         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5160
5161         $LFS mkdir -i0 $DIR/$tdir
5162         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5163
5164         for d in sub1 sub2 sub3; do
5165                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5166                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5167                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5168         done
5169
5170         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5171 }
5172 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5173
5174 test_49() { # LU-1030
5175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5176         remote_ost_nodsh && skip "remote OST with nodsh"
5177
5178         # get ost1 size - $FSNAME-OST0000
5179         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5180                 awk '{ print $4 }')
5181         # write 800M at maximum
5182         [[ $ost1_size -lt 2 ]] && ost1_size=2
5183         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5184
5185         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5186         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5187         local dd_pid=$!
5188
5189         # change max_pages_per_rpc while writing the file
5190         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5191         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5192         # loop until dd process exits
5193         while ps ax -opid | grep -wq $dd_pid; do
5194                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5195                 sleep $((RANDOM % 5 + 1))
5196         done
5197         # restore original max_pages_per_rpc
5198         $LCTL set_param $osc1_mppc=$orig_mppc
5199         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5200 }
5201 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5202
5203 test_50() {
5204         # bug 1485
5205         test_mkdir $DIR/$tdir
5206         cd $DIR/$tdir
5207         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5208 }
5209 run_test 50 "special situations: /proc symlinks  ==============="
5210
5211 test_51a() {    # was test_51
5212         # bug 1516 - create an empty entry right after ".." then split dir
5213         test_mkdir -c1 $DIR/$tdir
5214         touch $DIR/$tdir/foo
5215         $MCREATE $DIR/$tdir/bar
5216         rm $DIR/$tdir/foo
5217         createmany -m $DIR/$tdir/longfile 201
5218         FNUM=202
5219         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5220                 $MCREATE $DIR/$tdir/longfile$FNUM
5221                 FNUM=$(($FNUM + 1))
5222                 echo -n "+"
5223         done
5224         echo
5225         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5226 }
5227 run_test 51a "special situations: split htree with empty entry =="
5228
5229 cleanup_print_lfs_df () {
5230         trap 0
5231         $LFS df
5232         $LFS df -i
5233 }
5234
5235 test_51b() {
5236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5237
5238         local dir=$DIR/$tdir
5239         local nrdirs=$((65536 + 100))
5240
5241         # cleanup the directory
5242         rm -fr $dir
5243
5244         test_mkdir -c1 $dir
5245
5246         $LFS df
5247         $LFS df -i
5248         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5249         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5250         [[ $numfree -lt $nrdirs ]] &&
5251                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5252
5253         # need to check free space for the directories as well
5254         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5255         numfree=$(( blkfree / $(fs_inode_ksize) ))
5256         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5257
5258         trap cleanup_print_lfs_df EXIT
5259
5260         # create files
5261         createmany -d $dir/d $nrdirs || {
5262                 unlinkmany $dir/d $nrdirs
5263                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5264         }
5265
5266         # really created :
5267         nrdirs=$(ls -U $dir | wc -l)
5268
5269         # unlink all but 100 subdirectories, then check it still works
5270         local left=100
5271         local delete=$((nrdirs - left))
5272
5273         $LFS df
5274         $LFS df -i
5275
5276         # for ldiskfs the nlink count should be 1, but this is OSD specific
5277         # and so this is listed for informational purposes only
5278         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5279         unlinkmany -d $dir/d $delete ||
5280                 error "unlink of first $delete subdirs failed"
5281
5282         echo "nlink between: $(stat -c %h $dir)"
5283         local found=$(ls -U $dir | wc -l)
5284         [ $found -ne $left ] &&
5285                 error "can't find subdirs: found only $found, expected $left"
5286
5287         unlinkmany -d $dir/d $delete $left ||
5288                 error "unlink of second $left subdirs failed"
5289         # regardless of whether the backing filesystem tracks nlink accurately
5290         # or not, the nlink count shouldn't be more than "." and ".." here
5291         local after=$(stat -c %h $dir)
5292         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5293                 echo "nlink after: $after"
5294
5295         cleanup_print_lfs_df
5296 }
5297 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5298
5299 test_51d() {
5300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5301         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5302
5303         test_mkdir $DIR/$tdir
5304         createmany -o $DIR/$tdir/t- 1000
5305         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5306         for N in $(seq 0 $((OSTCOUNT - 1))); do
5307                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5308                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5309                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5310                         '($1 == '$N') { objs += 1 } \
5311                         END { printf("%0.0f", objs) }')
5312                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5313         done
5314         unlinkmany $DIR/$tdir/t- 1000
5315
5316         NLAST=0
5317         for N in $(seq 1 $((OSTCOUNT - 1))); do
5318                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5319                         error "OST $N has less objects vs OST $NLAST" \
5320                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5321                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5322                         error "OST $N has less objects vs OST $NLAST" \
5323                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5324
5325                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5326                         error "OST $N has less #0 objects vs OST $NLAST" \
5327                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5328                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5329                         error "OST $N has less #0 objects vs OST $NLAST" \
5330                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5331                 NLAST=$N
5332         done
5333         rm -f $TMP/$tfile
5334 }
5335 run_test 51d "check object distribution"
5336
5337 test_51e() {
5338         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5339                 skip_env "ldiskfs only test"
5340         fi
5341
5342         test_mkdir -c1 $DIR/$tdir
5343         test_mkdir -c1 $DIR/$tdir/d0
5344
5345         touch $DIR/$tdir/d0/foo
5346         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5347                 error "file exceed 65000 nlink limit!"
5348         unlinkmany $DIR/$tdir/d0/f- 65001
5349         return 0
5350 }
5351 run_test 51e "check file nlink limit"
5352
5353 test_51f() {
5354         test_mkdir $DIR/$tdir
5355
5356         local max=100000
5357         local ulimit_old=$(ulimit -n)
5358         local spare=20 # number of spare fd's for scripts/libraries, etc.
5359         local mdt=$($LFS getstripe -m $DIR/$tdir)
5360         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5361
5362         echo "MDT$mdt numfree=$numfree, max=$max"
5363         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5364         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5365                 while ! ulimit -n $((numfree + spare)); do
5366                         numfree=$((numfree * 3 / 4))
5367                 done
5368                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5369         else
5370                 echo "left ulimit at $ulimit_old"
5371         fi
5372
5373         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5374                 unlinkmany $DIR/$tdir/f $numfree
5375                 error "create+open $numfree files in $DIR/$tdir failed"
5376         }
5377         ulimit -n $ulimit_old
5378
5379         # if createmany exits at 120s there will be fewer than $numfree files
5380         unlinkmany $DIR/$tdir/f $numfree || true
5381 }
5382 run_test 51f "check many open files limit"
5383
5384 test_52a() {
5385         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5386         test_mkdir $DIR/$tdir
5387         touch $DIR/$tdir/foo
5388         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5389         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5390         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5391         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5392         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5393                                         error "link worked"
5394         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5395         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5396         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5397                                                      error "lsattr"
5398         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5399         cp -r $DIR/$tdir $TMP/
5400         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5401 }
5402 run_test 52a "append-only flag test (should return errors)"
5403
5404 test_52b() {
5405         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5406         test_mkdir $DIR/$tdir
5407         touch $DIR/$tdir/foo
5408         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5409         cat test > $DIR/$tdir/foo && error "cat test worked"
5410         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5411         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5412         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5413                                         error "link worked"
5414         echo foo >> $DIR/$tdir/foo && error "echo worked"
5415         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5416         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5417         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5418         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5419                                                         error "lsattr"
5420         chattr -i $DIR/$tdir/foo || error "chattr failed"
5421
5422         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5423 }
5424 run_test 52b "immutable flag test (should return errors) ======="
5425
5426 test_53() {
5427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5428         remote_mds_nodsh && skip "remote MDS with nodsh"
5429         remote_ost_nodsh && skip "remote OST with nodsh"
5430
5431         local param
5432         local param_seq
5433         local ostname
5434         local mds_last
5435         local mds_last_seq
5436         local ost_last
5437         local ost_last_seq
5438         local ost_last_id
5439         local ostnum
5440         local node
5441         local found=false
5442         local support_last_seq=true
5443
5444         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5445                 support_last_seq=false
5446
5447         # only test MDT0000
5448         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5449         local value
5450         for value in $(do_facet $SINGLEMDS \
5451                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5452                 param=$(echo ${value[0]} | cut -d "=" -f1)
5453                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5454
5455                 if $support_last_seq; then
5456                         param_seq=$(echo $param |
5457                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5458                         mds_last_seq=$(do_facet $SINGLEMDS \
5459                                        $LCTL get_param -n $param_seq)
5460                 fi
5461                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5462
5463                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5464                 node=$(facet_active_host ost$((ostnum+1)))
5465                 param="obdfilter.$ostname.last_id"
5466                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5467                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5468                         ost_last_id=$ost_last
5469
5470                         if $support_last_seq; then
5471                                 ost_last_id=$(echo $ost_last |
5472                                               awk -F':' '{print $2}' |
5473                                               sed -e "s/^0x//g")
5474                                 ost_last_seq=$(echo $ost_last |
5475                                                awk -F':' '{print $1}')
5476                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5477                         fi
5478
5479                         if [[ $ost_last_id != $mds_last ]]; then
5480                                 error "$ost_last_id != $mds_last"
5481                         else
5482                                 found=true
5483                                 break
5484                         fi
5485                 done
5486         done
5487         $found || error "can not match last_seq/last_id for $mdtosc"
5488         return 0
5489 }
5490 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5491
5492 test_54a() {
5493         perl -MSocket -e ';' || skip "no Socket perl module installed"
5494
5495         $SOCKETSERVER $DIR/socket ||
5496                 error "$SOCKETSERVER $DIR/socket failed: $?"
5497         $SOCKETCLIENT $DIR/socket ||
5498                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5499         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5500 }
5501 run_test 54a "unix domain socket test =========================="
5502
5503 test_54b() {
5504         f="$DIR/f54b"
5505         mknod $f c 1 3
5506         chmod 0666 $f
5507         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5508 }
5509 run_test 54b "char device works in lustre ======================"
5510
5511 find_loop_dev() {
5512         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5513         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5514         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5515
5516         for i in $(seq 3 7); do
5517                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5518                 LOOPDEV=$LOOPBASE$i
5519                 LOOPNUM=$i
5520                 break
5521         done
5522 }
5523
5524 cleanup_54c() {
5525         local rc=0
5526         loopdev="$DIR/loop54c"
5527
5528         trap 0
5529         $UMOUNT $DIR/$tdir || rc=$?
5530         losetup -d $loopdev || true
5531         losetup -d $LOOPDEV || true
5532         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5533         return $rc
5534 }
5535
5536 test_54c() {
5537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5538
5539         loopdev="$DIR/loop54c"
5540
5541         find_loop_dev
5542         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5543         trap cleanup_54c EXIT
5544         mknod $loopdev b 7 $LOOPNUM
5545         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5546         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5547         losetup $loopdev $DIR/$tfile ||
5548                 error "can't set up $loopdev for $DIR/$tfile"
5549         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5550         test_mkdir $DIR/$tdir
5551         mount -t ext2 $loopdev $DIR/$tdir ||
5552                 error "error mounting $loopdev on $DIR/$tdir"
5553         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5554                 error "dd write"
5555         df $DIR/$tdir
5556         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5557                 error "dd read"
5558         cleanup_54c
5559 }
5560 run_test 54c "block device works in lustre ====================="
5561
5562 test_54d() {
5563         f="$DIR/f54d"
5564         string="aaaaaa"
5565         mknod $f p
5566         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5567 }
5568 run_test 54d "fifo device works in lustre ======================"
5569
5570 test_54e() {
5571         f="$DIR/f54e"
5572         string="aaaaaa"
5573         cp -aL /dev/console $f
5574         echo $string > $f || error "echo $string to $f failed"
5575 }
5576 run_test 54e "console/tty device works in lustre ======================"
5577
5578 test_56a() {
5579         local numfiles=3
5580         local dir=$DIR/$tdir
5581
5582         rm -rf $dir
5583         test_mkdir -p $dir/dir
5584         for i in $(seq $numfiles); do
5585                 touch $dir/file$i
5586                 touch $dir/dir/file$i
5587         done
5588
5589         local numcomp=$($LFS getstripe --component-count $dir)
5590
5591         [[ $numcomp == 0 ]] && numcomp=1
5592
5593         # test lfs getstripe with --recursive
5594         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5595
5596         [[ $filenum -eq $((numfiles * 2)) ]] ||
5597                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5598         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5599         [[ $filenum -eq $numfiles ]] ||
5600                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5601         echo "$LFS getstripe showed obdidx or l_ost_idx"
5602
5603         # test lfs getstripe with file instead of dir
5604         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5605         [[ $filenum -eq 1 ]] ||
5606                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5607         echo "$LFS getstripe file1 passed"
5608
5609         #test lfs getstripe with --verbose
5610         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5611         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5612                 error "$LFS getstripe --verbose $dir: "\
5613                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5614         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5615                 error "$LFS getstripe $dir: showed lmm_magic"
5616
5617         #test lfs getstripe with -v prints lmm_fid
5618         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5619         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5620                 error "$LFS getstripe -v $dir: "\
5621                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5622         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5623                 error "$LFS getstripe $dir: showed lmm_fid by default"
5624         echo "$LFS getstripe --verbose passed"
5625
5626         #check for FID information
5627         local fid1=$($LFS getstripe --fid $dir/file1)
5628         local fid2=$($LFS getstripe --verbose $dir/file1 |
5629                      awk '/lmm_fid: / { print $2; exit; }')
5630         local fid3=$($LFS path2fid $dir/file1)
5631
5632         [ "$fid1" != "$fid2" ] &&
5633                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5634         [ "$fid1" != "$fid3" ] &&
5635                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5636         echo "$LFS getstripe --fid passed"
5637
5638         #test lfs getstripe with --obd
5639         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5640                 error "$LFS getstripe --obd wrong_uuid: should return error"
5641
5642         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5643
5644         local ostidx=1
5645         local obduuid=$(ostuuid_from_index $ostidx)
5646         local found=$($LFS getstripe -r --obd $obduuid $dir |
5647                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5648
5649         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5650         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5651                 ((filenum--))
5652         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5653                 ((filenum--))
5654
5655         [[ $found -eq $filenum ]] ||
5656                 error "$LFS getstripe --obd: found $found expect $filenum"
5657         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5658                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5659                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5660                 error "$LFS getstripe --obd: should not show file on other obd"
5661         echo "$LFS getstripe --obd passed"
5662 }
5663 run_test 56a "check $LFS getstripe"
5664
5665 test_56b() {
5666         local dir=$DIR/$tdir
5667         local numdirs=3
5668
5669         test_mkdir $dir
5670         for i in $(seq $numdirs); do
5671                 test_mkdir $dir/dir$i
5672         done
5673
5674         # test lfs getdirstripe default mode is non-recursion, which is
5675         # different from lfs getstripe
5676         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5677
5678         [[ $dircnt -eq 1 ]] ||
5679                 error "$LFS getdirstripe: found $dircnt, not 1"
5680         dircnt=$($LFS getdirstripe --recursive $dir |
5681                 grep -c lmv_stripe_count)
5682         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5683                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5684 }
5685 run_test 56b "check $LFS getdirstripe"
5686
5687 test_56c() {
5688         remote_ost_nodsh && skip "remote OST with nodsh"
5689
5690         local ost_idx=0
5691         local ost_name=$(ostname_from_index $ost_idx)
5692         local old_status=$(ost_dev_status $ost_idx)
5693         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5694
5695         [[ -z "$old_status" ]] ||
5696                 skip_env "OST $ost_name is in $old_status status"
5697
5698         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5699         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5700                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5701         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5702                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5703                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5704         fi
5705
5706         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5707                 error "$LFS df -v showing inactive devices"
5708         sleep_maxage
5709
5710         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5711
5712         [[ "$new_status" =~ "D" ]] ||
5713                 error "$ost_name status is '$new_status', missing 'D'"
5714         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5715                 [[ "$new_status" =~ "N" ]] ||
5716                         error "$ost_name status is '$new_status', missing 'N'"
5717         fi
5718         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5719                 [[ "$new_status" =~ "f" ]] ||
5720                         error "$ost_name status is '$new_status', missing 'f'"
5721         fi
5722
5723         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5724         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5725                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5726         [[ -z "$p" ]] && restore_lustre_params < $p || true
5727         sleep_maxage
5728
5729         new_status=$(ost_dev_status $ost_idx)
5730         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5731                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5732         # can't check 'f' as devices may actually be on flash
5733 }
5734 run_test 56c "check 'lfs df' showing device status"
5735
5736 test_56d() {
5737         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5738         local osts=$($LFS df -v $MOUNT | grep -c OST)
5739
5740         $LFS df $MOUNT
5741
5742         (( mdts == MDSCOUNT )) ||
5743                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5744         (( osts == OSTCOUNT )) ||
5745                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5746 }
5747 run_test 56d "'lfs df -v' prints only configured devices"
5748
5749 NUMFILES=3
5750 NUMDIRS=3
5751 setup_56() {
5752         local local_tdir="$1"
5753         local local_numfiles="$2"
5754         local local_numdirs="$3"
5755         local dir_params="$4"
5756         local dir_stripe_params="$5"
5757
5758         if [ ! -d "$local_tdir" ] ; then
5759                 test_mkdir -p $dir_stripe_params $local_tdir
5760                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5761                 for i in $(seq $local_numfiles) ; do
5762                         touch $local_tdir/file$i
5763                 done
5764                 for i in $(seq $local_numdirs) ; do
5765                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5766                         for j in $(seq $local_numfiles) ; do
5767                                 touch $local_tdir/dir$i/file$j
5768                         done
5769                 done
5770         fi
5771 }
5772
5773 setup_56_special() {
5774         local local_tdir=$1
5775         local local_numfiles=$2
5776         local local_numdirs=$3
5777
5778         setup_56 $local_tdir $local_numfiles $local_numdirs
5779
5780         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5781                 for i in $(seq $local_numfiles) ; do
5782                         mknod $local_tdir/loop${i}b b 7 $i
5783                         mknod $local_tdir/null${i}c c 1 3
5784                         ln -s $local_tdir/file1 $local_tdir/link${i}
5785                 done
5786                 for i in $(seq $local_numdirs) ; do
5787                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5788                         mknod $local_tdir/dir$i/null${i}c c 1 3
5789                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5790                 done
5791         fi
5792 }
5793
5794 test_56g() {
5795         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5796         local expected=$(($NUMDIRS + 2))
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 56g "check lfs find -name"
5810
5811 test_56h() {
5812         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5813         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5814
5815         setup_56 $dir $NUMFILES $NUMDIRS
5816
5817         # test lfs find with ! -name
5818         for i in $(seq $NUMFILES) ; do
5819                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5820
5821                 [ $nums -eq $expected ] ||
5822                         error "lfs find ! -name '*$i' $dir wrong: "\
5823                               "found $nums, expected $expected"
5824         done
5825 }
5826 run_test 56h "check lfs find ! -name"
5827
5828 test_56i() {
5829         local dir=$DIR/$tdir
5830
5831         test_mkdir $dir
5832
5833         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5834         local out=$($cmd)
5835
5836         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5837 }
5838 run_test 56i "check 'lfs find -ost UUID' skips directories"
5839
5840 test_56j() {
5841         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5842
5843         setup_56_special $dir $NUMFILES $NUMDIRS
5844
5845         local expected=$((NUMDIRS + 1))
5846         local cmd="$LFS find -type d $dir"
5847         local nums=$($cmd | wc -l)
5848
5849         [ $nums -eq $expected ] ||
5850                 error "'$cmd' wrong: found $nums, expected $expected"
5851 }
5852 run_test 56j "check lfs find -type d"
5853
5854 test_56k() {
5855         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5856
5857         setup_56_special $dir $NUMFILES $NUMDIRS
5858
5859         local expected=$(((NUMDIRS + 1) * NUMFILES))
5860         local cmd="$LFS find -type f $dir"
5861         local nums=$($cmd | wc -l)
5862
5863         [ $nums -eq $expected ] ||
5864                 error "'$cmd' wrong: found $nums, expected $expected"
5865 }
5866 run_test 56k "check lfs find -type f"
5867
5868 test_56l() {
5869         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5870
5871         setup_56_special $dir $NUMFILES $NUMDIRS
5872
5873         local expected=$((NUMDIRS + NUMFILES))
5874         local cmd="$LFS find -type b $dir"
5875         local nums=$($cmd | wc -l)
5876
5877         [ $nums -eq $expected ] ||
5878                 error "'$cmd' wrong: found $nums, expected $expected"
5879 }
5880 run_test 56l "check lfs find -type b"
5881
5882 test_56m() {
5883         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5884
5885         setup_56_special $dir $NUMFILES $NUMDIRS
5886
5887         local expected=$((NUMDIRS + NUMFILES))
5888         local cmd="$LFS find -type c $dir"
5889         local nums=$($cmd | wc -l)
5890         [ $nums -eq $expected ] ||
5891                 error "'$cmd' wrong: found $nums, expected $expected"
5892 }
5893 run_test 56m "check lfs find -type c"
5894
5895 test_56n() {
5896         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5897         setup_56_special $dir $NUMFILES $NUMDIRS
5898
5899         local expected=$((NUMDIRS + NUMFILES))
5900         local cmd="$LFS find -type l $dir"
5901         local nums=$($cmd | wc -l)
5902
5903         [ $nums -eq $expected ] ||
5904                 error "'$cmd' wrong: found $nums, expected $expected"
5905 }
5906 run_test 56n "check lfs find -type l"
5907
5908 test_56o() {
5909         local dir=$DIR/$tdir
5910
5911         setup_56 $dir $NUMFILES $NUMDIRS
5912         utime $dir/file1 > /dev/null || error "utime (1)"
5913         utime $dir/file2 > /dev/null || error "utime (2)"
5914         utime $dir/dir1 > /dev/null || error "utime (3)"
5915         utime $dir/dir2 > /dev/null || error "utime (4)"
5916         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5917         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5918
5919         local expected=4
5920         local nums=$($LFS find -mtime +0 $dir | wc -l)
5921
5922         [ $nums -eq $expected ] ||
5923                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5924
5925         expected=12
5926         cmd="$LFS find -mtime 0 $dir"
5927         nums=$($cmd | wc -l)
5928         [ $nums -eq $expected ] ||
5929                 error "'$cmd' wrong: found $nums, expected $expected"
5930 }
5931 run_test 56o "check lfs find -mtime for old files"
5932
5933 test_56ob() {
5934         local dir=$DIR/$tdir
5935         local expected=1
5936         local count=0
5937
5938         # just to make sure there is something that won't be found
5939         test_mkdir $dir
5940         touch $dir/$tfile.now
5941
5942         for age in year week day hour min; do
5943                 count=$((count + 1))
5944
5945                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5946                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5947                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5948
5949                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5950                 local nums=$($cmd | wc -l)
5951                 [ $nums -eq $expected ] ||
5952                         error "'$cmd' wrong: found $nums, expected $expected"
5953
5954                 cmd="$LFS find $dir -atime $count${age:0:1}"
5955                 nums=$($cmd | wc -l)
5956                 [ $nums -eq $expected ] ||
5957                         error "'$cmd' wrong: found $nums, expected $expected"
5958         done
5959
5960         sleep 2
5961         cmd="$LFS find $dir -ctime +1s -type f"
5962         nums=$($cmd | wc -l)
5963         (( $nums == $count * 2 + 1)) ||
5964                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5965 }
5966 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5967
5968 test_newerXY_base() {
5969         local x=$1
5970         local y=$2
5971         local dir=$DIR/$tdir
5972         local ref
5973         local negref
5974
5975         if [ $y == "t" ]; then
5976                 if [ $x == "b" ]; then
5977                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5978                 else
5979                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5980                 fi
5981         else
5982                 ref=$DIR/$tfile.newer.$x$y
5983                 touch $ref || error "touch $ref failed"
5984         fi
5985
5986         echo "before = $ref"
5987         sleep 2
5988         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5989         sleep 2
5990         if [ $y == "t" ]; then
5991                 if [ $x == "b" ]; then
5992                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5993                 else
5994                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5995                 fi
5996         else
5997                 negref=$DIR/$tfile.negnewer.$x$y
5998                 touch $negref || error "touch $negref failed"
5999         fi
6000
6001         echo "after = $negref"
6002         local cmd="$LFS find $dir -newer$x$y $ref"
6003         local nums=$(eval $cmd | wc -l)
6004         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6005
6006         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6007                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6008
6009         cmd="$LFS find $dir ! -newer$x$y $negref"
6010         nums=$(eval $cmd | wc -l)
6011         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6012                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6013
6014         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6015         nums=$(eval $cmd | wc -l)
6016         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6017                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6018
6019         rm -rf $DIR/*
6020 }
6021
6022 test_56oc() {
6023         test_newerXY_base "a" "a"
6024         test_newerXY_base "a" "m"
6025         test_newerXY_base "a" "c"
6026         test_newerXY_base "m" "a"
6027         test_newerXY_base "m" "m"
6028         test_newerXY_base "m" "c"
6029         test_newerXY_base "c" "a"
6030         test_newerXY_base "c" "m"
6031         test_newerXY_base "c" "c"
6032
6033         [[ -n "$sles_version" ]] &&
6034                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6035
6036         test_newerXY_base "a" "t"
6037         test_newerXY_base "m" "t"
6038         test_newerXY_base "c" "t"
6039
6040         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6041            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6042                 ! btime_supported && echo "btime unsupported" && return 0
6043
6044         test_newerXY_base "b" "b"
6045         test_newerXY_base "b" "t"
6046 }
6047 run_test 56oc "check lfs find -newerXY work"
6048
6049 btime_supported() {
6050         local dir=$DIR/$tdir
6051         local rc
6052
6053         mkdir -p $dir
6054         touch $dir/$tfile
6055         $LFS find $dir -btime -1d -type f
6056         rc=$?
6057         rm -rf $dir
6058         return $rc
6059 }
6060
6061 test_56od() {
6062         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6063                 ! btime_supported && skip "btime unsupported on MDS"
6064
6065         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6066                 ! btime_supported && skip "btime unsupported on clients"
6067
6068         local dir=$DIR/$tdir
6069         local ref=$DIR/$tfile.ref
6070         local negref=$DIR/$tfile.negref
6071
6072         mkdir $dir || error "mkdir $dir failed"
6073         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6074         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6075         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6076         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6077         touch $ref || error "touch $ref failed"
6078         # sleep 3 seconds at least
6079         sleep 3
6080
6081         local before=$(do_facet mds1 date +%s)
6082         local skew=$(($(date +%s) - before + 1))
6083
6084         if (( skew < 0 && skew > -5 )); then
6085                 sleep $((0 - skew + 1))
6086                 skew=0
6087         fi
6088
6089         # Set the dir stripe params to limit files all on MDT0,
6090         # otherwise we need to calc the max clock skew between
6091         # the client and MDTs.
6092         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6093         sleep 2
6094         touch $negref || error "touch $negref failed"
6095
6096         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6097         local nums=$($cmd | wc -l)
6098         local expected=$(((NUMFILES + 1) * NUMDIRS))
6099
6100         [ $nums -eq $expected ] ||
6101                 error "'$cmd' wrong: found $nums, expected $expected"
6102
6103         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6104         nums=$($cmd | wc -l)
6105         expected=$((NUMFILES + 1))
6106         [ $nums -eq $expected ] ||
6107                 error "'$cmd' wrong: found $nums, expected $expected"
6108
6109         [ $skew -lt 0 ] && return
6110
6111         local after=$(do_facet mds1 date +%s)
6112         local age=$((after - before + 1 + skew))
6113
6114         cmd="$LFS find $dir -btime -${age}s -type f"
6115         nums=$($cmd | wc -l)
6116         expected=$(((NUMFILES + 1) * NUMDIRS))
6117
6118         echo "Clock skew between client and server: $skew, age:$age"
6119         [ $nums -eq $expected ] ||
6120                 error "'$cmd' wrong: found $nums, expected $expected"
6121
6122         expected=$(($NUMDIRS + 1))
6123         cmd="$LFS find $dir -btime -${age}s -type d"
6124         nums=$($cmd | wc -l)
6125         [ $nums -eq $expected ] ||
6126                 error "'$cmd' wrong: found $nums, expected $expected"
6127         rm -f $ref $negref || error "Failed to remove $ref $negref"
6128 }
6129 run_test 56od "check lfs find -btime with units"
6130
6131 test_56p() {
6132         [ $RUNAS_ID -eq $UID ] &&
6133                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6134
6135         local dir=$DIR/$tdir
6136
6137         setup_56 $dir $NUMFILES $NUMDIRS
6138         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6139
6140         local expected=$NUMFILES
6141         local cmd="$LFS find -uid $RUNAS_ID $dir"
6142         local nums=$($cmd | wc -l)
6143
6144         [ $nums -eq $expected ] ||
6145                 error "'$cmd' wrong: found $nums, expected $expected"
6146
6147         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6148         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6149         nums=$($cmd | wc -l)
6150         [ $nums -eq $expected ] ||
6151                 error "'$cmd' wrong: found $nums, expected $expected"
6152 }
6153 run_test 56p "check lfs find -uid and ! -uid"
6154
6155 test_56q() {
6156         [ $RUNAS_ID -eq $UID ] &&
6157                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6158
6159         local dir=$DIR/$tdir
6160
6161         setup_56 $dir $NUMFILES $NUMDIRS
6162         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6163
6164         local expected=$NUMFILES
6165         local cmd="$LFS find -gid $RUNAS_GID $dir"
6166         local nums=$($cmd | wc -l)
6167
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170
6171         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6172         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6173         nums=$($cmd | wc -l)
6174         [ $nums -eq $expected ] ||
6175                 error "'$cmd' wrong: found $nums, expected $expected"
6176 }
6177 run_test 56q "check lfs find -gid and ! -gid"
6178
6179 test_56r() {
6180         local dir=$DIR/$tdir
6181
6182         setup_56 $dir $NUMFILES $NUMDIRS
6183
6184         local expected=12
6185         local cmd="$LFS find -size 0 -type f -lazy $dir"
6186         local nums=$($cmd | wc -l)
6187
6188         [ $nums -eq $expected ] ||
6189                 error "'$cmd' wrong: found $nums, expected $expected"
6190         cmd="$LFS find -size 0 -type f $dir"
6191         nums=$($cmd | wc -l)
6192         [ $nums -eq $expected ] ||
6193                 error "'$cmd' wrong: found $nums, expected $expected"
6194
6195         expected=0
6196         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6197         nums=$($cmd | wc -l)
6198         [ $nums -eq $expected ] ||
6199                 error "'$cmd' wrong: found $nums, expected $expected"
6200         cmd="$LFS find ! -size 0 -type f $dir"
6201         nums=$($cmd | wc -l)
6202         [ $nums -eq $expected ] ||
6203                 error "'$cmd' wrong: found $nums, expected $expected"
6204
6205         echo "test" > $dir/$tfile
6206         echo "test2" > $dir/$tfile.2 && sync
6207         expected=1
6208         cmd="$LFS find -size 5 -type f -lazy $dir"
6209         nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find -size 5 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=1
6218         cmd="$LFS find -size +5 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find -size +5 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226
6227         expected=2
6228         cmd="$LFS find -size +0 -type f -lazy $dir"
6229         nums=$($cmd | wc -l)
6230         [ $nums -eq $expected ] ||
6231                 error "'$cmd' wrong: found $nums, expected $expected"
6232         cmd="$LFS find -size +0 -type f $dir"
6233         nums=$($cmd | wc -l)
6234         [ $nums -eq $expected ] ||
6235                 error "'$cmd' wrong: found $nums, expected $expected"
6236
6237         expected=2
6238         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6239         nums=$($cmd | wc -l)
6240         [ $nums -eq $expected ] ||
6241                 error "'$cmd' wrong: found $nums, expected $expected"
6242         cmd="$LFS find ! -size -5 -type f $dir"
6243         nums=$($cmd | wc -l)
6244         [ $nums -eq $expected ] ||
6245                 error "'$cmd' wrong: found $nums, expected $expected"
6246
6247         expected=12
6248         cmd="$LFS find -size -5 -type f -lazy $dir"
6249         nums=$($cmd | wc -l)
6250         [ $nums -eq $expected ] ||
6251                 error "'$cmd' wrong: found $nums, expected $expected"
6252         cmd="$LFS find -size -5 -type f $dir"
6253         nums=$($cmd | wc -l)
6254         [ $nums -eq $expected ] ||
6255                 error "'$cmd' wrong: found $nums, expected $expected"
6256 }
6257 run_test 56r "check lfs find -size works"
6258
6259 test_56ra_sub() {
6260         local expected=$1
6261         local glimpses=$2
6262         local cmd="$3"
6263
6264         cancel_lru_locks $OSC
6265
6266         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6267         local nums=$($cmd | wc -l)
6268
6269         [ $nums -eq $expected ] ||
6270                 error "'$cmd' wrong: found $nums, expected $expected"
6271
6272         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6273
6274         if (( rpcs_before + glimpses != rpcs_after )); then
6275                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6276                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6277
6278                 if [[ $glimpses == 0 ]]; then
6279                         error "'$cmd' should not send glimpse RPCs to OST"
6280                 else
6281                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6282                 fi
6283         fi
6284 }
6285
6286 test_56ra() {
6287         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6288                 skip "MDS < 2.12.58 doesn't return LSOM data"
6289         local dir=$DIR/$tdir
6290         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6291
6292         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6293
6294         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6295         $LCTL set_param -n llite.*.statahead_agl=0
6296         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6297
6298         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6299         # open and close all files to ensure LSOM is updated
6300         cancel_lru_locks $OSC
6301         find $dir -type f | xargs cat > /dev/null
6302
6303         #   expect_found  glimpse_rpcs  command_to_run
6304         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6305         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6306         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6307         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6308
6309         echo "test" > $dir/$tfile
6310         echo "test2" > $dir/$tfile.2 && sync
6311         cancel_lru_locks $OSC
6312         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6313
6314         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6315         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6316         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6317         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6318
6319         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6320         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6321         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6322         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6323         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6324         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6325 }
6326 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6327
6328 test_56rb() {
6329         local dir=$DIR/$tdir
6330         local tmp=$TMP/$tfile.log
6331         local mdt_idx;
6332
6333         test_mkdir -p $dir || error "failed to mkdir $dir"
6334         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6335                 error "failed to setstripe $dir/$tfile"
6336         mdt_idx=$($LFS getdirstripe -i $dir)
6337         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6338
6339         stack_trap "rm -f $tmp" EXIT
6340         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6341         ! grep -q obd_uuid $tmp ||
6342                 error "failed to find --size +100K --ost 0 $dir"
6343         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6344         ! grep -q obd_uuid $tmp ||
6345                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6346 }
6347 run_test 56rb "check lfs find --size --ost/--mdt works"
6348
6349 test_56s() { # LU-611 #LU-9369
6350         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6351
6352         local dir=$DIR/$tdir
6353         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6354
6355         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6356         for i in $(seq $NUMDIRS); do
6357                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6358         done
6359
6360         local expected=$NUMDIRS
6361         local cmd="$LFS find -c $OSTCOUNT $dir"
6362         local nums=$($cmd | wc -l)
6363
6364         [ $nums -eq $expected ] || {
6365                 $LFS getstripe -R $dir
6366                 error "'$cmd' wrong: found $nums, expected $expected"
6367         }
6368
6369         expected=$((NUMDIRS + onestripe))
6370         cmd="$LFS find -stripe-count +0 -type f $dir"
6371         nums=$($cmd | wc -l)
6372         [ $nums -eq $expected ] || {
6373                 $LFS getstripe -R $dir
6374                 error "'$cmd' wrong: found $nums, expected $expected"
6375         }
6376
6377         expected=$onestripe
6378         cmd="$LFS find -stripe-count 1 -type f $dir"
6379         nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] || {
6381                 $LFS getstripe -R $dir
6382                 error "'$cmd' wrong: found $nums, expected $expected"
6383         }
6384
6385         cmd="$LFS find -stripe-count -2 -type f $dir"
6386         nums=$($cmd | wc -l)
6387         [ $nums -eq $expected ] || {
6388                 $LFS getstripe -R $dir
6389                 error "'$cmd' wrong: found $nums, expected $expected"
6390         }
6391
6392         expected=0
6393         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6394         nums=$($cmd | wc -l)
6395         [ $nums -eq $expected ] || {
6396                 $LFS getstripe -R $dir
6397                 error "'$cmd' wrong: found $nums, expected $expected"
6398         }
6399 }
6400 run_test 56s "check lfs find -stripe-count works"
6401
6402 test_56t() { # LU-611 #LU-9369
6403         local dir=$DIR/$tdir
6404
6405         setup_56 $dir 0 $NUMDIRS
6406         for i in $(seq $NUMDIRS); do
6407                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6408         done
6409
6410         local expected=$NUMDIRS
6411         local cmd="$LFS find -S 8M $dir"
6412         local nums=$($cmd | wc -l)
6413
6414         [ $nums -eq $expected ] || {
6415                 $LFS getstripe -R $dir
6416                 error "'$cmd' wrong: found $nums, expected $expected"
6417         }
6418         rm -rf $dir
6419
6420         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6421
6422         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6423
6424         expected=$(((NUMDIRS + 1) * NUMFILES))
6425         cmd="$LFS find -stripe-size 512k -type f $dir"
6426         nums=$($cmd | wc -l)
6427         [ $nums -eq $expected ] ||
6428                 error "'$cmd' wrong: found $nums, expected $expected"
6429
6430         cmd="$LFS find -stripe-size +320k -type f $dir"
6431         nums=$($cmd | wc -l)
6432         [ $nums -eq $expected ] ||
6433                 error "'$cmd' wrong: found $nums, expected $expected"
6434
6435         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6436         cmd="$LFS find -stripe-size +200k -type f $dir"
6437         nums=$($cmd | wc -l)
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         cmd="$LFS find -stripe-size -640k -type f $dir"
6442         nums=$($cmd | wc -l)
6443         [ $nums -eq $expected ] ||
6444                 error "'$cmd' wrong: found $nums, expected $expected"
6445
6446         expected=4
6447         cmd="$LFS find -stripe-size 256k -type f $dir"
6448         nums=$($cmd | wc -l)
6449         [ $nums -eq $expected ] ||
6450                 error "'$cmd' wrong: found $nums, expected $expected"
6451
6452         cmd="$LFS find -stripe-size -320k -type f $dir"
6453         nums=$($cmd | wc -l)
6454         [ $nums -eq $expected ] ||
6455                 error "'$cmd' wrong: found $nums, expected $expected"
6456
6457         expected=0
6458         cmd="$LFS find -stripe-size 1024k -type f $dir"
6459         nums=$($cmd | wc -l)
6460         [ $nums -eq $expected ] ||
6461                 error "'$cmd' wrong: found $nums, expected $expected"
6462 }
6463 run_test 56t "check lfs find -stripe-size works"
6464
6465 test_56u() { # LU-611
6466         local dir=$DIR/$tdir
6467
6468         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6469
6470         if [[ $OSTCOUNT -gt 1 ]]; then
6471                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6472                 onestripe=4
6473         else
6474                 onestripe=0
6475         fi
6476
6477         local expected=$(((NUMDIRS + 1) * NUMFILES))
6478         local cmd="$LFS find -stripe-index 0 -type f $dir"
6479         local nums=$($cmd | wc -l)
6480
6481         [ $nums -eq $expected ] ||
6482                 error "'$cmd' wrong: found $nums, expected $expected"
6483
6484         expected=$onestripe
6485         cmd="$LFS find -stripe-index 1 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6491         nums=$($cmd | wc -l)
6492         [ $nums -eq $expected ] ||
6493                 error "'$cmd' wrong: found $nums, expected $expected"
6494
6495         expected=0
6496         # This should produce an error and not return any files
6497         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6498         nums=$($cmd 2>/dev/null | wc -l)
6499         [ $nums -eq $expected ] ||
6500                 error "'$cmd' wrong: found $nums, expected $expected"
6501
6502         if [[ $OSTCOUNT -gt 1 ]]; then
6503                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6504                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6505                 nums=$($cmd | wc -l)
6506                 [ $nums -eq $expected ] ||
6507                         error "'$cmd' wrong: found $nums, expected $expected"
6508         fi
6509 }
6510 run_test 56u "check lfs find -stripe-index works"
6511
6512 test_56v() {
6513         local mdt_idx=0
6514         local dir=$DIR/$tdir
6515
6516         setup_56 $dir $NUMFILES $NUMDIRS
6517
6518         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6519         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6520
6521         for file in $($LFS find -m $UUID $dir); do
6522                 file_midx=$($LFS getstripe -m $file)
6523                 [ $file_midx -eq $mdt_idx ] ||
6524                         error "lfs find -m $UUID != getstripe -m $file_midx"
6525         done
6526 }
6527 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6528
6529 test_56w() {
6530         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6532
6533         local dir=$DIR/$tdir
6534
6535         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6536
6537         local stripe_size=$($LFS getstripe -S -d $dir) ||
6538                 error "$LFS getstripe -S -d $dir failed"
6539         stripe_size=${stripe_size%% *}
6540
6541         local file_size=$((stripe_size * OSTCOUNT))
6542         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6543         local required_space=$((file_num * file_size))
6544         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6545                            head -n1)
6546         [[ $free_space -le $((required_space / 1024)) ]] &&
6547                 skip_env "need $required_space, have $free_space kbytes"
6548
6549         local dd_bs=65536
6550         local dd_count=$((file_size / dd_bs))
6551
6552         # write data into the files
6553         local i
6554         local j
6555         local file
6556
6557         for i in $(seq $NUMFILES); do
6558                 file=$dir/file$i
6559                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6560                         error "write data into $file failed"
6561         done
6562         for i in $(seq $NUMDIRS); do
6563                 for j in $(seq $NUMFILES); do
6564                         file=$dir/dir$i/file$j
6565                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6566                                 error "write data into $file failed"
6567                 done
6568         done
6569
6570         # $LFS_MIGRATE will fail if hard link migration is unsupported
6571         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6572                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6573                         error "creating links to $dir/dir1/file1 failed"
6574         fi
6575
6576         local expected=-1
6577
6578         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6579
6580         # lfs_migrate file
6581         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6582
6583         echo "$cmd"
6584         eval $cmd || error "$cmd failed"
6585
6586         check_stripe_count $dir/file1 $expected
6587
6588         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6589         then
6590                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6591                 # OST 1 if it is on OST 0. This file is small enough to
6592                 # be on only one stripe.
6593                 file=$dir/migr_1_ost
6594                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6595                         error "write data into $file failed"
6596                 local obdidx=$($LFS getstripe -i $file)
6597                 local oldmd5=$(md5sum $file)
6598                 local newobdidx=0
6599
6600                 [[ $obdidx -eq 0 ]] && newobdidx=1
6601                 cmd="$LFS migrate -i $newobdidx $file"
6602                 echo $cmd
6603                 eval $cmd || error "$cmd failed"
6604
6605                 local realobdix=$($LFS getstripe -i $file)
6606                 local newmd5=$(md5sum $file)
6607
6608                 [[ $newobdidx -ne $realobdix ]] &&
6609                         error "new OST is different (was=$obdidx, "\
6610                               "wanted=$newobdidx, got=$realobdix)"
6611                 [[ "$oldmd5" != "$newmd5" ]] &&
6612                         error "md5sum differ: $oldmd5, $newmd5"
6613         fi
6614
6615         # lfs_migrate dir
6616         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6617         echo "$cmd"
6618         eval $cmd || error "$cmd failed"
6619
6620         for j in $(seq $NUMFILES); do
6621                 check_stripe_count $dir/dir1/file$j $expected
6622         done
6623
6624         # lfs_migrate works with lfs find
6625         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6626              $LFS_MIGRATE -y -c $expected"
6627         echo "$cmd"
6628         eval $cmd || error "$cmd failed"
6629
6630         for i in $(seq 2 $NUMFILES); do
6631                 check_stripe_count $dir/file$i $expected
6632         done
6633         for i in $(seq 2 $NUMDIRS); do
6634                 for j in $(seq $NUMFILES); do
6635                 check_stripe_count $dir/dir$i/file$j $expected
6636                 done
6637         done
6638 }
6639 run_test 56w "check lfs_migrate -c stripe_count works"
6640
6641 test_56wb() {
6642         local file1=$DIR/$tdir/file1
6643         local create_pool=false
6644         local initial_pool=$($LFS getstripe -p $DIR)
6645         local pool_list=()
6646         local pool=""
6647
6648         echo -n "Creating test dir..."
6649         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6650         echo "done."
6651
6652         echo -n "Creating test file..."
6653         touch $file1 || error "cannot create file"
6654         echo "done."
6655
6656         echo -n "Detecting existing pools..."
6657         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6658
6659         if [ ${#pool_list[@]} -gt 0 ]; then
6660                 echo "${pool_list[@]}"
6661                 for thispool in "${pool_list[@]}"; do
6662                         if [[ -z "$initial_pool" ||
6663                               "$initial_pool" != "$thispool" ]]; then
6664                                 pool="$thispool"
6665                                 echo "Using existing pool '$pool'"
6666                                 break
6667                         fi
6668                 done
6669         else
6670                 echo "none detected."
6671         fi
6672         if [ -z "$pool" ]; then
6673                 pool=${POOL:-testpool}
6674                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6675                 echo -n "Creating pool '$pool'..."
6676                 create_pool=true
6677                 pool_add $pool &> /dev/null ||
6678                         error "pool_add failed"
6679                 echo "done."
6680
6681                 echo -n "Adding target to pool..."
6682                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6683                         error "pool_add_targets failed"
6684                 echo "done."
6685         fi
6686
6687         echo -n "Setting pool using -p option..."
6688         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6689                 error "migrate failed rc = $?"
6690         echo "done."
6691
6692         echo -n "Verifying test file is in pool after migrating..."
6693         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6694                 error "file was not migrated to pool $pool"
6695         echo "done."
6696
6697         echo -n "Removing test file from pool '$pool'..."
6698         # "lfs migrate $file" won't remove the file from the pool
6699         # until some striping information is changed.
6700         $LFS migrate -c 1 $file1 &> /dev/null ||
6701                 error "cannot remove from pool"
6702         [ "$($LFS getstripe -p $file1)" ] &&
6703                 error "pool still set"
6704         echo "done."
6705
6706         echo -n "Setting pool using --pool option..."
6707         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6708                 error "migrate failed rc = $?"
6709         echo "done."
6710
6711         # Clean up
6712         rm -f $file1
6713         if $create_pool; then
6714                 destroy_test_pools 2> /dev/null ||
6715                         error "destroy test pools failed"
6716         fi
6717 }
6718 run_test 56wb "check lfs_migrate pool support"
6719
6720 test_56wc() {
6721         local file1="$DIR/$tdir/file1"
6722         local parent_ssize
6723         local parent_scount
6724         local cur_ssize
6725         local cur_scount
6726         local orig_ssize
6727
6728         echo -n "Creating test dir..."
6729         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6730         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6731                 error "cannot set stripe by '-S 1M -c 1'"
6732         echo "done"
6733
6734         echo -n "Setting initial stripe for test file..."
6735         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6736                 error "cannot set stripe"
6737         cur_ssize=$($LFS getstripe -S "$file1")
6738         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6739         echo "done."
6740
6741         # File currently set to -S 512K -c 1
6742
6743         # Ensure -c and -S options are rejected when -R is set
6744         echo -n "Verifying incompatible options are detected..."
6745         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6746                 error "incompatible -c and -R options not detected"
6747         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6748                 error "incompatible -S and -R options not detected"
6749         echo "done."
6750
6751         # Ensure unrecognized options are passed through to 'lfs migrate'
6752         echo -n "Verifying -S option is passed through to lfs migrate..."
6753         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6754                 error "migration failed"
6755         cur_ssize=$($LFS getstripe -S "$file1")
6756         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6757         echo "done."
6758
6759         # File currently set to -S 1M -c 1
6760
6761         # Ensure long options are supported
6762         echo -n "Verifying long options supported..."
6763         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6764                 error "long option without argument not supported"
6765         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6766                 error "long option with argument not supported"
6767         cur_ssize=$($LFS getstripe -S "$file1")
6768         [ $cur_ssize -eq 524288 ] ||
6769                 error "migrate --stripe-size $cur_ssize != 524288"
6770         echo "done."
6771
6772         # File currently set to -S 512K -c 1
6773
6774         if [ "$OSTCOUNT" -gt 1 ]; then
6775                 echo -n "Verifying explicit stripe count can be set..."
6776                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6777                         error "migrate failed"
6778                 cur_scount=$($LFS getstripe -c "$file1")
6779                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6780                 echo "done."
6781         fi
6782
6783         # File currently set to -S 512K -c 1 or -S 512K -c 2
6784
6785         # Ensure parent striping is used if -R is set, and no stripe
6786         # count or size is specified
6787         echo -n "Setting stripe for parent directory..."
6788         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6789                 error "cannot set stripe '-S 2M -c 1'"
6790         echo "done."
6791
6792         echo -n "Verifying restripe option uses parent stripe settings..."
6793         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6794         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6795         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6796                 error "migrate failed"
6797         cur_ssize=$($LFS getstripe -S "$file1")
6798         [ $cur_ssize -eq $parent_ssize ] ||
6799                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6800         cur_scount=$($LFS getstripe -c "$file1")
6801         [ $cur_scount -eq $parent_scount ] ||
6802                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6803         echo "done."
6804
6805         # File currently set to -S 1M -c 1
6806
6807         # Ensure striping is preserved if -R is not set, and no stripe
6808         # count or size is specified
6809         echo -n "Verifying striping size preserved when not specified..."
6810         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6811         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6812                 error "cannot set stripe on parent directory"
6813         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6814                 error "migrate failed"
6815         cur_ssize=$($LFS getstripe -S "$file1")
6816         [ $cur_ssize -eq $orig_ssize ] ||
6817                 error "migrate by default $cur_ssize != $orig_ssize"
6818         echo "done."
6819
6820         # Ensure file name properly detected when final option has no argument
6821         echo -n "Verifying file name properly detected..."
6822         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6823                 error "file name interpreted as option argument"
6824         echo "done."
6825
6826         # Clean up
6827         rm -f "$file1"
6828 }
6829 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6830
6831 test_56wd() {
6832         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6833
6834         local file1=$DIR/$tdir/file1
6835
6836         echo -n "Creating test dir..."
6837         test_mkdir $DIR/$tdir || error "cannot create dir"
6838         echo "done."
6839
6840         echo -n "Creating test file..."
6841         touch $file1
6842         echo "done."
6843
6844         # Ensure 'lfs migrate' will fail by using a non-existent option,
6845         # and make sure rsync is not called to recover
6846         echo -n "Make sure --no-rsync option works..."
6847         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6848                 grep -q 'refusing to fall back to rsync' ||
6849                 error "rsync was called with --no-rsync set"
6850         echo "done."
6851
6852         # Ensure rsync is called without trying 'lfs migrate' first
6853         echo -n "Make sure --rsync option works..."
6854         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6855                 grep -q 'falling back to rsync' &&
6856                 error "lfs migrate was called with --rsync set"
6857         echo "done."
6858
6859         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6860         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6861                 grep -q 'at the same time' ||
6862                 error "--rsync and --no-rsync accepted concurrently"
6863         echo "done."
6864
6865         # Clean up
6866         rm -f $file1
6867 }
6868 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6869
6870 test_56we() {
6871         local td=$DIR/$tdir
6872         local tf=$td/$tfile
6873
6874         test_mkdir $td || error "cannot create $td"
6875         touch $tf || error "cannot touch $tf"
6876
6877         echo -n "Make sure --non-direct|-D works..."
6878         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6879                 grep -q "lfs migrate --non-direct" ||
6880                 error "--non-direct option cannot work correctly"
6881         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6882                 grep -q "lfs migrate -D" ||
6883                 error "-D option cannot work correctly"
6884         echo "done."
6885 }
6886 run_test 56we "check lfs_migrate --non-direct|-D support"
6887
6888 test_56x() {
6889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6890         check_swap_layouts_support
6891
6892         local dir=$DIR/$tdir
6893         local ref1=/etc/passwd
6894         local file1=$dir/file1
6895
6896         test_mkdir $dir || error "creating dir $dir"
6897         $LFS setstripe -c 2 $file1
6898         cp $ref1 $file1
6899         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6900         stripe=$($LFS getstripe -c $file1)
6901         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6902         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6903
6904         # clean up
6905         rm -f $file1
6906 }
6907 run_test 56x "lfs migration support"
6908
6909 test_56xa() {
6910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6911         check_swap_layouts_support
6912
6913         local dir=$DIR/$tdir/$testnum
6914
6915         test_mkdir -p $dir
6916
6917         local ref1=/etc/passwd
6918         local file1=$dir/file1
6919
6920         $LFS setstripe -c 2 $file1
6921         cp $ref1 $file1
6922         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6923
6924         local stripe=$($LFS getstripe -c $file1)
6925
6926         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6927         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6928
6929         # clean up
6930         rm -f $file1
6931 }
6932 run_test 56xa "lfs migration --block support"
6933
6934 check_migrate_links() {
6935         local dir="$1"
6936         local file1="$dir/file1"
6937         local begin="$2"
6938         local count="$3"
6939         local runas="$4"
6940         local total_count=$(($begin + $count - 1))
6941         local symlink_count=10
6942         local uniq_count=10
6943
6944         if [ ! -f "$file1" ]; then
6945                 echo -n "creating initial file..."
6946                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6947                         error "cannot setstripe initial file"
6948                 echo "done"
6949
6950                 echo -n "creating symlinks..."
6951                 for s in $(seq 1 $symlink_count); do
6952                         ln -s "$file1" "$dir/slink$s" ||
6953                                 error "cannot create symlinks"
6954                 done
6955                 echo "done"
6956
6957                 echo -n "creating nonlinked files..."
6958                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6959                         error "cannot create nonlinked files"
6960                 echo "done"
6961         fi
6962
6963         # create hard links
6964         if [ ! -f "$dir/file$total_count" ]; then
6965                 echo -n "creating hard links $begin:$total_count..."
6966                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6967                         /dev/null || error "cannot create hard links"
6968                 echo "done"
6969         fi
6970
6971         echo -n "checking number of hard links listed in xattrs..."
6972         local fid=$($LFS getstripe -F "$file1")
6973         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6974
6975         echo "${#paths[*]}"
6976         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6977                         skip "hard link list has unexpected size, skipping test"
6978         fi
6979         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6980                         error "link names should exceed xattrs size"
6981         fi
6982
6983         echo -n "migrating files..."
6984         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6985         local rc=$?
6986         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6987         echo "done"
6988
6989         # make sure all links have been properly migrated
6990         echo -n "verifying files..."
6991         fid=$($LFS getstripe -F "$file1") ||
6992                 error "cannot get fid for file $file1"
6993         for i in $(seq 2 $total_count); do
6994                 local fid2=$($LFS getstripe -F $dir/file$i)
6995
6996                 [ "$fid2" == "$fid" ] ||
6997                         error "migrated hard link has mismatched FID"
6998         done
6999
7000         # make sure hard links were properly detected, and migration was
7001         # performed only once for the entire link set; nonlinked files should
7002         # also be migrated
7003         local actual=$(grep -c 'done' <<< "$migrate_out")
7004         local expected=$(($uniq_count + 1))
7005
7006         [ "$actual" -eq  "$expected" ] ||
7007                 error "hard links individually migrated ($actual != $expected)"
7008
7009         # make sure the correct number of hard links are present
7010         local hardlinks=$(stat -c '%h' "$file1")
7011
7012         [ $hardlinks -eq $total_count ] ||
7013                 error "num hard links $hardlinks != $total_count"
7014         echo "done"
7015
7016         return 0
7017 }
7018
7019 test_56xb() {
7020         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7021                 skip "Need MDS version at least 2.10.55"
7022
7023         local dir="$DIR/$tdir"
7024
7025         test_mkdir "$dir" || error "cannot create dir $dir"
7026
7027         echo "testing lfs migrate mode when all links fit within xattrs"
7028         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7029
7030         echo "testing rsync mode when all links fit within xattrs"
7031         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7032
7033         echo "testing lfs migrate mode when all links do not fit within xattrs"
7034         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7035
7036         echo "testing rsync mode when all links do not fit within xattrs"
7037         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7038
7039         chown -R $RUNAS_ID $dir
7040         echo "testing non-root lfs migrate mode when not all links are in xattr"
7041         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7042
7043         # clean up
7044         rm -rf $dir
7045 }
7046 run_test 56xb "lfs migration hard link support"
7047
7048 test_56xc() {
7049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7050
7051         local dir="$DIR/$tdir"
7052
7053         test_mkdir "$dir" || error "cannot create dir $dir"
7054
7055         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7056         echo -n "Setting initial stripe for 20MB test file..."
7057         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7058                 error "cannot setstripe 20MB file"
7059         echo "done"
7060         echo -n "Sizing 20MB test file..."
7061         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7062         echo "done"
7063         echo -n "Verifying small file autostripe count is 1..."
7064         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7065                 error "cannot migrate 20MB file"
7066         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7067                 error "cannot get stripe for $dir/20mb"
7068         [ $stripe_count -eq 1 ] ||
7069                 error "unexpected stripe count $stripe_count for 20MB file"
7070         rm -f "$dir/20mb"
7071         echo "done"
7072
7073         # Test 2: File is small enough to fit within the available space on
7074         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7075         # have at least an additional 1KB for each desired stripe for test 3
7076         echo -n "Setting stripe for 1GB test file..."
7077         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7078         echo "done"
7079         echo -n "Sizing 1GB test file..."
7080         # File size is 1GB + 3KB
7081         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7082         echo "done"
7083
7084         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7085         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7086         if (( avail > 524288 * OSTCOUNT )); then
7087                 echo -n "Migrating 1GB file..."
7088                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7089                         error "cannot migrate 1GB file"
7090                 echo "done"
7091                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7092                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7093                         error "cannot getstripe for 1GB file"
7094                 [ $stripe_count -eq 2 ] ||
7095                         error "unexpected stripe count $stripe_count != 2"
7096                 echo "done"
7097         fi
7098
7099         # Test 3: File is too large to fit within the available space on
7100         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7101         if [ $OSTCOUNT -ge 3 ]; then
7102                 # The required available space is calculated as
7103                 # file size (1GB + 3KB) / OST count (3).
7104                 local kb_per_ost=349526
7105
7106                 echo -n "Migrating 1GB file with limit..."
7107                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7108                         error "cannot migrate 1GB file with limit"
7109                 echo "done"
7110
7111                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7112                 echo -n "Verifying 1GB autostripe count with limited space..."
7113                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7114                         error "unexpected stripe count $stripe_count (min 3)"
7115                 echo "done"
7116         fi
7117
7118         # clean up
7119         rm -rf $dir
7120 }
7121 run_test 56xc "lfs migration autostripe"
7122
7123 test_56xd() {
7124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7125
7126         local dir=$DIR/$tdir
7127         local f_mgrt=$dir/$tfile.mgrt
7128         local f_yaml=$dir/$tfile.yaml
7129         local f_copy=$dir/$tfile.copy
7130         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7131         local layout_copy="-c 2 -S 2M -i 1"
7132         local yamlfile=$dir/yamlfile
7133         local layout_before;
7134         local layout_after;
7135
7136         test_mkdir "$dir" || error "cannot create dir $dir"
7137         $LFS setstripe $layout_yaml $f_yaml ||
7138                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7139         $LFS getstripe --yaml $f_yaml > $yamlfile
7140         $LFS setstripe $layout_copy $f_copy ||
7141                 error "cannot setstripe $f_copy with layout $layout_copy"
7142         touch $f_mgrt
7143         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7144
7145         # 1. test option --yaml
7146         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7147                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7148         layout_before=$(get_layout_param $f_yaml)
7149         layout_after=$(get_layout_param $f_mgrt)
7150         [ "$layout_after" == "$layout_before" ] ||
7151                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7152
7153         # 2. test option --copy
7154         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7155                 error "cannot migrate $f_mgrt with --copy $f_copy"
7156         layout_before=$(get_layout_param $f_copy)
7157         layout_after=$(get_layout_param $f_mgrt)
7158         [ "$layout_after" == "$layout_before" ] ||
7159                 error "lfs_migrate --copy: $layout_after != $layout_before"
7160 }
7161 run_test 56xd "check lfs_migrate --yaml and --copy support"
7162
7163 test_56xe() {
7164         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7165
7166         local dir=$DIR/$tdir
7167         local f_comp=$dir/$tfile
7168         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7169         local layout_before=""
7170         local layout_after=""
7171
7172         test_mkdir "$dir" || error "cannot create dir $dir"
7173         $LFS setstripe $layout $f_comp ||
7174                 error "cannot setstripe $f_comp with layout $layout"
7175         layout_before=$(get_layout_param $f_comp)
7176         dd if=/dev/zero of=$f_comp bs=1M count=4
7177
7178         # 1. migrate a comp layout file by lfs_migrate
7179         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7180         layout_after=$(get_layout_param $f_comp)
7181         [ "$layout_before" == "$layout_after" ] ||
7182                 error "lfs_migrate: $layout_before != $layout_after"
7183
7184         # 2. migrate a comp layout file by lfs migrate
7185         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7186         layout_after=$(get_layout_param $f_comp)
7187         [ "$layout_before" == "$layout_after" ] ||
7188                 error "lfs migrate: $layout_before != $layout_after"
7189 }
7190 run_test 56xe "migrate a composite layout file"
7191
7192 test_56xf() {
7193         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7194
7195         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7196                 skip "Need server version at least 2.13.53"
7197
7198         local dir=$DIR/$tdir
7199         local f_comp=$dir/$tfile
7200         local layout="-E 1M -c1 -E -1 -c2"
7201         local fid_before=""
7202         local fid_after=""
7203
7204         test_mkdir "$dir" || error "cannot create dir $dir"
7205         $LFS setstripe $layout $f_comp ||
7206                 error "cannot setstripe $f_comp with layout $layout"
7207         fid_before=$($LFS getstripe --fid $f_comp)
7208         dd if=/dev/zero of=$f_comp bs=1M count=4
7209
7210         # 1. migrate a comp layout file to a comp layout
7211         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7212         fid_after=$($LFS getstripe --fid $f_comp)
7213         [ "$fid_before" == "$fid_after" ] ||
7214                 error "comp-to-comp migrate: $fid_before != $fid_after"
7215
7216         # 2. migrate a comp layout file to a plain layout
7217         $LFS migrate -c2 $f_comp ||
7218                 error "cannot migrate $f_comp by lfs migrate"
7219         fid_after=$($LFS getstripe --fid $f_comp)
7220         [ "$fid_before" == "$fid_after" ] ||
7221                 error "comp-to-plain migrate: $fid_before != $fid_after"
7222
7223         # 3. migrate a plain layout file to a comp layout
7224         $LFS migrate $layout $f_comp ||
7225                 error "cannot migrate $f_comp by lfs migrate"
7226         fid_after=$($LFS getstripe --fid $f_comp)
7227         [ "$fid_before" == "$fid_after" ] ||
7228                 error "plain-to-comp migrate: $fid_before != $fid_after"
7229 }
7230 run_test 56xf "FID is not lost during migration of a composite layout file"
7231
7232 test_56y() {
7233         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7234                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7235
7236         local res=""
7237         local dir=$DIR/$tdir
7238         local f1=$dir/file1
7239         local f2=$dir/file2
7240
7241         test_mkdir -p $dir || error "creating dir $dir"
7242         touch $f1 || error "creating std file $f1"
7243         $MULTIOP $f2 H2c || error "creating released file $f2"
7244
7245         # a directory can be raid0, so ask only for files
7246         res=$($LFS find $dir -L raid0 -type f | wc -l)
7247         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7248
7249         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7250         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7251
7252         # only files can be released, so no need to force file search
7253         res=$($LFS find $dir -L released)
7254         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7255
7256         res=$($LFS find $dir -type f \! -L released)
7257         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7258 }
7259 run_test 56y "lfs find -L raid0|released"
7260
7261 test_56z() { # LU-4824
7262         # This checks to make sure 'lfs find' continues after errors
7263         # There are two classes of errors that should be caught:
7264         # - If multiple paths are provided, all should be searched even if one
7265         #   errors out
7266         # - If errors are encountered during the search, it should not terminate
7267         #   early
7268         local dir=$DIR/$tdir
7269         local i
7270
7271         test_mkdir $dir
7272         for i in d{0..9}; do
7273                 test_mkdir $dir/$i
7274                 touch $dir/$i/$tfile
7275         done
7276         $LFS find $DIR/non_existent_dir $dir &&
7277                 error "$LFS find did not return an error"
7278         # Make a directory unsearchable. This should NOT be the last entry in
7279         # directory order.  Arbitrarily pick the 6th entry
7280         chmod 700 $($LFS find $dir -type d | sed '6!d')
7281
7282         $RUNAS $LFS find $DIR/non_existent $dir
7283         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7284
7285         # The user should be able to see 10 directories and 9 files
7286         (( count == 19 )) ||
7287                 error "$LFS find found $count != 19 entries after error"
7288 }
7289 run_test 56z "lfs find should continue after an error"
7290
7291 test_56aa() { # LU-5937
7292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7293
7294         local dir=$DIR/$tdir
7295
7296         mkdir $dir
7297         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7298
7299         createmany -o $dir/striped_dir/${tfile}- 1024
7300         local dirs=$($LFS find --size +8k $dir/)
7301
7302         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7303 }
7304 run_test 56aa "lfs find --size under striped dir"
7305
7306 test_56ab() { # LU-10705
7307         test_mkdir $DIR/$tdir
7308         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7309         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7310         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7311         # Flush writes to ensure valid blocks.  Need to be more thorough for
7312         # ZFS, since blocks are not allocated/returned to client immediately.
7313         sync_all_data
7314         wait_zfs_commit ost1 2
7315         cancel_lru_locks osc
7316         ls -ls $DIR/$tdir
7317
7318         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7319
7320         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7321
7322         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7323         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7324
7325         rm -f $DIR/$tdir/$tfile.[123]
7326 }
7327 run_test 56ab "lfs find --blocks"
7328
7329 test_56ba() {
7330         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7331                 skip "Need MDS version at least 2.10.50"
7332
7333         # Create composite files with one component
7334         local dir=$DIR/$tdir
7335
7336         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7337         # Create composite files with three components
7338         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7339         # Create non-composite files
7340         createmany -o $dir/${tfile}- 10
7341
7342         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7343
7344         [[ $nfiles == 10 ]] ||
7345                 error "lfs find -E 1M found $nfiles != 10 files"
7346
7347         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7348         [[ $nfiles == 25 ]] ||
7349                 error "lfs find ! -E 1M found $nfiles != 25 files"
7350
7351         # All files have a component that starts at 0
7352         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7353         [[ $nfiles == 35 ]] ||
7354                 error "lfs find --component-start 0 - $nfiles != 35 files"
7355
7356         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7357         [[ $nfiles == 15 ]] ||
7358                 error "lfs find --component-start 2M - $nfiles != 15 files"
7359
7360         # All files created here have a componenet that does not starts at 2M
7361         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7362         [[ $nfiles == 35 ]] ||
7363                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7364
7365         # Find files with a specified number of components
7366         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7367         [[ $nfiles == 15 ]] ||
7368                 error "lfs find --component-count 3 - $nfiles != 15 files"
7369
7370         # Remember non-composite files have a component count of zero
7371         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7372         [[ $nfiles == 10 ]] ||
7373                 error "lfs find --component-count 0 - $nfiles != 10 files"
7374
7375         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7376         [[ $nfiles == 20 ]] ||
7377                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7378
7379         # All files have a flag called "init"
7380         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7381         [[ $nfiles == 35 ]] ||
7382                 error "lfs find --component-flags init - $nfiles != 35 files"
7383
7384         # Multi-component files will have a component not initialized
7385         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7386         [[ $nfiles == 15 ]] ||
7387                 error "lfs find !--component-flags init - $nfiles != 15 files"
7388
7389         rm -rf $dir
7390
7391 }
7392 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7393
7394 test_56ca() {
7395         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7396                 skip "Need MDS version at least 2.10.57"
7397
7398         local td=$DIR/$tdir
7399         local tf=$td/$tfile
7400         local dir
7401         local nfiles
7402         local cmd
7403         local i
7404         local j
7405
7406         # create mirrored directories and mirrored files
7407         mkdir $td || error "mkdir $td failed"
7408         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7409         createmany -o $tf- 10 || error "create $tf- failed"
7410
7411         for i in $(seq 2); do
7412                 dir=$td/dir$i
7413                 mkdir $dir || error "mkdir $dir failed"
7414                 $LFS mirror create -N$((3 + i)) $dir ||
7415                         error "create mirrored dir $dir failed"
7416                 createmany -o $dir/$tfile- 10 ||
7417                         error "create $dir/$tfile- failed"
7418         done
7419
7420         # change the states of some mirrored files
7421         echo foo > $tf-6
7422         for i in $(seq 2); do
7423                 dir=$td/dir$i
7424                 for j in $(seq 4 9); do
7425                         echo foo > $dir/$tfile-$j
7426                 done
7427         done
7428
7429         # find mirrored files with specific mirror count
7430         cmd="$LFS find --mirror-count 3 --type f $td"
7431         nfiles=$($cmd | wc -l)
7432         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7433
7434         cmd="$LFS find ! --mirror-count 3 --type f $td"
7435         nfiles=$($cmd | wc -l)
7436         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7437
7438         cmd="$LFS find --mirror-count +2 --type f $td"
7439         nfiles=$($cmd | wc -l)
7440         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7441
7442         cmd="$LFS find --mirror-count -6 --type f $td"
7443         nfiles=$($cmd | wc -l)
7444         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7445
7446         # find mirrored files with specific file state
7447         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7448         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7449
7450         cmd="$LFS find --mirror-state=ro --type f $td"
7451         nfiles=$($cmd | wc -l)
7452         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7453
7454         cmd="$LFS find ! --mirror-state=ro --type f $td"
7455         nfiles=$($cmd | wc -l)
7456         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7457
7458         cmd="$LFS find --mirror-state=wp --type f $td"
7459         nfiles=$($cmd | wc -l)
7460         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7461
7462         cmd="$LFS find ! --mirror-state=sp --type f $td"
7463         nfiles=$($cmd | wc -l)
7464         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7465 }
7466 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7467
7468 test_57a() {
7469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7470         # note test will not do anything if MDS is not local
7471         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7472                 skip_env "ldiskfs only test"
7473         fi
7474         remote_mds_nodsh && skip "remote MDS with nodsh"
7475
7476         local MNTDEV="osd*.*MDT*.mntdev"
7477         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7478         [ -z "$DEV" ] && error "can't access $MNTDEV"
7479         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7480                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7481                         error "can't access $DEV"
7482                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7483                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7484                 rm $TMP/t57a.dump
7485         done
7486 }
7487 run_test 57a "verify MDS filesystem created with large inodes =="
7488
7489 test_57b() {
7490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7491         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7492                 skip_env "ldiskfs only test"
7493         fi
7494         remote_mds_nodsh && skip "remote MDS with nodsh"
7495
7496         local dir=$DIR/$tdir
7497         local filecount=100
7498         local file1=$dir/f1
7499         local fileN=$dir/f$filecount
7500
7501         rm -rf $dir || error "removing $dir"
7502         test_mkdir -c1 $dir
7503         local mdtidx=$($LFS getstripe -m $dir)
7504         local mdtname=MDT$(printf %04x $mdtidx)
7505         local facet=mds$((mdtidx + 1))
7506
7507         echo "mcreating $filecount files"
7508         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7509
7510         # verify that files do not have EAs yet
7511         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7512                 error "$file1 has an EA"
7513         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7514                 error "$fileN has an EA"
7515
7516         sync
7517         sleep 1
7518         df $dir  #make sure we get new statfs data
7519         local mdsfree=$(do_facet $facet \
7520                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7521         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7522         local file
7523
7524         echo "opening files to create objects/EAs"
7525         for file in $(seq -f $dir/f%g 1 $filecount); do
7526                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7527                         error "opening $file"
7528         done
7529
7530         # verify that files have EAs now
7531         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7532         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7533
7534         sleep 1  #make sure we get new statfs data
7535         df $dir
7536         local mdsfree2=$(do_facet $facet \
7537                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7538         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7539
7540         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7541                 if [ "$mdsfree" != "$mdsfree2" ]; then
7542                         error "MDC before $mdcfree != after $mdcfree2"
7543                 else
7544                         echo "MDC before $mdcfree != after $mdcfree2"
7545                         echo "unable to confirm if MDS has large inodes"
7546                 fi
7547         fi
7548         rm -rf $dir
7549 }
7550 run_test 57b "default LOV EAs are stored inside large inodes ==="
7551
7552 test_58() {
7553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7554         [ -z "$(which wiretest 2>/dev/null)" ] &&
7555                         skip_env "could not find wiretest"
7556
7557         wiretest
7558 }
7559 run_test 58 "verify cross-platform wire constants =============="
7560
7561 test_59() {
7562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7563
7564         echo "touch 130 files"
7565         createmany -o $DIR/f59- 130
7566         echo "rm 130 files"
7567         unlinkmany $DIR/f59- 130
7568         sync
7569         # wait for commitment of removal
7570         wait_delete_completed
7571 }
7572 run_test 59 "verify cancellation of llog records async ========="
7573
7574 TEST60_HEAD="test_60 run $RANDOM"
7575 test_60a() {
7576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7577         remote_mgs_nodsh && skip "remote MGS with nodsh"
7578         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7579                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7580                         skip_env "missing subtest run-llog.sh"
7581
7582         log "$TEST60_HEAD - from kernel mode"
7583         do_facet mgs "$LCTL dk > /dev/null"
7584         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7585         do_facet mgs $LCTL dk > $TMP/$tfile
7586
7587         # LU-6388: test llog_reader
7588         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7589         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7590         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7591                         skip_env "missing llog_reader"
7592         local fstype=$(facet_fstype mgs)
7593         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7594                 skip_env "Only for ldiskfs or zfs type mgs"
7595
7596         local mntpt=$(facet_mntpt mgs)
7597         local mgsdev=$(mgsdevname 1)
7598         local fid_list
7599         local fid
7600         local rec_list
7601         local rec
7602         local rec_type
7603         local obj_file
7604         local path
7605         local seq
7606         local oid
7607         local pass=true
7608
7609         #get fid and record list
7610         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7611                 tail -n 4))
7612         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7613                 tail -n 4))
7614         #remount mgs as ldiskfs or zfs type
7615         stop mgs || error "stop mgs failed"
7616         mount_fstype mgs || error "remount mgs failed"
7617         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7618                 fid=${fid_list[i]}
7619                 rec=${rec_list[i]}
7620                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7621                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7622                 oid=$((16#$oid))
7623
7624                 case $fstype in
7625                         ldiskfs )
7626                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7627                         zfs )
7628                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7629                 esac
7630                 echo "obj_file is $obj_file"
7631                 do_facet mgs $llog_reader $obj_file
7632
7633                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7634                         awk '{ print $3 }' | sed -e "s/^type=//g")
7635                 if [ $rec_type != $rec ]; then
7636                         echo "FAILED test_60a wrong record type $rec_type," \
7637                               "should be $rec"
7638                         pass=false
7639                         break
7640                 fi
7641
7642                 #check obj path if record type is LLOG_LOGID_MAGIC
7643                 if [ "$rec" == "1064553b" ]; then
7644                         path=$(do_facet mgs $llog_reader $obj_file |
7645                                 grep "path=" | awk '{ print $NF }' |
7646                                 sed -e "s/^path=//g")
7647                         if [ $obj_file != $mntpt/$path ]; then
7648                                 echo "FAILED test_60a wrong obj path" \
7649                                       "$montpt/$path, should be $obj_file"
7650                                 pass=false
7651                                 break
7652                         fi
7653                 fi
7654         done
7655         rm -f $TMP/$tfile
7656         #restart mgs before "error", otherwise it will block the next test
7657         stop mgs || error "stop mgs failed"
7658         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7659         $pass || error "test failed, see FAILED test_60a messages for specifics"
7660 }
7661 run_test 60a "llog_test run from kernel module and test llog_reader"
7662
7663 test_60b() { # bug 6411
7664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7665
7666         dmesg > $DIR/$tfile
7667         LLOG_COUNT=$(do_facet mgs dmesg |
7668                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7669                           /llog_[a-z]*.c:[0-9]/ {
7670                                 if (marker)
7671                                         from_marker++
7672                                 from_begin++
7673                           }
7674                           END {
7675                                 if (marker)
7676                                         print from_marker
7677                                 else
7678                                         print from_begin
7679                           }")
7680
7681         [[ $LLOG_COUNT -gt 120 ]] &&
7682                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7683 }
7684 run_test 60b "limit repeated messages from CERROR/CWARN"
7685
7686 test_60c() {
7687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7688
7689         echo "create 5000 files"
7690         createmany -o $DIR/f60c- 5000
7691 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7692         lctl set_param fail_loc=0x80000137
7693         unlinkmany $DIR/f60c- 5000
7694         lctl set_param fail_loc=0
7695 }
7696 run_test 60c "unlink file when mds full"
7697
7698 test_60d() {
7699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7700
7701         SAVEPRINTK=$(lctl get_param -n printk)
7702         # verify "lctl mark" is even working"
7703         MESSAGE="test message ID $RANDOM $$"
7704         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7705         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7706
7707         lctl set_param printk=0 || error "set lnet.printk failed"
7708         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7709         MESSAGE="new test message ID $RANDOM $$"
7710         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7711         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7712         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7713
7714         lctl set_param -n printk="$SAVEPRINTK"
7715 }
7716 run_test 60d "test printk console message masking"
7717
7718 test_60e() {
7719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7720         remote_mds_nodsh && skip "remote MDS with nodsh"
7721
7722         touch $DIR/$tfile
7723 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7724         do_facet mds1 lctl set_param fail_loc=0x15b
7725         rm $DIR/$tfile
7726 }
7727 run_test 60e "no space while new llog is being created"
7728
7729 test_60g() {
7730         local pid
7731         local i
7732
7733         test_mkdir -c $MDSCOUNT $DIR/$tdir
7734
7735         (
7736                 local index=0
7737                 while true; do
7738                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7739                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7740                                 2>/dev/null
7741                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7742                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7743                         index=$((index + 1))
7744                 done
7745         ) &
7746
7747         pid=$!
7748
7749         for i in {0..100}; do
7750                 # define OBD_FAIL_OSD_TXN_START    0x19a
7751                 local index=$((i % MDSCOUNT + 1))
7752
7753                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7754                         > /dev/null
7755                 sleep 0.01
7756         done
7757
7758         kill -9 $pid
7759
7760         for i in $(seq $MDSCOUNT); do
7761                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7762         done
7763
7764         mkdir $DIR/$tdir/new || error "mkdir failed"
7765         rmdir $DIR/$tdir/new || error "rmdir failed"
7766
7767         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7768                 -t namespace
7769         for i in $(seq $MDSCOUNT); do
7770                 wait_update_facet mds$i "$LCTL get_param -n \
7771                         mdd.$(facet_svc mds$i).lfsck_namespace |
7772                         awk '/^status/ { print \\\$2 }'" "completed"
7773         done
7774
7775         ls -R $DIR/$tdir || error "ls failed"
7776         rm -rf $DIR/$tdir || error "rmdir failed"
7777 }
7778 run_test 60g "transaction abort won't cause MDT hung"
7779
7780 test_60h() {
7781         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7782                 skip "Need MDS version at least 2.12.52"
7783         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7784
7785         local f
7786
7787         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7788         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7789         for fail_loc in 0x80000188 0x80000189; do
7790                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7791                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7792                         error "mkdir $dir-$fail_loc failed"
7793                 for i in {0..10}; do
7794                         # create may fail on missing stripe
7795                         echo $i > $DIR/$tdir-$fail_loc/$i
7796                 done
7797                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7798                         error "getdirstripe $tdir-$fail_loc failed"
7799                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7800                         error "migrate $tdir-$fail_loc failed"
7801                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7802                         error "getdirstripe $tdir-$fail_loc failed"
7803                 pushd $DIR/$tdir-$fail_loc
7804                 for f in *; do
7805                         echo $f | cmp $f - || error "$f data mismatch"
7806                 done
7807                 popd
7808                 rm -rf $DIR/$tdir-$fail_loc
7809         done
7810 }
7811 run_test 60h "striped directory with missing stripes can be accessed"
7812
7813 test_61a() {
7814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7815
7816         f="$DIR/f61"
7817         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7818         cancel_lru_locks osc
7819         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7820         sync
7821 }
7822 run_test 61a "mmap() writes don't make sync hang ================"
7823
7824 test_61b() {
7825         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7826 }
7827 run_test 61b "mmap() of unstriped file is successful"
7828
7829 # bug 2330 - insufficient obd_match error checking causes LBUG
7830 test_62() {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         f="$DIR/f62"
7834         echo foo > $f
7835         cancel_lru_locks osc
7836         lctl set_param fail_loc=0x405
7837         cat $f && error "cat succeeded, expect -EIO"
7838         lctl set_param fail_loc=0
7839 }
7840 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7841 # match every page all of the time.
7842 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7843
7844 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7845 # Though this test is irrelevant anymore, it helped to reveal some
7846 # other grant bugs (LU-4482), let's keep it.
7847 test_63a() {   # was test_63
7848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7849
7850         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7851
7852         for i in `seq 10` ; do
7853                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7854                 sleep 5
7855                 kill $!
7856                 sleep 1
7857         done
7858
7859         rm -f $DIR/f63 || true
7860 }
7861 run_test 63a "Verify oig_wait interruption does not crash ======="
7862
7863 # bug 2248 - async write errors didn't return to application on sync
7864 # bug 3677 - async write errors left page locked
7865 test_63b() {
7866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7867
7868         debugsave
7869         lctl set_param debug=-1
7870
7871         # ensure we have a grant to do async writes
7872         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7873         rm $DIR/$tfile
7874
7875         sync    # sync lest earlier test intercept the fail_loc
7876
7877         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7878         lctl set_param fail_loc=0x80000406
7879         $MULTIOP $DIR/$tfile Owy && \
7880                 error "sync didn't return ENOMEM"
7881         sync; sleep 2; sync     # do a real sync this time to flush page
7882         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7883                 error "locked page left in cache after async error" || true
7884         debugrestore
7885 }
7886 run_test 63b "async write errors should be returned to fsync ==="
7887
7888 test_64a () {
7889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7890
7891         lfs df $DIR
7892         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7893 }
7894 run_test 64a "verify filter grant calculations (in kernel) ====="
7895
7896 test_64b () {
7897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7898
7899         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7900 }
7901 run_test 64b "check out-of-space detection on client"
7902
7903 test_64c() {
7904         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7905 }
7906 run_test 64c "verify grant shrink"
7907
7908 import_param() {
7909         local tgt=$1
7910         local param=$2
7911
7912         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7913 }
7914
7915 # this does exactly what osc_request.c:osc_announce_cached() does in
7916 # order to calculate max amount of grants to ask from server
7917 want_grant() {
7918         local tgt=$1
7919
7920         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7921         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7922
7923         ((rpc_in_flight++));
7924         nrpages=$((nrpages * rpc_in_flight))
7925
7926         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7927
7928         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7929
7930         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7931         local undirty=$((nrpages * PAGE_SIZE))
7932
7933         local max_extent_pages
7934         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7935         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7936         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7937         local grant_extent_tax
7938         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7939
7940         undirty=$((undirty + nrextents * grant_extent_tax))
7941
7942         echo $undirty
7943 }
7944
7945 # this is size of unit for grant allocation. It should be equal to
7946 # what tgt_grant.c:tgt_grant_chunk() calculates
7947 grant_chunk() {
7948         local tgt=$1
7949         local max_brw_size
7950         local grant_extent_tax
7951
7952         max_brw_size=$(import_param $tgt max_brw_size)
7953
7954         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7955
7956         echo $(((max_brw_size + grant_extent_tax) * 2))
7957 }
7958
7959 test_64d() {
7960         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7961                 skip "OST < 2.10.55 doesn't limit grants enough"
7962
7963         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7964
7965         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7966                 skip "no grant_param connect flag"
7967
7968         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7969
7970         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7971         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7972
7973
7974         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7975         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7976
7977         $LFS setstripe $DIR/$tfile -i 0 -c 1
7978         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7979         ddpid=$!
7980
7981         while kill -0 $ddpid; do
7982                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7983
7984                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7985                         kill $ddpid
7986                         error "cur_grant $cur_grant > $max_cur_granted"
7987                 fi
7988
7989                 sleep 1
7990         done
7991 }
7992 run_test 64d "check grant limit exceed"
7993
7994 check_grants() {
7995         local tgt=$1
7996         local expected=$2
7997         local msg=$3
7998         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7999
8000         ((cur_grants == expected)) ||
8001                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8002 }
8003
8004 round_up_p2() {
8005         echo $((($1 + $2 - 1) & ~($2 - 1)))
8006 }
8007
8008 test_64e() {
8009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8010         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8011                 skip "Need OSS version at least 2.11.56"
8012
8013         # Remount client to reset grant
8014         remount_client $MOUNT || error "failed to remount client"
8015         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8016
8017         local init_grants=$(import_param $osc_tgt initial_grant)
8018
8019         check_grants $osc_tgt $init_grants "init grants"
8020
8021         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8022         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8023         local gbs=$(import_param $osc_tgt grant_block_size)
8024
8025         # write random number of bytes from max_brw_size / 4 to max_brw_size
8026         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8027         # align for direct io
8028         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8029         # round to grant consumption unit
8030         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8031
8032         local grants=$((wb_round_up + extent_tax))
8033
8034         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8035
8036         # define OBD_FAIL_TGT_NO_GRANT 0x725
8037         # make the server not grant more back
8038         do_facet ost1 $LCTL set_param fail_loc=0x725
8039         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8040
8041         do_facet ost1 $LCTL set_param fail_loc=0
8042
8043         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8044
8045         rm -f $DIR/$tfile || error "rm failed"
8046
8047         # Remount client to reset grant
8048         remount_client $MOUNT || error "failed to remount client"
8049         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8050
8051         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8052
8053         # define OBD_FAIL_TGT_NO_GRANT 0x725
8054         # make the server not grant more back
8055         do_facet ost1 $LCTL set_param fail_loc=0x725
8056         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8057         do_facet ost1 $LCTL set_param fail_loc=0
8058
8059         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8060 }
8061 run_test 64e "check grant consumption (no grant allocation)"
8062
8063 test_64f() {
8064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8065
8066         # Remount client to reset grant
8067         remount_client $MOUNT || error "failed to remount client"
8068         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8069
8070         local init_grants=$(import_param $osc_tgt initial_grant)
8071         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8072         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8073         local gbs=$(import_param $osc_tgt grant_block_size)
8074         local chunk=$(grant_chunk $osc_tgt)
8075
8076         # write random number of bytes from max_brw_size / 4 to max_brw_size
8077         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8078         # align for direct io
8079         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8080         # round to grant consumption unit
8081         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8082
8083         local grants=$((wb_round_up + extent_tax))
8084
8085         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8086         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8087                 error "error writing to $DIR/$tfile"
8088
8089         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8090                 "direct io with grant allocation"
8091
8092         rm -f $DIR/$tfile || error "rm failed"
8093
8094         # Remount client to reset grant
8095         remount_client $MOUNT || error "failed to remount client"
8096         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8097
8098         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8099
8100         local cmd="oO_WRONLY:w${write_bytes}_yc"
8101
8102         $MULTIOP $DIR/$tfile $cmd &
8103         MULTIPID=$!
8104         sleep 1
8105
8106         check_grants $osc_tgt $((init_grants - grants)) \
8107                 "buffered io, not write rpc"
8108
8109         kill -USR1 $MULTIPID
8110         wait
8111
8112         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8113                 "buffered io, one RPC"
8114 }
8115 run_test 64f "check grant consumption (with grant allocation)"
8116
8117 # bug 1414 - set/get directories' stripe info
8118 test_65a() {
8119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8120
8121         test_mkdir $DIR/$tdir
8122         touch $DIR/$tdir/f1
8123         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8124 }
8125 run_test 65a "directory with no stripe info"
8126
8127 test_65b() {
8128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8129
8130         test_mkdir $DIR/$tdir
8131         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8132
8133         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8134                                                 error "setstripe"
8135         touch $DIR/$tdir/f2
8136         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8137 }
8138 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8139
8140 test_65c() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8143
8144         test_mkdir $DIR/$tdir
8145         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8146
8147         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8148                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8149         touch $DIR/$tdir/f3
8150         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8151 }
8152 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8153
8154 test_65d() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/$tdir
8158         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8159         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8160
8161         if [[ $STRIPECOUNT -le 0 ]]; then
8162                 sc=1
8163         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8164                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8165                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8166         else
8167                 sc=$(($STRIPECOUNT - 1))
8168         fi
8169         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8170         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8171         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8172                 error "lverify failed"
8173 }
8174 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8175
8176 test_65e() {
8177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8178
8179         test_mkdir $DIR/$tdir
8180
8181         $LFS setstripe $DIR/$tdir || error "setstripe"
8182         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8183                                         error "no stripe info failed"
8184         touch $DIR/$tdir/f6
8185         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8186 }
8187 run_test 65e "directory setstripe defaults"
8188
8189 test_65f() {
8190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8191
8192         test_mkdir $DIR/${tdir}f
8193         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8194                 error "setstripe succeeded" || true
8195 }
8196 run_test 65f "dir setstripe permission (should return error) ==="
8197
8198 test_65g() {
8199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8200
8201         test_mkdir $DIR/$tdir
8202         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8203
8204         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8205                 error "setstripe -S failed"
8206         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8207         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8208                 error "delete default stripe failed"
8209 }
8210 run_test 65g "directory setstripe -d"
8211
8212 test_65h() {
8213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8214
8215         test_mkdir $DIR/$tdir
8216         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8217
8218         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8219                 error "setstripe -S failed"
8220         test_mkdir $DIR/$tdir/dd1
8221         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8222                 error "stripe info inherit failed"
8223 }
8224 run_test 65h "directory stripe info inherit ===================="
8225
8226 test_65i() {
8227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8228
8229         save_layout_restore_at_exit $MOUNT
8230
8231         # bug6367: set non-default striping on root directory
8232         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8233
8234         # bug12836: getstripe on -1 default directory striping
8235         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8236
8237         # bug12836: getstripe -v on -1 default directory striping
8238         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8239
8240         # bug12836: new find on -1 default directory striping
8241         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8242 }
8243 run_test 65i "various tests to set root directory striping"
8244
8245 test_65j() { # bug6367
8246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8247
8248         sync; sleep 1
8249
8250         # if we aren't already remounting for each test, do so for this test
8251         if [ "$I_MOUNTED" = "yes" ]; then
8252                 cleanup || error "failed to unmount"
8253                 setup
8254         fi
8255
8256         save_layout_restore_at_exit $MOUNT
8257
8258         $LFS setstripe -d $MOUNT || error "setstripe failed"
8259 }
8260 run_test 65j "set default striping on root directory (bug 6367)="
8261
8262 cleanup_65k() {
8263         rm -rf $DIR/$tdir
8264         wait_delete_completed
8265         do_facet $SINGLEMDS "lctl set_param -n \
8266                 osp.$ost*MDT0000.max_create_count=$max_count"
8267         do_facet $SINGLEMDS "lctl set_param -n \
8268                 osp.$ost*MDT0000.create_count=$count"
8269         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8270         echo $INACTIVE_OSC "is Activate"
8271
8272         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8273 }
8274
8275 test_65k() { # bug11679
8276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8277         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8278         remote_mds_nodsh && skip "remote MDS with nodsh"
8279
8280         local disable_precreate=true
8281         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8282                 disable_precreate=false
8283
8284         echo "Check OST status: "
8285         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8286                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8287
8288         for OSC in $MDS_OSCS; do
8289                 echo $OSC "is active"
8290                 do_facet $SINGLEMDS lctl --device %$OSC activate
8291         done
8292
8293         for INACTIVE_OSC in $MDS_OSCS; do
8294                 local ost=$(osc_to_ost $INACTIVE_OSC)
8295                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8296                                lov.*md*.target_obd |
8297                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8298
8299                 mkdir -p $DIR/$tdir
8300                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8301                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8302
8303                 echo "Deactivate: " $INACTIVE_OSC
8304                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8305
8306                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8307                               osp.$ost*MDT0000.create_count")
8308                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8309                                   osp.$ost*MDT0000.max_create_count")
8310                 $disable_precreate &&
8311                         do_facet $SINGLEMDS "lctl set_param -n \
8312                                 osp.$ost*MDT0000.max_create_count=0"
8313
8314                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8315                         [ -f $DIR/$tdir/$idx ] && continue
8316                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8317                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8318                                 { cleanup_65k;
8319                                   error "setstripe $idx should succeed"; }
8320                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8321                 done
8322                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8323                 rmdir $DIR/$tdir
8324
8325                 do_facet $SINGLEMDS "lctl set_param -n \
8326                         osp.$ost*MDT0000.max_create_count=$max_count"
8327                 do_facet $SINGLEMDS "lctl set_param -n \
8328                         osp.$ost*MDT0000.create_count=$count"
8329                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8330                 echo $INACTIVE_OSC "is Activate"
8331
8332                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8333         done
8334 }
8335 run_test 65k "validate manual striping works properly with deactivated OSCs"
8336
8337 test_65l() { # bug 12836
8338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8339
8340         test_mkdir -p $DIR/$tdir/test_dir
8341         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8342         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8343 }
8344 run_test 65l "lfs find on -1 stripe dir ========================"
8345
8346 test_65m() {
8347         local layout=$(save_layout $MOUNT)
8348         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8349                 restore_layout $MOUNT $layout
8350                 error "setstripe should fail by non-root users"
8351         }
8352         true
8353 }
8354 run_test 65m "normal user can't set filesystem default stripe"
8355
8356 test_65n() {
8357         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8358         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8359                 skip "Need MDS version at least 2.12.50"
8360         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8361
8362         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8363         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8364         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8365
8366         local root_layout=$(save_layout $MOUNT)
8367         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8368
8369         # new subdirectory under root directory should not inherit
8370         # the default layout from root
8371         local dir1=$MOUNT/$tdir-1
8372         mkdir $dir1 || error "mkdir $dir1 failed"
8373         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8374                 error "$dir1 shouldn't have LOV EA"
8375
8376         # delete the default layout on root directory
8377         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8378
8379         local dir2=$MOUNT/$tdir-2
8380         mkdir $dir2 || error "mkdir $dir2 failed"
8381         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8382                 error "$dir2 shouldn't have LOV EA"
8383
8384         # set a new striping pattern on root directory
8385         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8386         local new_def_stripe_size=$((def_stripe_size * 2))
8387         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8388                 error "set stripe size on $MOUNT failed"
8389
8390         # new file created in $dir2 should inherit the new stripe size from
8391         # the filesystem default
8392         local file2=$dir2/$tfile-2
8393         touch $file2 || error "touch $file2 failed"
8394
8395         local file2_stripe_size=$($LFS getstripe -S $file2)
8396         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8397                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8398
8399         local dir3=$MOUNT/$tdir-3
8400         mkdir $dir3 || error "mkdir $dir3 failed"
8401         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8402         # the root layout, which is the actual default layout that will be used
8403         # when new files are created in $dir3.
8404         local dir3_layout=$(get_layout_param $dir3)
8405         local root_dir_layout=$(get_layout_param $MOUNT)
8406         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8407                 error "$dir3 should show the default layout from $MOUNT"
8408
8409         # set OST pool on root directory
8410         local pool=$TESTNAME
8411         pool_add $pool || error "add $pool failed"
8412         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8413                 error "add targets to $pool failed"
8414
8415         $LFS setstripe -p $pool $MOUNT ||
8416                 error "set OST pool on $MOUNT failed"
8417
8418         # new file created in $dir3 should inherit the pool from
8419         # the filesystem default
8420         local file3=$dir3/$tfile-3
8421         touch $file3 || error "touch $file3 failed"
8422
8423         local file3_pool=$($LFS getstripe -p $file3)
8424         [[ "$file3_pool" = "$pool" ]] ||
8425                 error "$file3 didn't inherit OST pool $pool"
8426
8427         local dir4=$MOUNT/$tdir-4
8428         mkdir $dir4 || error "mkdir $dir4 failed"
8429         local dir4_layout=$(get_layout_param $dir4)
8430         root_dir_layout=$(get_layout_param $MOUNT)
8431         echo "$LFS getstripe -d $dir4"
8432         $LFS getstripe -d $dir4
8433         echo "$LFS getstripe -d $MOUNT"
8434         $LFS getstripe -d $MOUNT
8435         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8436                 error "$dir4 should show the default layout from $MOUNT"
8437
8438         # new file created in $dir4 should inherit the pool from
8439         # the filesystem default
8440         local file4=$dir4/$tfile-4
8441         touch $file4 || error "touch $file4 failed"
8442
8443         local file4_pool=$($LFS getstripe -p $file4)
8444         [[ "$file4_pool" = "$pool" ]] ||
8445                 error "$file4 didn't inherit OST pool $pool"
8446
8447         # new subdirectory under non-root directory should inherit
8448         # the default layout from its parent directory
8449         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8450                 error "set directory layout on $dir4 failed"
8451
8452         local dir5=$dir4/$tdir-5
8453         mkdir $dir5 || error "mkdir $dir5 failed"
8454
8455         dir4_layout=$(get_layout_param $dir4)
8456         local dir5_layout=$(get_layout_param $dir5)
8457         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8458                 error "$dir5 should inherit the default layout from $dir4"
8459
8460         # though subdir under ROOT doesn't inherit default layout, but
8461         # its sub dir/file should be created with default layout.
8462         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8463         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8464                 skip "Need MDS version at least 2.12.59"
8465
8466         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8467         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8468         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8469
8470         if [ $default_lmv_hash == "none" ]; then
8471                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8472         else
8473                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8474                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8475         fi
8476
8477         $LFS setdirstripe -D -c 2 $MOUNT ||
8478                 error "setdirstripe -D -c 2 failed"
8479         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8480         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8481         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8482 }
8483 run_test 65n "don't inherit default layout from root for new subdirectories"
8484
8485 # bug 2543 - update blocks count on client
8486 test_66() {
8487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8488
8489         COUNT=${COUNT:-8}
8490         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8491         sync; sync_all_data; sync; sync_all_data
8492         cancel_lru_locks osc
8493         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8494         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8495 }
8496 run_test 66 "update inode blocks count on client ==============="
8497
8498 meminfo() {
8499         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8500 }
8501
8502 swap_used() {
8503         swapon -s | awk '($1 == "'$1'") { print $4 }'
8504 }
8505
8506 # bug5265, obdfilter oa2dentry return -ENOENT
8507 # #define OBD_FAIL_SRV_ENOENT 0x217
8508 test_69() {
8509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8510         remote_ost_nodsh && skip "remote OST with nodsh"
8511
8512         f="$DIR/$tfile"
8513         $LFS setstripe -c 1 -i 0 $f
8514
8515         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8516
8517         do_facet ost1 lctl set_param fail_loc=0x217
8518         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8519         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8520
8521         do_facet ost1 lctl set_param fail_loc=0
8522         $DIRECTIO write $f 0 2 || error "write error"
8523
8524         cancel_lru_locks osc
8525         $DIRECTIO read $f 0 1 || error "read error"
8526
8527         do_facet ost1 lctl set_param fail_loc=0x217
8528         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8529
8530         do_facet ost1 lctl set_param fail_loc=0
8531         rm -f $f
8532 }
8533 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8534
8535 test_71() {
8536         test_mkdir $DIR/$tdir
8537         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8538         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8539 }
8540 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8541
8542 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8544         [ "$RUNAS_ID" = "$UID" ] &&
8545                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8546         # Check that testing environment is properly set up. Skip if not
8547         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8548                 skip_env "User $RUNAS_ID does not exist - skipping"
8549
8550         touch $DIR/$tfile
8551         chmod 777 $DIR/$tfile
8552         chmod ug+s $DIR/$tfile
8553         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8554                 error "$RUNAS dd $DIR/$tfile failed"
8555         # See if we are still setuid/sgid
8556         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8557                 error "S/gid is not dropped on write"
8558         # Now test that MDS is updated too
8559         cancel_lru_locks mdc
8560         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8561                 error "S/gid is not dropped on MDS"
8562         rm -f $DIR/$tfile
8563 }
8564 run_test 72a "Test that remove suid works properly (bug5695) ===="
8565
8566 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8567         local perm
8568
8569         [ "$RUNAS_ID" = "$UID" ] &&
8570                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8571         [ "$RUNAS_ID" -eq 0 ] &&
8572                 skip_env "RUNAS_ID = 0 -- skipping"
8573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8574         # Check that testing environment is properly set up. Skip if not
8575         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8576                 skip_env "User $RUNAS_ID does not exist - skipping"
8577
8578         touch $DIR/${tfile}-f{g,u}
8579         test_mkdir $DIR/${tfile}-dg
8580         test_mkdir $DIR/${tfile}-du
8581         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8582         chmod g+s $DIR/${tfile}-{f,d}g
8583         chmod u+s $DIR/${tfile}-{f,d}u
8584         for perm in 777 2777 4777; do
8585                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8586                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8587                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8588                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8589         done
8590         true
8591 }
8592 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8593
8594 # bug 3462 - multiple simultaneous MDC requests
8595 test_73() {
8596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8597
8598         test_mkdir $DIR/d73-1
8599         test_mkdir $DIR/d73-2
8600         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8601         pid1=$!
8602
8603         lctl set_param fail_loc=0x80000129
8604         $MULTIOP $DIR/d73-1/f73-2 Oc &
8605         sleep 1
8606         lctl set_param fail_loc=0
8607
8608         $MULTIOP $DIR/d73-2/f73-3 Oc &
8609         pid3=$!
8610
8611         kill -USR1 $pid1
8612         wait $pid1 || return 1
8613
8614         sleep 25
8615
8616         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8617         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8618         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8619
8620         rm -rf $DIR/d73-*
8621 }
8622 run_test 73 "multiple MDC requests (should not deadlock)"
8623
8624 test_74a() { # bug 6149, 6184
8625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8626
8627         touch $DIR/f74a
8628         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8629         #
8630         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8631         # will spin in a tight reconnection loop
8632         $LCTL set_param fail_loc=0x8000030e
8633         # get any lock that won't be difficult - lookup works.
8634         ls $DIR/f74a
8635         $LCTL set_param fail_loc=0
8636         rm -f $DIR/f74a
8637         true
8638 }
8639 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8640
8641 test_74b() { # bug 13310
8642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8643
8644         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8645         #
8646         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8647         # will spin in a tight reconnection loop
8648         $LCTL set_param fail_loc=0x8000030e
8649         # get a "difficult" lock
8650         touch $DIR/f74b
8651         $LCTL set_param fail_loc=0
8652         rm -f $DIR/f74b
8653         true
8654 }
8655 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8656
8657 test_74c() {
8658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8659
8660         #define OBD_FAIL_LDLM_NEW_LOCK
8661         $LCTL set_param fail_loc=0x319
8662         touch $DIR/$tfile && error "touch successful"
8663         $LCTL set_param fail_loc=0
8664         true
8665 }
8666 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8667
8668 slab_lic=/sys/kernel/slab/lustre_inode_cache
8669 num_objects() {
8670         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8671         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8672                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8673 }
8674
8675 test_76a() { # Now for b=20433, added originally in b=1443
8676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8677
8678         cancel_lru_locks osc
8679         # there may be some slab objects cached per core
8680         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8681         local before=$(num_objects)
8682         local count=$((512 * cpus))
8683         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8684         local margin=$((count / 10))
8685         if [[ -f $slab_lic/aliases ]]; then
8686                 local aliases=$(cat $slab_lic/aliases)
8687                 (( aliases > 0 )) && margin=$((margin * aliases))
8688         fi
8689
8690         echo "before slab objects: $before"
8691         for i in $(seq $count); do
8692                 touch $DIR/$tfile
8693                 rm -f $DIR/$tfile
8694         done
8695         cancel_lru_locks osc
8696         local after=$(num_objects)
8697         echo "created: $count, after slab objects: $after"
8698         # shared slab counts are not very accurate, allow significant margin
8699         # the main goal is that the cache growth is not permanently > $count
8700         while (( after > before + margin )); do
8701                 sleep 1
8702                 after=$(num_objects)
8703                 wait=$((wait + 1))
8704                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8705                 if (( wait > 60 )); then
8706                         error "inode slab grew from $before+$margin to $after"
8707                 fi
8708         done
8709 }
8710 run_test 76a "confirm clients recycle inodes properly ===="
8711
8712 test_76b() {
8713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8714         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8715
8716         local count=512
8717         local before=$(num_objects)
8718
8719         for i in $(seq $count); do
8720                 mkdir $DIR/$tdir
8721                 rmdir $DIR/$tdir
8722         done
8723
8724         local after=$(num_objects)
8725         local wait=0
8726
8727         while (( after > before )); do
8728                 sleep 1
8729                 after=$(num_objects)
8730                 wait=$((wait + 1))
8731                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8732                 if (( wait > 60 )); then
8733                         error "inode slab grew from $before to $after"
8734                 fi
8735         done
8736
8737         echo "slab objects before: $before, after: $after"
8738 }
8739 run_test 76b "confirm clients recycle directory inodes properly ===="
8740
8741 export ORIG_CSUM=""
8742 set_checksums()
8743 {
8744         # Note: in sptlrpc modes which enable its own bulk checksum, the
8745         # original crc32_le bulk checksum will be automatically disabled,
8746         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8747         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8748         # In this case set_checksums() will not be no-op, because sptlrpc
8749         # bulk checksum will be enabled all through the test.
8750
8751         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8752         lctl set_param -n osc.*.checksums $1
8753         return 0
8754 }
8755
8756 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8757                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8758 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8759                              tr -d [] | head -n1)}
8760 set_checksum_type()
8761 {
8762         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8763         rc=$?
8764         log "set checksum type to $1, rc = $rc"
8765         return $rc
8766 }
8767
8768 get_osc_checksum_type()
8769 {
8770         # arugment 1: OST name, like OST0000
8771         ost=$1
8772         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8773                         sed 's/.*\[\(.*\)\].*/\1/g')
8774         rc=$?
8775         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8776         echo $checksum_type
8777 }
8778
8779 F77_TMP=$TMP/f77-temp
8780 F77SZ=8
8781 setup_f77() {
8782         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8783                 error "error writing to $F77_TMP"
8784 }
8785
8786 test_77a() { # bug 10889
8787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8788         $GSS && skip_env "could not run with gss"
8789
8790         [ ! -f $F77_TMP ] && setup_f77
8791         set_checksums 1
8792         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8793         set_checksums 0
8794         rm -f $DIR/$tfile
8795 }
8796 run_test 77a "normal checksum read/write operation"
8797
8798 test_77b() { # bug 10889
8799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8800         $GSS && skip_env "could not run with gss"
8801
8802         [ ! -f $F77_TMP ] && setup_f77
8803         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8804         $LCTL set_param fail_loc=0x80000409
8805         set_checksums 1
8806
8807         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8808                 error "dd error: $?"
8809         $LCTL set_param fail_loc=0
8810
8811         for algo in $CKSUM_TYPES; do
8812                 cancel_lru_locks osc
8813                 set_checksum_type $algo
8814                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8815                 $LCTL set_param fail_loc=0x80000408
8816                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8817                 $LCTL set_param fail_loc=0
8818         done
8819         set_checksums 0
8820         set_checksum_type $ORIG_CSUM_TYPE
8821         rm -f $DIR/$tfile
8822 }
8823 run_test 77b "checksum error on client write, read"
8824
8825 cleanup_77c() {
8826         trap 0
8827         set_checksums 0
8828         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8829         $check_ost &&
8830                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8831         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8832         $check_ost && [ -n "$ost_file_prefix" ] &&
8833                 do_facet ost1 rm -f ${ost_file_prefix}\*
8834 }
8835
8836 test_77c() {
8837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8838         $GSS && skip_env "could not run with gss"
8839         remote_ost_nodsh && skip "remote OST with nodsh"
8840
8841         local bad1
8842         local osc_file_prefix
8843         local osc_file
8844         local check_ost=false
8845         local ost_file_prefix
8846         local ost_file
8847         local orig_cksum
8848         local dump_cksum
8849         local fid
8850
8851         # ensure corruption will occur on first OSS/OST
8852         $LFS setstripe -i 0 $DIR/$tfile
8853
8854         [ ! -f $F77_TMP ] && setup_f77
8855         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8856                 error "dd write error: $?"
8857         fid=$($LFS path2fid $DIR/$tfile)
8858
8859         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8860         then
8861                 check_ost=true
8862                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8863                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8864         else
8865                 echo "OSS do not support bulk pages dump upon error"
8866         fi
8867
8868         osc_file_prefix=$($LCTL get_param -n debug_path)
8869         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8870
8871         trap cleanup_77c EXIT
8872
8873         set_checksums 1
8874         # enable bulk pages dump upon error on Client
8875         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8876         # enable bulk pages dump upon error on OSS
8877         $check_ost &&
8878                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8879
8880         # flush Client cache to allow next read to reach OSS
8881         cancel_lru_locks osc
8882
8883         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8884         $LCTL set_param fail_loc=0x80000408
8885         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8886         $LCTL set_param fail_loc=0
8887
8888         rm -f $DIR/$tfile
8889
8890         # check cksum dump on Client
8891         osc_file=$(ls ${osc_file_prefix}*)
8892         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8893         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8894         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8895         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8896         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8897                      cksum)
8898         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8899         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8900                 error "dump content does not match on Client"
8901
8902         $check_ost || skip "No need to check cksum dump on OSS"
8903
8904         # check cksum dump on OSS
8905         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8906         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8907         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8908         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8909         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8910                 error "dump content does not match on OSS"
8911
8912         cleanup_77c
8913 }
8914 run_test 77c "checksum error on client read with debug"
8915
8916 test_77d() { # bug 10889
8917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8918         $GSS && skip_env "could not run with gss"
8919
8920         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8921         $LCTL set_param fail_loc=0x80000409
8922         set_checksums 1
8923         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8924                 error "direct write: rc=$?"
8925         $LCTL set_param fail_loc=0
8926         set_checksums 0
8927
8928         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8929         $LCTL set_param fail_loc=0x80000408
8930         set_checksums 1
8931         cancel_lru_locks osc
8932         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8933                 error "direct read: rc=$?"
8934         $LCTL set_param fail_loc=0
8935         set_checksums 0
8936 }
8937 run_test 77d "checksum error on OST direct write, read"
8938
8939 test_77f() { # bug 10889
8940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8941         $GSS && skip_env "could not run with gss"
8942
8943         set_checksums 1
8944         for algo in $CKSUM_TYPES; do
8945                 cancel_lru_locks osc
8946                 set_checksum_type $algo
8947                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8948                 $LCTL set_param fail_loc=0x409
8949                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8950                         error "direct write succeeded"
8951                 $LCTL set_param fail_loc=0
8952         done
8953         set_checksum_type $ORIG_CSUM_TYPE
8954         set_checksums 0
8955 }
8956 run_test 77f "repeat checksum error on write (expect error)"
8957
8958 test_77g() { # bug 10889
8959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8960         $GSS && skip_env "could not run with gss"
8961         remote_ost_nodsh && skip "remote OST with nodsh"
8962
8963         [ ! -f $F77_TMP ] && setup_f77
8964
8965         local file=$DIR/$tfile
8966         stack_trap "rm -f $file" EXIT
8967
8968         $LFS setstripe -c 1 -i 0 $file
8969         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8970         do_facet ost1 lctl set_param fail_loc=0x8000021a
8971         set_checksums 1
8972         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8973                 error "write error: rc=$?"
8974         do_facet ost1 lctl set_param fail_loc=0
8975         set_checksums 0
8976
8977         cancel_lru_locks osc
8978         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8979         do_facet ost1 lctl set_param fail_loc=0x8000021b
8980         set_checksums 1
8981         cmp $F77_TMP $file || error "file compare failed"
8982         do_facet ost1 lctl set_param fail_loc=0
8983         set_checksums 0
8984 }
8985 run_test 77g "checksum error on OST write, read"
8986
8987 test_77k() { # LU-10906
8988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8989         $GSS && skip_env "could not run with gss"
8990
8991         local cksum_param="osc.$FSNAME*.checksums"
8992         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8993         local checksum
8994         local i
8995
8996         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8997         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8998         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8999
9000         for i in 0 1; do
9001                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9002                         error "failed to set checksum=$i on MGS"
9003                 wait_update $HOSTNAME "$get_checksum" $i
9004                 #remount
9005                 echo "remount client, checksum should be $i"
9006                 remount_client $MOUNT || error "failed to remount client"
9007                 checksum=$(eval $get_checksum)
9008                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9009         done
9010         # remove persistent param to avoid races with checksum mountopt below
9011         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9012                 error "failed to delete checksum on MGS"
9013
9014         for opt in "checksum" "nochecksum"; do
9015                 #remount with mount option
9016                 echo "remount client with option $opt, checksum should be $i"
9017                 umount_client $MOUNT || error "failed to umount client"
9018                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9019                         error "failed to mount client with option '$opt'"
9020                 checksum=$(eval $get_checksum)
9021                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9022                 i=$((i - 1))
9023         done
9024
9025         remount_client $MOUNT || error "failed to remount client"
9026 }
9027 run_test 77k "enable/disable checksum correctly"
9028
9029 test_77l() {
9030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9031         $GSS && skip_env "could not run with gss"
9032
9033         set_checksums 1
9034         stack_trap "set_checksums $ORIG_CSUM" EXIT
9035         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9036
9037         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9038
9039         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9040         for algo in $CKSUM_TYPES; do
9041                 set_checksum_type $algo || error "fail to set checksum type $algo"
9042                 osc_algo=$(get_osc_checksum_type OST0000)
9043                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9044
9045                 # no locks, no reqs to let the connection idle
9046                 cancel_lru_locks osc
9047                 lru_resize_disable osc
9048                 wait_osc_import_state client ost1 IDLE
9049
9050                 # ensure ost1 is connected
9051                 stat $DIR/$tfile >/dev/null || error "can't stat"
9052                 wait_osc_import_state client ost1 FULL
9053
9054                 osc_algo=$(get_osc_checksum_type OST0000)
9055                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9056         done
9057         return 0
9058 }
9059 run_test 77l "preferred checksum type is remembered after reconnected"
9060
9061 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9062 rm -f $F77_TMP
9063 unset F77_TMP
9064
9065 cleanup_test_78() {
9066         trap 0
9067         rm -f $DIR/$tfile
9068 }
9069
9070 test_78() { # bug 10901
9071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9072         remote_ost || skip_env "local OST"
9073
9074         NSEQ=5
9075         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9076         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9077         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9078         echo "MemTotal: $MEMTOTAL"
9079
9080         # reserve 256MB of memory for the kernel and other running processes,
9081         # and then take 1/2 of the remaining memory for the read/write buffers.
9082         if [ $MEMTOTAL -gt 512 ] ;then
9083                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9084         else
9085                 # for those poor memory-starved high-end clusters...
9086                 MEMTOTAL=$((MEMTOTAL / 2))
9087         fi
9088         echo "Mem to use for directio: $MEMTOTAL"
9089
9090         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9091         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9092         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9093         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9094                 head -n1)
9095         echo "Smallest OST: $SMALLESTOST"
9096         [[ $SMALLESTOST -lt 10240 ]] &&
9097                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9098
9099         trap cleanup_test_78 EXIT
9100
9101         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9102                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9103
9104         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9105         echo "File size: $F78SIZE"
9106         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9107         for i in $(seq 1 $NSEQ); do
9108                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9109                 echo directIO rdwr round $i of $NSEQ
9110                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9111         done
9112
9113         cleanup_test_78
9114 }
9115 run_test 78 "handle large O_DIRECT writes correctly ============"
9116
9117 test_79() { # bug 12743
9118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9119
9120         wait_delete_completed
9121
9122         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9123         BKFREE=$(calc_osc_kbytes kbytesfree)
9124         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9125
9126         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9127         DFTOTAL=`echo $STRING | cut -d, -f1`
9128         DFUSED=`echo $STRING  | cut -d, -f2`
9129         DFAVAIL=`echo $STRING | cut -d, -f3`
9130         DFFREE=$(($DFTOTAL - $DFUSED))
9131
9132         ALLOWANCE=$((64 * $OSTCOUNT))
9133
9134         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9135            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9136                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9137         fi
9138         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9139            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9140                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9141         fi
9142         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9143            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9144                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9145         fi
9146 }
9147 run_test 79 "df report consistency check ======================="
9148
9149 test_80() { # bug 10718
9150         remote_ost_nodsh && skip "remote OST with nodsh"
9151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9152
9153         # relax strong synchronous semantics for slow backends like ZFS
9154         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9155                 local soc="obdfilter.*.sync_lock_cancel"
9156                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9157
9158                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9159                 if [ -z "$save" ]; then
9160                         soc="obdfilter.*.sync_on_lock_cancel"
9161                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9162                 fi
9163
9164                 if [ "$save" != "never" ]; then
9165                         local hosts=$(comma_list $(osts_nodes))
9166
9167                         do_nodes $hosts $LCTL set_param $soc=never
9168                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9169                 fi
9170         fi
9171
9172         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9173         sync; sleep 1; sync
9174         local before=$(date +%s)
9175         cancel_lru_locks osc
9176         local after=$(date +%s)
9177         local diff=$((after - before))
9178         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9179
9180         rm -f $DIR/$tfile
9181 }
9182 run_test 80 "Page eviction is equally fast at high offsets too"
9183
9184 test_81a() { # LU-456
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186         remote_ost_nodsh && skip "remote OST with nodsh"
9187
9188         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9189         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9190         do_facet ost1 lctl set_param fail_loc=0x80000228
9191
9192         # write should trigger a retry and success
9193         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9194         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9195         RC=$?
9196         if [ $RC -ne 0 ] ; then
9197                 error "write should success, but failed for $RC"
9198         fi
9199 }
9200 run_test 81a "OST should retry write when get -ENOSPC ==============="
9201
9202 test_81b() { # LU-456
9203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9204         remote_ost_nodsh && skip "remote OST with nodsh"
9205
9206         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9207         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9208         do_facet ost1 lctl set_param fail_loc=0x228
9209
9210         # write should retry several times and return -ENOSPC finally
9211         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9212         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9213         RC=$?
9214         ENOSPC=28
9215         if [ $RC -ne $ENOSPC ] ; then
9216                 error "dd should fail for -ENOSPC, but succeed."
9217         fi
9218 }
9219 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9220
9221 test_99() {
9222         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9223
9224         test_mkdir $DIR/$tdir.cvsroot
9225         chown $RUNAS_ID $DIR/$tdir.cvsroot
9226
9227         cd $TMP
9228         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9229
9230         cd /etc/init.d
9231         # some versions of cvs import exit(1) when asked to import links or
9232         # files they can't read.  ignore those files.
9233         local toignore=$(find . -type l -printf '-I %f\n' -o \
9234                          ! -perm /4 -printf '-I %f\n')
9235         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9236                 $tdir.reposname vtag rtag
9237
9238         cd $DIR
9239         test_mkdir $DIR/$tdir.reposname
9240         chown $RUNAS_ID $DIR/$tdir.reposname
9241         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9242
9243         cd $DIR/$tdir.reposname
9244         $RUNAS touch foo99
9245         $RUNAS cvs add -m 'addmsg' foo99
9246         $RUNAS cvs update
9247         $RUNAS cvs commit -m 'nomsg' foo99
9248         rm -fr $DIR/$tdir.cvsroot
9249 }
9250 run_test 99 "cvs strange file/directory operations"
9251
9252 test_100() {
9253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9254         [[ "$NETTYPE" =~ tcp ]] ||
9255                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9256         remote_ost_nodsh && skip "remote OST with nodsh"
9257         remote_mds_nodsh && skip "remote MDS with nodsh"
9258         remote_servers ||
9259                 skip "useless for local single node setup"
9260
9261         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9262                 [ "$PROT" != "tcp" ] && continue
9263                 RPORT=$(echo $REMOTE | cut -d: -f2)
9264                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9265
9266                 rc=0
9267                 LPORT=`echo $LOCAL | cut -d: -f2`
9268                 if [ $LPORT -ge 1024 ]; then
9269                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9270                         netstat -tna
9271                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9272                 fi
9273         done
9274         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9275 }
9276 run_test 100 "check local port using privileged port ==========="
9277
9278 function get_named_value()
9279 {
9280     local tag
9281
9282     tag=$1
9283     while read ;do
9284         line=$REPLY
9285         case $line in
9286         $tag*)
9287             echo $line | sed "s/^$tag[ ]*//"
9288             break
9289             ;;
9290         esac
9291     done
9292 }
9293
9294 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9295                    awk '/^max_cached_mb/ { print $2 }')
9296
9297 cleanup_101a() {
9298         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9299         trap 0
9300 }
9301
9302 test_101a() {
9303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9304
9305         local s
9306         local discard
9307         local nreads=10000
9308         local cache_limit=32
9309
9310         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9311         trap cleanup_101a EXIT
9312         $LCTL set_param -n llite.*.read_ahead_stats 0
9313         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9314
9315         #
9316         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9317         #
9318         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9319         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9320
9321         discard=0
9322         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9323                 get_named_value 'read but discarded' | cut -d" " -f1); do
9324                         discard=$(($discard + $s))
9325         done
9326         cleanup_101a
9327
9328         $LCTL get_param osc.*-osc*.rpc_stats
9329         $LCTL get_param llite.*.read_ahead_stats
9330
9331         # Discard is generally zero, but sometimes a few random reads line up
9332         # and trigger larger readahead, which is wasted & leads to discards.
9333         if [[ $(($discard)) -gt $nreads ]]; then
9334                 error "too many ($discard) discarded pages"
9335         fi
9336         rm -f $DIR/$tfile || true
9337 }
9338 run_test 101a "check read-ahead for random reads"
9339
9340 setup_test101bc() {
9341         test_mkdir $DIR/$tdir
9342         local ssize=$1
9343         local FILE_LENGTH=$2
9344         STRIPE_OFFSET=0
9345
9346         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9347
9348         local list=$(comma_list $(osts_nodes))
9349         set_osd_param $list '' read_cache_enable 0
9350         set_osd_param $list '' writethrough_cache_enable 0
9351
9352         trap cleanup_test101bc EXIT
9353         # prepare the read-ahead file
9354         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9355
9356         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9357                                 count=$FILE_SIZE_MB 2> /dev/null
9358
9359 }
9360
9361 cleanup_test101bc() {
9362         trap 0
9363         rm -rf $DIR/$tdir
9364         rm -f $DIR/$tfile
9365
9366         local list=$(comma_list $(osts_nodes))
9367         set_osd_param $list '' read_cache_enable 1
9368         set_osd_param $list '' writethrough_cache_enable 1
9369 }
9370
9371 calc_total() {
9372         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9373 }
9374
9375 ra_check_101() {
9376         local READ_SIZE=$1
9377         local STRIPE_SIZE=$2
9378         local FILE_LENGTH=$3
9379         local RA_INC=1048576
9380         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9381         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9382                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9383         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9384                         get_named_value 'read but discarded' |
9385                         cut -d" " -f1 | calc_total)
9386         if [[ $DISCARD -gt $discard_limit ]]; then
9387                 $LCTL get_param llite.*.read_ahead_stats
9388                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9389         else
9390                 echo "Read-ahead success for size ${READ_SIZE}"
9391         fi
9392 }
9393
9394 test_101b() {
9395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9396         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9397
9398         local STRIPE_SIZE=1048576
9399         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9400
9401         if [ $SLOW == "yes" ]; then
9402                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9403         else
9404                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9405         fi
9406
9407         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9408
9409         # prepare the read-ahead file
9410         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9411         cancel_lru_locks osc
9412         for BIDX in 2 4 8 16 32 64 128 256
9413         do
9414                 local BSIZE=$((BIDX*4096))
9415                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9416                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9417                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9418                 $LCTL set_param -n llite.*.read_ahead_stats 0
9419                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9420                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9421                 cancel_lru_locks osc
9422                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9423         done
9424         cleanup_test101bc
9425         true
9426 }
9427 run_test 101b "check stride-io mode read-ahead ================="
9428
9429 test_101c() {
9430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9431
9432         local STRIPE_SIZE=1048576
9433         local FILE_LENGTH=$((STRIPE_SIZE*100))
9434         local nreads=10000
9435         local rsize=65536
9436         local osc_rpc_stats
9437
9438         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9439
9440         cancel_lru_locks osc
9441         $LCTL set_param osc.*.rpc_stats 0
9442         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9443         $LCTL get_param osc.*.rpc_stats
9444         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9445                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9446                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9447                 local size
9448
9449                 if [ $lines -le 20 ]; then
9450                         echo "continue debug"
9451                         continue
9452                 fi
9453                 for size in 1 2 4 8; do
9454                         local rpc=$(echo "$stats" |
9455                                     awk '($1 == "'$size':") {print $2; exit; }')
9456                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9457                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9458                 done
9459                 echo "$osc_rpc_stats check passed!"
9460         done
9461         cleanup_test101bc
9462         true
9463 }
9464 run_test 101c "check stripe_size aligned read-ahead ================="
9465
9466 test_101d() {
9467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9468
9469         local file=$DIR/$tfile
9470         local sz_MB=${FILESIZE_101d:-80}
9471         local ra_MB=${READAHEAD_MB:-40}
9472
9473         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9474         [ $free_MB -lt $sz_MB ] &&
9475                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9476
9477         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9478         $LFS setstripe -c -1 $file || error "setstripe failed"
9479
9480         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9481         echo Cancel LRU locks on lustre client to flush the client cache
9482         cancel_lru_locks osc
9483
9484         echo Disable read-ahead
9485         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9486         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9487         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9488         $LCTL get_param -n llite.*.max_read_ahead_mb
9489
9490         echo "Reading the test file $file with read-ahead disabled"
9491         local sz_KB=$((sz_MB * 1024 / 4))
9492         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9493         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9494         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9495                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9496
9497         echo "Cancel LRU locks on lustre client to flush the client cache"
9498         cancel_lru_locks osc
9499         echo Enable read-ahead with ${ra_MB}MB
9500         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9501
9502         echo "Reading the test file $file with read-ahead enabled"
9503         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9504                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9505
9506         echo "read-ahead disabled time read $raOFF"
9507         echo "read-ahead enabled time read $raON"
9508
9509         rm -f $file
9510         wait_delete_completed
9511
9512         # use awk for this check instead of bash because it handles decimals
9513         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9514                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9515 }
9516 run_test 101d "file read with and without read-ahead enabled"
9517
9518 test_101e() {
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520
9521         local file=$DIR/$tfile
9522         local size_KB=500  #KB
9523         local count=100
9524         local bsize=1024
9525
9526         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9527         local need_KB=$((count * size_KB))
9528         [[ $free_KB -le $need_KB ]] &&
9529                 skip_env "Need free space $need_KB, have $free_KB"
9530
9531         echo "Creating $count ${size_KB}K test files"
9532         for ((i = 0; i < $count; i++)); do
9533                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9534         done
9535
9536         echo "Cancel LRU locks on lustre client to flush the client cache"
9537         cancel_lru_locks $OSC
9538
9539         echo "Reset readahead stats"
9540         $LCTL set_param -n llite.*.read_ahead_stats 0
9541
9542         for ((i = 0; i < $count; i++)); do
9543                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9544         done
9545
9546         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9547                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9548
9549         for ((i = 0; i < $count; i++)); do
9550                 rm -rf $file.$i 2>/dev/null
9551         done
9552
9553         #10000 means 20% reads are missing in readahead
9554         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9555 }
9556 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9557
9558 test_101f() {
9559         which iozone || skip_env "no iozone installed"
9560
9561         local old_debug=$($LCTL get_param debug)
9562         old_debug=${old_debug#*=}
9563         $LCTL set_param debug="reada mmap"
9564
9565         # create a test file
9566         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9567
9568         echo Cancel LRU locks on lustre client to flush the client cache
9569         cancel_lru_locks osc
9570
9571         echo Reset readahead stats
9572         $LCTL set_param -n llite.*.read_ahead_stats 0
9573
9574         echo mmap read the file with small block size
9575         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9576                 > /dev/null 2>&1
9577
9578         echo checking missing pages
9579         $LCTL get_param llite.*.read_ahead_stats
9580         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9581                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9582
9583         $LCTL set_param debug="$old_debug"
9584         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9585         rm -f $DIR/$tfile
9586 }
9587 run_test 101f "check mmap read performance"
9588
9589 test_101g_brw_size_test() {
9590         local mb=$1
9591         local pages=$((mb * 1048576 / PAGE_SIZE))
9592         local file=$DIR/$tfile
9593
9594         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9595                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9596         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9597                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9598                         return 2
9599         done
9600
9601         stack_trap "rm -f $file" EXIT
9602         $LCTL set_param -n osc.*.rpc_stats=0
9603
9604         # 10 RPCs should be enough for the test
9605         local count=10
9606         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9607                 { error "dd write ${mb} MB blocks failed"; return 3; }
9608         cancel_lru_locks osc
9609         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9610                 { error "dd write ${mb} MB blocks failed"; return 4; }
9611
9612         # calculate number of full-sized read and write RPCs
9613         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9614                 sed -n '/pages per rpc/,/^$/p' |
9615                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9616                 END { print reads,writes }'))
9617         # allow one extra full-sized read RPC for async readahead
9618         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9619                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9620         [[ ${rpcs[1]} == $count ]] ||
9621                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9622 }
9623
9624 test_101g() {
9625         remote_ost_nodsh && skip "remote OST with nodsh"
9626
9627         local rpcs
9628         local osts=$(get_facets OST)
9629         local list=$(comma_list $(osts_nodes))
9630         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9631         local brw_size="obdfilter.*.brw_size"
9632
9633         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9634
9635         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9636
9637         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9638                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9639                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9640            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9641                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9642                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9643
9644                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9645                         suffix="M"
9646
9647                 if [[ $orig_mb -lt 16 ]]; then
9648                         save_lustre_params $osts "$brw_size" > $p
9649                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9650                                 error "set 16MB RPC size failed"
9651
9652                         echo "remount client to enable new RPC size"
9653                         remount_client $MOUNT || error "remount_client failed"
9654                 fi
9655
9656                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9657                 # should be able to set brw_size=12, but no rpc_stats for that
9658                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9659         fi
9660
9661         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9662
9663         if [[ $orig_mb -lt 16 ]]; then
9664                 restore_lustre_params < $p
9665                 remount_client $MOUNT || error "remount_client restore failed"
9666         fi
9667
9668         rm -f $p $DIR/$tfile
9669 }
9670 run_test 101g "Big bulk(4/16 MiB) readahead"
9671
9672 test_101h() {
9673         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9674
9675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9676                 error "dd 70M file failed"
9677         echo Cancel LRU locks on lustre client to flush the client cache
9678         cancel_lru_locks osc
9679
9680         echo "Reset readahead stats"
9681         $LCTL set_param -n llite.*.read_ahead_stats 0
9682
9683         echo "Read 10M of data but cross 64M bundary"
9684         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9685         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9686                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9687         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9688         rm -f $p $DIR/$tfile
9689 }
9690 run_test 101h "Readahead should cover current read window"
9691
9692 test_101i() {
9693         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9694                 error "dd 10M file failed"
9695
9696         local max_per_file_mb=$($LCTL get_param -n \
9697                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9698         cancel_lru_locks osc
9699         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9700         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9701                 error "set max_read_ahead_per_file_mb to 1 failed"
9702
9703         echo "Reset readahead stats"
9704         $LCTL set_param llite.*.read_ahead_stats=0
9705
9706         dd if=$DIR/$tfile of=/dev/null bs=2M
9707
9708         $LCTL get_param llite.*.read_ahead_stats
9709         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9710                      awk '/misses/ { print $2 }')
9711         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9712         rm -f $DIR/$tfile
9713 }
9714 run_test 101i "allow current readahead to exceed reservation"
9715
9716 test_101j() {
9717         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9718                 error "setstripe $DIR/$tfile failed"
9719         local file_size=$((1048576 * 16))
9720         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9721         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9722
9723         echo Disable read-ahead
9724         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9725
9726         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9727         for blk in $PAGE_SIZE 1048576 $file_size; do
9728                 cancel_lru_locks osc
9729                 echo "Reset readahead stats"
9730                 $LCTL set_param -n llite.*.read_ahead_stats=0
9731                 local count=$(($file_size / $blk))
9732                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9733                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9734                              get_named_value 'failed to fast read' |
9735                              cut -d" " -f1 | calc_total)
9736                 $LCTL get_param -n llite.*.read_ahead_stats
9737                 [ $miss -eq $count ] || error "expected $count got $miss"
9738         done
9739
9740         rm -f $p $DIR/$tfile
9741 }
9742 run_test 101j "A complete read block should be submitted when no RA"
9743
9744 setup_test102() {
9745         test_mkdir $DIR/$tdir
9746         chown $RUNAS_ID $DIR/$tdir
9747         STRIPE_SIZE=65536
9748         STRIPE_OFFSET=1
9749         STRIPE_COUNT=$OSTCOUNT
9750         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9751
9752         trap cleanup_test102 EXIT
9753         cd $DIR
9754         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9755         cd $DIR/$tdir
9756         for num in 1 2 3 4; do
9757                 for count in $(seq 1 $STRIPE_COUNT); do
9758                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9759                                 local size=`expr $STRIPE_SIZE \* $num`
9760                                 local file=file"$num-$idx-$count"
9761                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9762                         done
9763                 done
9764         done
9765
9766         cd $DIR
9767         $1 tar cf $TMP/f102.tar $tdir --xattrs
9768 }
9769
9770 cleanup_test102() {
9771         trap 0
9772         rm -f $TMP/f102.tar
9773         rm -rf $DIR/d0.sanity/d102
9774 }
9775
9776 test_102a() {
9777         [ "$UID" != 0 ] && skip "must run as root"
9778         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9779                 skip_env "must have user_xattr"
9780
9781         [ -z "$(which setfattr 2>/dev/null)" ] &&
9782                 skip_env "could not find setfattr"
9783
9784         local testfile=$DIR/$tfile
9785
9786         touch $testfile
9787         echo "set/get xattr..."
9788         setfattr -n trusted.name1 -v value1 $testfile ||
9789                 error "setfattr -n trusted.name1=value1 $testfile failed"
9790         getfattr -n trusted.name1 $testfile 2> /dev/null |
9791           grep "trusted.name1=.value1" ||
9792                 error "$testfile missing trusted.name1=value1"
9793
9794         setfattr -n user.author1 -v author1 $testfile ||
9795                 error "setfattr -n user.author1=author1 $testfile failed"
9796         getfattr -n user.author1 $testfile 2> /dev/null |
9797           grep "user.author1=.author1" ||
9798                 error "$testfile missing trusted.author1=author1"
9799
9800         echo "listxattr..."
9801         setfattr -n trusted.name2 -v value2 $testfile ||
9802                 error "$testfile unable to set trusted.name2"
9803         setfattr -n trusted.name3 -v value3 $testfile ||
9804                 error "$testfile unable to set trusted.name3"
9805         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9806             grep "trusted.name" | wc -l) -eq 3 ] ||
9807                 error "$testfile missing 3 trusted.name xattrs"
9808
9809         setfattr -n user.author2 -v author2 $testfile ||
9810                 error "$testfile unable to set user.author2"
9811         setfattr -n user.author3 -v author3 $testfile ||
9812                 error "$testfile unable to set user.author3"
9813         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9814             grep "user.author" | wc -l) -eq 3 ] ||
9815                 error "$testfile missing 3 user.author xattrs"
9816
9817         echo "remove xattr..."
9818         setfattr -x trusted.name1 $testfile ||
9819                 error "$testfile error deleting trusted.name1"
9820         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9821                 error "$testfile did not delete trusted.name1 xattr"
9822
9823         setfattr -x user.author1 $testfile ||
9824                 error "$testfile error deleting user.author1"
9825         echo "set lustre special xattr ..."
9826         $LFS setstripe -c1 $testfile
9827         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9828                 awk -F "=" '/trusted.lov/ { print $2 }' )
9829         setfattr -n "trusted.lov" -v $lovea $testfile ||
9830                 error "$testfile doesn't ignore setting trusted.lov again"
9831         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9832                 error "$testfile allow setting invalid trusted.lov"
9833         rm -f $testfile
9834 }
9835 run_test 102a "user xattr test =================================="
9836
9837 check_102b_layout() {
9838         local layout="$*"
9839         local testfile=$DIR/$tfile
9840
9841         echo "test layout '$layout'"
9842         $LFS setstripe $layout $testfile || error "setstripe failed"
9843         $LFS getstripe -y $testfile
9844
9845         echo "get/set/list trusted.lov xattr ..." # b=10930
9846         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9847         [[ "$value" =~ "trusted.lov" ]] ||
9848                 error "can't get trusted.lov from $testfile"
9849         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9850                 error "getstripe failed"
9851
9852         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9853
9854         value=$(cut -d= -f2 <<<$value)
9855         # LU-13168: truncated xattr should fail if short lov_user_md header
9856         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9857                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9858         for len in $lens; do
9859                 echo "setfattr $len $testfile.2"
9860                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9861                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9862         done
9863         local stripe_size=$($LFS getstripe -S $testfile.2)
9864         local stripe_count=$($LFS getstripe -c $testfile.2)
9865         [[ $stripe_size -eq 65536 ]] ||
9866                 error "stripe size $stripe_size != 65536"
9867         [[ $stripe_count -eq $stripe_count_orig ]] ||
9868                 error "stripe count $stripe_count != $stripe_count_orig"
9869         rm $testfile $testfile.2
9870 }
9871
9872 test_102b() {
9873         [ -z "$(which setfattr 2>/dev/null)" ] &&
9874                 skip_env "could not find setfattr"
9875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9876
9877         # check plain layout
9878         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9879
9880         # and also check composite layout
9881         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9882
9883 }
9884 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9885
9886 test_102c() {
9887         [ -z "$(which setfattr 2>/dev/null)" ] &&
9888                 skip_env "could not find setfattr"
9889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9890
9891         # b10930: get/set/list lustre.lov xattr
9892         echo "get/set/list lustre.lov xattr ..."
9893         test_mkdir $DIR/$tdir
9894         chown $RUNAS_ID $DIR/$tdir
9895         local testfile=$DIR/$tdir/$tfile
9896         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9897                 error "setstripe failed"
9898         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9899                 error "getstripe failed"
9900         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9901         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9902
9903         local testfile2=${testfile}2
9904         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9905                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9906
9907         $RUNAS $MCREATE $testfile2
9908         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9909         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9910         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9911         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9912         [ $stripe_count -eq $STRIPECOUNT ] ||
9913                 error "stripe count $stripe_count != $STRIPECOUNT"
9914 }
9915 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9916
9917 compare_stripe_info1() {
9918         local stripe_index_all_zero=true
9919
9920         for num in 1 2 3 4; do
9921                 for count in $(seq 1 $STRIPE_COUNT); do
9922                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9923                                 local size=$((STRIPE_SIZE * num))
9924                                 local file=file"$num-$offset-$count"
9925                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9926                                 [[ $stripe_size -ne $size ]] &&
9927                                     error "$file: size $stripe_size != $size"
9928                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9929                                 # allow fewer stripes to be created, ORI-601
9930                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9931                                     error "$file: count $stripe_count != $count"
9932                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9933                                 [[ $stripe_index -ne 0 ]] &&
9934                                         stripe_index_all_zero=false
9935                         done
9936                 done
9937         done
9938         $stripe_index_all_zero &&
9939                 error "all files are being extracted starting from OST index 0"
9940         return 0
9941 }
9942
9943 have_xattrs_include() {
9944         tar --help | grep -q xattrs-include &&
9945                 echo --xattrs-include="lustre.*"
9946 }
9947
9948 test_102d() {
9949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9950         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9951
9952         XINC=$(have_xattrs_include)
9953         setup_test102
9954         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9955         cd $DIR/$tdir/$tdir
9956         compare_stripe_info1
9957 }
9958 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9959
9960 test_102f() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9963
9964         XINC=$(have_xattrs_include)
9965         setup_test102
9966         test_mkdir $DIR/$tdir.restore
9967         cd $DIR
9968         tar cf - --xattrs $tdir | tar xf - \
9969                 -C $DIR/$tdir.restore --xattrs $XINC
9970         cd $DIR/$tdir.restore/$tdir
9971         compare_stripe_info1
9972 }
9973 run_test 102f "tar copy files, not keep osts"
9974
9975 grow_xattr() {
9976         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9977                 skip "must have user_xattr"
9978         [ -z "$(which setfattr 2>/dev/null)" ] &&
9979                 skip_env "could not find setfattr"
9980         [ -z "$(which getfattr 2>/dev/null)" ] &&
9981                 skip_env "could not find getfattr"
9982
9983         local xsize=${1:-1024}  # in bytes
9984         local file=$DIR/$tfile
9985         local value="$(generate_string $xsize)"
9986         local xbig=trusted.big
9987         local toobig=$2
9988
9989         touch $file
9990         log "save $xbig on $file"
9991         if [ -z "$toobig" ]
9992         then
9993                 setfattr -n $xbig -v $value $file ||
9994                         error "saving $xbig on $file failed"
9995         else
9996                 setfattr -n $xbig -v $value $file &&
9997                         error "saving $xbig on $file succeeded"
9998                 return 0
9999         fi
10000
10001         local orig=$(get_xattr_value $xbig $file)
10002         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10003
10004         local xsml=trusted.sml
10005         log "save $xsml on $file"
10006         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10007
10008         local new=$(get_xattr_value $xbig $file)
10009         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10010
10011         log "grow $xsml on $file"
10012         setfattr -n $xsml -v "$value" $file ||
10013                 error "growing $xsml on $file failed"
10014
10015         new=$(get_xattr_value $xbig $file)
10016         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10017         log "$xbig still valid after growing $xsml"
10018
10019         rm -f $file
10020 }
10021
10022 test_102h() { # bug 15777
10023         grow_xattr 1024
10024 }
10025 run_test 102h "grow xattr from inside inode to external block"
10026
10027 test_102ha() {
10028         large_xattr_enabled || skip_env "ea_inode feature disabled"
10029
10030         echo "setting xattr of max xattr size: $(max_xattr_size)"
10031         grow_xattr $(max_xattr_size)
10032
10033         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10034         echo "This should fail:"
10035         grow_xattr $(($(max_xattr_size) + 10)) 1
10036 }
10037 run_test 102ha "grow xattr from inside inode to external inode"
10038
10039 test_102i() { # bug 17038
10040         [ -z "$(which getfattr 2>/dev/null)" ] &&
10041                 skip "could not find getfattr"
10042
10043         touch $DIR/$tfile
10044         ln -s $DIR/$tfile $DIR/${tfile}link
10045         getfattr -n trusted.lov $DIR/$tfile ||
10046                 error "lgetxattr on $DIR/$tfile failed"
10047         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10048                 grep -i "no such attr" ||
10049                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10050         rm -f $DIR/$tfile $DIR/${tfile}link
10051 }
10052 run_test 102i "lgetxattr test on symbolic link ============"
10053
10054 test_102j() {
10055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10056         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10057
10058         XINC=$(have_xattrs_include)
10059         setup_test102 "$RUNAS"
10060         chown $RUNAS_ID $DIR/$tdir
10061         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10062         cd $DIR/$tdir/$tdir
10063         compare_stripe_info1 "$RUNAS"
10064 }
10065 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10066
10067 test_102k() {
10068         [ -z "$(which setfattr 2>/dev/null)" ] &&
10069                 skip "could not find setfattr"
10070
10071         touch $DIR/$tfile
10072         # b22187 just check that does not crash for regular file.
10073         setfattr -n trusted.lov $DIR/$tfile
10074         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10075         local test_kdir=$DIR/$tdir
10076         test_mkdir $test_kdir
10077         local default_size=$($LFS getstripe -S $test_kdir)
10078         local default_count=$($LFS getstripe -c $test_kdir)
10079         local default_offset=$($LFS getstripe -i $test_kdir)
10080         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10081                 error 'dir setstripe failed'
10082         setfattr -n trusted.lov $test_kdir
10083         local stripe_size=$($LFS getstripe -S $test_kdir)
10084         local stripe_count=$($LFS getstripe -c $test_kdir)
10085         local stripe_offset=$($LFS getstripe -i $test_kdir)
10086         [ $stripe_size -eq $default_size ] ||
10087                 error "stripe size $stripe_size != $default_size"
10088         [ $stripe_count -eq $default_count ] ||
10089                 error "stripe count $stripe_count != $default_count"
10090         [ $stripe_offset -eq $default_offset ] ||
10091                 error "stripe offset $stripe_offset != $default_offset"
10092         rm -rf $DIR/$tfile $test_kdir
10093 }
10094 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10095
10096 test_102l() {
10097         [ -z "$(which getfattr 2>/dev/null)" ] &&
10098                 skip "could not find getfattr"
10099
10100         # LU-532 trusted. xattr is invisible to non-root
10101         local testfile=$DIR/$tfile
10102
10103         touch $testfile
10104
10105         echo "listxattr as user..."
10106         chown $RUNAS_ID $testfile
10107         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10108             grep -q "trusted" &&
10109                 error "$testfile trusted xattrs are user visible"
10110
10111         return 0;
10112 }
10113 run_test 102l "listxattr size test =================================="
10114
10115 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10116         local path=$DIR/$tfile
10117         touch $path
10118
10119         listxattr_size_check $path || error "listattr_size_check $path failed"
10120 }
10121 run_test 102m "Ensure listxattr fails on small bufffer ========"
10122
10123 cleanup_test102
10124
10125 getxattr() { # getxattr path name
10126         # Return the base64 encoding of the value of xattr name on path.
10127         local path=$1
10128         local name=$2
10129
10130         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10131         # file: $path
10132         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10133         #
10134         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10135
10136         getfattr --absolute-names --encoding=base64 --name=$name $path |
10137                 awk -F= -v name=$name '$1 == name {
10138                         print substr($0, index($0, "=") + 1);
10139         }'
10140 }
10141
10142 test_102n() { # LU-4101 mdt: protect internal xattrs
10143         [ -z "$(which setfattr 2>/dev/null)" ] &&
10144                 skip "could not find setfattr"
10145         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10146         then
10147                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10148         fi
10149
10150         local file0=$DIR/$tfile.0
10151         local file1=$DIR/$tfile.1
10152         local xattr0=$TMP/$tfile.0
10153         local xattr1=$TMP/$tfile.1
10154         local namelist="lov lma lmv link fid version som hsm"
10155         local name
10156         local value
10157
10158         rm -rf $file0 $file1 $xattr0 $xattr1
10159         touch $file0 $file1
10160
10161         # Get 'before' xattrs of $file1.
10162         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10163
10164         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10165                 namelist+=" lfsck_namespace"
10166         for name in $namelist; do
10167                 # Try to copy xattr from $file0 to $file1.
10168                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10169
10170                 setfattr --name=trusted.$name --value="$value" $file1 ||
10171                         error "setxattr 'trusted.$name' failed"
10172
10173                 # Try to set a garbage xattr.
10174                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10175
10176                 if [[ x$name == "xlov" ]]; then
10177                         setfattr --name=trusted.lov --value="$value" $file1 &&
10178                         error "setxattr invalid 'trusted.lov' success"
10179                 else
10180                         setfattr --name=trusted.$name --value="$value" $file1 ||
10181                                 error "setxattr invalid 'trusted.$name' failed"
10182                 fi
10183
10184                 # Try to remove the xattr from $file1. We don't care if this
10185                 # appears to succeed or fail, we just don't want there to be
10186                 # any changes or crashes.
10187                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10188         done
10189
10190         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10191         then
10192                 name="lfsck_ns"
10193                 # Try to copy xattr from $file0 to $file1.
10194                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10195
10196                 setfattr --name=trusted.$name --value="$value" $file1 ||
10197                         error "setxattr 'trusted.$name' failed"
10198
10199                 # Try to set a garbage xattr.
10200                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10201
10202                 setfattr --name=trusted.$name --value="$value" $file1 ||
10203                         error "setxattr 'trusted.$name' failed"
10204
10205                 # Try to remove the xattr from $file1. We don't care if this
10206                 # appears to succeed or fail, we just don't want there to be
10207                 # any changes or crashes.
10208                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10209         fi
10210
10211         # Get 'after' xattrs of file1.
10212         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10213
10214         if ! diff $xattr0 $xattr1; then
10215                 error "before and after xattrs of '$file1' differ"
10216         fi
10217
10218         rm -rf $file0 $file1 $xattr0 $xattr1
10219
10220         return 0
10221 }
10222 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10223
10224 test_102p() { # LU-4703 setxattr did not check ownership
10225         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10226                 skip "MDS needs to be at least 2.5.56"
10227
10228         local testfile=$DIR/$tfile
10229
10230         touch $testfile
10231
10232         echo "setfacl as user..."
10233         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10234         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10235
10236         echo "setfattr as user..."
10237         setfacl -m "u:$RUNAS_ID:---" $testfile
10238         $RUNAS setfattr -x system.posix_acl_access $testfile
10239         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10240 }
10241 run_test 102p "check setxattr(2) correctly fails without permission"
10242
10243 test_102q() {
10244         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10245                 skip "MDS needs to be at least 2.6.92"
10246
10247         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10248 }
10249 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10250
10251 test_102r() {
10252         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10253                 skip "MDS needs to be at least 2.6.93"
10254
10255         touch $DIR/$tfile || error "touch"
10256         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10257         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10258         rm $DIR/$tfile || error "rm"
10259
10260         #normal directory
10261         mkdir -p $DIR/$tdir || error "mkdir"
10262         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10263         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10264         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10265                 error "$testfile error deleting user.author1"
10266         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10267                 grep "user.$(basename $tdir)" &&
10268                 error "$tdir did not delete user.$(basename $tdir)"
10269         rmdir $DIR/$tdir || error "rmdir"
10270
10271         #striped directory
10272         test_mkdir $DIR/$tdir
10273         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10274         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10275         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10276                 error "$testfile error deleting user.author1"
10277         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10278                 grep "user.$(basename $tdir)" &&
10279                 error "$tdir did not delete user.$(basename $tdir)"
10280         rmdir $DIR/$tdir || error "rm striped dir"
10281 }
10282 run_test 102r "set EAs with empty values"
10283
10284 test_102s() {
10285         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10286                 skip "MDS needs to be at least 2.11.52"
10287
10288         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10289
10290         save_lustre_params client "llite.*.xattr_cache" > $save
10291
10292         for cache in 0 1; do
10293                 lctl set_param llite.*.xattr_cache=$cache
10294
10295                 rm -f $DIR/$tfile
10296                 touch $DIR/$tfile || error "touch"
10297                 for prefix in lustre security system trusted user; do
10298                         # Note getxattr() may fail with 'Operation not
10299                         # supported' or 'No such attribute' depending
10300                         # on prefix and cache.
10301                         getfattr -n $prefix.n102s $DIR/$tfile &&
10302                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10303                 done
10304         done
10305
10306         restore_lustre_params < $save
10307 }
10308 run_test 102s "getting nonexistent xattrs should fail"
10309
10310 test_102t() {
10311         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10312                 skip "MDS needs to be at least 2.11.52"
10313
10314         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10315
10316         save_lustre_params client "llite.*.xattr_cache" > $save
10317
10318         for cache in 0 1; do
10319                 lctl set_param llite.*.xattr_cache=$cache
10320
10321                 for buf_size in 0 256; do
10322                         rm -f $DIR/$tfile
10323                         touch $DIR/$tfile || error "touch"
10324                         setfattr -n user.multiop $DIR/$tfile
10325                         $MULTIOP $DIR/$tfile oa$buf_size ||
10326                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10327                 done
10328         done
10329
10330         restore_lustre_params < $save
10331 }
10332 run_test 102t "zero length xattr values handled correctly"
10333
10334 run_acl_subtest()
10335 {
10336     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10337     return $?
10338 }
10339
10340 test_103a() {
10341         [ "$UID" != 0 ] && skip "must run as root"
10342         $GSS && skip_env "could not run under gss"
10343         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10344                 skip_env "must have acl enabled"
10345         [ -z "$(which setfacl 2>/dev/null)" ] &&
10346                 skip_env "could not find setfacl"
10347         remote_mds_nodsh && skip "remote MDS with nodsh"
10348
10349         gpasswd -a daemon bin                           # LU-5641
10350         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10351
10352         declare -a identity_old
10353
10354         for num in $(seq $MDSCOUNT); do
10355                 switch_identity $num true || identity_old[$num]=$?
10356         done
10357
10358         SAVE_UMASK=$(umask)
10359         umask 0022
10360         mkdir -p $DIR/$tdir
10361         cd $DIR/$tdir
10362
10363         echo "performing cp ..."
10364         run_acl_subtest cp || error "run_acl_subtest cp failed"
10365         echo "performing getfacl-noacl..."
10366         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10367         echo "performing misc..."
10368         run_acl_subtest misc || error  "misc test failed"
10369         echo "performing permissions..."
10370         run_acl_subtest permissions || error "permissions failed"
10371         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10372         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10373                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10374                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10375         then
10376                 echo "performing permissions xattr..."
10377                 run_acl_subtest permissions_xattr ||
10378                         error "permissions_xattr failed"
10379         fi
10380         echo "performing setfacl..."
10381         run_acl_subtest setfacl || error  "setfacl test failed"
10382
10383         # inheritance test got from HP
10384         echo "performing inheritance..."
10385         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10386         chmod +x make-tree || error "chmod +x failed"
10387         run_acl_subtest inheritance || error "inheritance test failed"
10388         rm -f make-tree
10389
10390         echo "LU-974 ignore umask when acl is enabled..."
10391         run_acl_subtest 974 || error "LU-974 umask test failed"
10392         if [ $MDSCOUNT -ge 2 ]; then
10393                 run_acl_subtest 974_remote ||
10394                         error "LU-974 umask test failed under remote dir"
10395         fi
10396
10397         echo "LU-2561 newly created file is same size as directory..."
10398         if [ "$mds1_FSTYPE" != "zfs" ]; then
10399                 run_acl_subtest 2561 || error "LU-2561 test failed"
10400         else
10401                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10402         fi
10403
10404         run_acl_subtest 4924 || error "LU-4924 test failed"
10405
10406         cd $SAVE_PWD
10407         umask $SAVE_UMASK
10408
10409         for num in $(seq $MDSCOUNT); do
10410                 if [ "${identity_old[$num]}" = 1 ]; then
10411                         switch_identity $num false || identity_old[$num]=$?
10412                 fi
10413         done
10414 }
10415 run_test 103a "acl test"
10416
10417 test_103b() {
10418         declare -a pids
10419         local U
10420
10421         for U in {0..511}; do
10422                 {
10423                 local O=$(printf "%04o" $U)
10424
10425                 umask $(printf "%04o" $((511 ^ $O)))
10426                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10427                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10428
10429                 (( $S == ($O & 0666) )) ||
10430                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10431
10432                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10433                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10434                 (( $S == ($O & 0666) )) ||
10435                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10436
10437                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10438                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10439                 (( $S == ($O & 0666) )) ||
10440                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10441                 rm -f $DIR/$tfile.[smp]$0
10442                 } &
10443                 local pid=$!
10444
10445                 # limit the concurrently running threads to 64. LU-11878
10446                 local idx=$((U % 64))
10447                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10448                 pids[idx]=$pid
10449         done
10450         wait
10451 }
10452 run_test 103b "umask lfs setstripe"
10453
10454 test_103c() {
10455         mkdir -p $DIR/$tdir
10456         cp -rp $DIR/$tdir $DIR/$tdir.bak
10457
10458         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10459                 error "$DIR/$tdir shouldn't contain default ACL"
10460         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10461                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10462         true
10463 }
10464 run_test 103c "'cp -rp' won't set empty acl"
10465
10466 test_104a() {
10467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10468
10469         touch $DIR/$tfile
10470         lfs df || error "lfs df failed"
10471         lfs df -ih || error "lfs df -ih failed"
10472         lfs df -h $DIR || error "lfs df -h $DIR failed"
10473         lfs df -i $DIR || error "lfs df -i $DIR failed"
10474         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10475         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10476
10477         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10478         lctl --device %$OSC deactivate
10479         lfs df || error "lfs df with deactivated OSC failed"
10480         lctl --device %$OSC activate
10481         # wait the osc back to normal
10482         wait_osc_import_ready client ost
10483
10484         lfs df || error "lfs df with reactivated OSC failed"
10485         rm -f $DIR/$tfile
10486 }
10487 run_test 104a "lfs df [-ih] [path] test ========================="
10488
10489 test_104b() {
10490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10491         [ $RUNAS_ID -eq $UID ] &&
10492                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10493
10494         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10495                         grep "Permission denied" | wc -l)))
10496         if [ $denied_cnt -ne 0 ]; then
10497                 error "lfs check servers test failed"
10498         fi
10499 }
10500 run_test 104b "$RUNAS lfs check servers test ===================="
10501
10502 test_105a() {
10503         # doesn't work on 2.4 kernels
10504         touch $DIR/$tfile
10505         if $(flock_is_enabled); then
10506                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10507         else
10508                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10509         fi
10510         rm -f $DIR/$tfile
10511 }
10512 run_test 105a "flock when mounted without -o flock test ========"
10513
10514 test_105b() {
10515         touch $DIR/$tfile
10516         if $(flock_is_enabled); then
10517                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10518         else
10519                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10520         fi
10521         rm -f $DIR/$tfile
10522 }
10523 run_test 105b "fcntl when mounted without -o flock test ========"
10524
10525 test_105c() {
10526         touch $DIR/$tfile
10527         if $(flock_is_enabled); then
10528                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10529         else
10530                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10531         fi
10532         rm -f $DIR/$tfile
10533 }
10534 run_test 105c "lockf when mounted without -o flock test"
10535
10536 test_105d() { # bug 15924
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538
10539         test_mkdir $DIR/$tdir
10540         flock_is_enabled || skip_env "mount w/o flock enabled"
10541         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10542         $LCTL set_param fail_loc=0x80000315
10543         flocks_test 2 $DIR/$tdir
10544 }
10545 run_test 105d "flock race (should not freeze) ========"
10546
10547 test_105e() { # bug 22660 && 22040
10548         flock_is_enabled || skip_env "mount w/o flock enabled"
10549
10550         touch $DIR/$tfile
10551         flocks_test 3 $DIR/$tfile
10552 }
10553 run_test 105e "Two conflicting flocks from same process"
10554
10555 test_106() { #bug 10921
10556         test_mkdir $DIR/$tdir
10557         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10558         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10559 }
10560 run_test 106 "attempt exec of dir followed by chown of that dir"
10561
10562 test_107() {
10563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10564
10565         CDIR=`pwd`
10566         local file=core
10567
10568         cd $DIR
10569         rm -f $file
10570
10571         local save_pattern=$(sysctl -n kernel.core_pattern)
10572         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10573         sysctl -w kernel.core_pattern=$file
10574         sysctl -w kernel.core_uses_pid=0
10575
10576         ulimit -c unlimited
10577         sleep 60 &
10578         SLEEPPID=$!
10579
10580         sleep 1
10581
10582         kill -s 11 $SLEEPPID
10583         wait $SLEEPPID
10584         if [ -e $file ]; then
10585                 size=`stat -c%s $file`
10586                 [ $size -eq 0 ] && error "Fail to create core file $file"
10587         else
10588                 error "Fail to create core file $file"
10589         fi
10590         rm -f $file
10591         sysctl -w kernel.core_pattern=$save_pattern
10592         sysctl -w kernel.core_uses_pid=$save_uses_pid
10593         cd $CDIR
10594 }
10595 run_test 107 "Coredump on SIG"
10596
10597 test_110() {
10598         test_mkdir $DIR/$tdir
10599         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10600         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10601                 error "mkdir with 256 char should fail, but did not"
10602         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10603                 error "create with 255 char failed"
10604         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10605                 error "create with 256 char should fail, but did not"
10606
10607         ls -l $DIR/$tdir
10608         rm -rf $DIR/$tdir
10609 }
10610 run_test 110 "filename length checking"
10611
10612 #
10613 # Purpose: To verify dynamic thread (OSS) creation.
10614 #
10615 test_115() {
10616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10617         remote_ost_nodsh && skip "remote OST with nodsh"
10618
10619         # Lustre does not stop service threads once they are started.
10620         # Reset number of running threads to default.
10621         stopall
10622         setupall
10623
10624         local OSTIO_pre
10625         local save_params="$TMP/sanity-$TESTNAME.parameters"
10626
10627         # Get ll_ost_io count before I/O
10628         OSTIO_pre=$(do_facet ost1 \
10629                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10630         # Exit if lustre is not running (ll_ost_io not running).
10631         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10632
10633         echo "Starting with $OSTIO_pre threads"
10634         local thread_max=$((OSTIO_pre * 2))
10635         local rpc_in_flight=$((thread_max * 2))
10636         # Number of I/O Process proposed to be started.
10637         local nfiles
10638         local facets=$(get_facets OST)
10639
10640         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10641         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10642
10643         # Set in_flight to $rpc_in_flight
10644         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10645                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10646         nfiles=${rpc_in_flight}
10647         # Set ost thread_max to $thread_max
10648         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10649
10650         # 5 Minutes should be sufficient for max number of OSS
10651         # threads(thread_max) to be created.
10652         local timeout=300
10653
10654         # Start I/O.
10655         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10656         test_mkdir $DIR/$tdir
10657         for i in $(seq $nfiles); do
10658                 local file=$DIR/$tdir/${tfile}-$i
10659                 $LFS setstripe -c -1 -i 0 $file
10660                 ($WTL $file $timeout)&
10661         done
10662
10663         # I/O Started - Wait for thread_started to reach thread_max or report
10664         # error if thread_started is more than thread_max.
10665         echo "Waiting for thread_started to reach thread_max"
10666         local thread_started=0
10667         local end_time=$((SECONDS + timeout))
10668
10669         while [ $SECONDS -le $end_time ] ; do
10670                 echo -n "."
10671                 # Get ost i/o thread_started count.
10672                 thread_started=$(do_facet ost1 \
10673                         "$LCTL get_param \
10674                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10675                 # Break out if thread_started is equal/greater than thread_max
10676                 if [[ $thread_started -ge $thread_max ]]; then
10677                         echo ll_ost_io thread_started $thread_started, \
10678                                 equal/greater than thread_max $thread_max
10679                         break
10680                 fi
10681                 sleep 1
10682         done
10683
10684         # Cleanup - We have the numbers, Kill i/o jobs if running.
10685         jobcount=($(jobs -p))
10686         for i in $(seq 0 $((${#jobcount[@]}-1)))
10687         do
10688                 kill -9 ${jobcount[$i]}
10689                 if [ $? -ne 0 ] ; then
10690                         echo Warning: \
10691                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10692                 fi
10693         done
10694
10695         # Cleanup files left by WTL binary.
10696         for i in $(seq $nfiles); do
10697                 local file=$DIR/$tdir/${tfile}-$i
10698                 rm -rf $file
10699                 if [ $? -ne 0 ] ; then
10700                         echo "Warning: Failed to delete file $file"
10701                 fi
10702         done
10703
10704         restore_lustre_params <$save_params
10705         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10706
10707         # Error out if no new thread has started or Thread started is greater
10708         # than thread max.
10709         if [[ $thread_started -le $OSTIO_pre ||
10710                         $thread_started -gt $thread_max ]]; then
10711                 error "ll_ost_io: thread_started $thread_started" \
10712                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10713                       "No new thread started or thread started greater " \
10714                       "than thread_max."
10715         fi
10716 }
10717 run_test 115 "verify dynamic thread creation===================="
10718
10719 free_min_max () {
10720         wait_delete_completed
10721         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10722         echo "OST kbytes available: ${AVAIL[@]}"
10723         MAXV=${AVAIL[0]}
10724         MAXI=0
10725         MINV=${AVAIL[0]}
10726         MINI=0
10727         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10728                 #echo OST $i: ${AVAIL[i]}kb
10729                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10730                         MAXV=${AVAIL[i]}
10731                         MAXI=$i
10732                 fi
10733                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10734                         MINV=${AVAIL[i]}
10735                         MINI=$i
10736                 fi
10737         done
10738         echo "Min free space: OST $MINI: $MINV"
10739         echo "Max free space: OST $MAXI: $MAXV"
10740 }
10741
10742 test_116a() { # was previously test_116()
10743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10745         remote_mds_nodsh && skip "remote MDS with nodsh"
10746
10747         echo -n "Free space priority "
10748         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10749                 head -n1
10750         declare -a AVAIL
10751         free_min_max
10752
10753         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10754         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10755         trap simple_cleanup_common EXIT
10756
10757         # Check if we need to generate uneven OSTs
10758         test_mkdir -p $DIR/$tdir/OST${MINI}
10759         local FILL=$((MINV / 4))
10760         local DIFF=$((MAXV - MINV))
10761         local DIFF2=$((DIFF * 100 / MINV))
10762
10763         local threshold=$(do_facet $SINGLEMDS \
10764                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10765         threshold=${threshold%%%}
10766         echo -n "Check for uneven OSTs: "
10767         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10768
10769         if [[ $DIFF2 -gt $threshold ]]; then
10770                 echo "ok"
10771                 echo "Don't need to fill OST$MINI"
10772         else
10773                 # generate uneven OSTs. Write 2% over the QOS threshold value
10774                 echo "no"
10775                 DIFF=$((threshold - DIFF2 + 2))
10776                 DIFF2=$((MINV * DIFF / 100))
10777                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10778                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10779                         error "setstripe failed"
10780                 DIFF=$((DIFF2 / 2048))
10781                 i=0
10782                 while [ $i -lt $DIFF ]; do
10783                         i=$((i + 1))
10784                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10785                                 bs=2M count=1 2>/dev/null
10786                         echo -n .
10787                 done
10788                 echo .
10789                 sync
10790                 sleep_maxage
10791                 free_min_max
10792         fi
10793
10794         DIFF=$((MAXV - MINV))
10795         DIFF2=$((DIFF * 100 / MINV))
10796         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10797         if [ $DIFF2 -gt $threshold ]; then
10798                 echo "ok"
10799         else
10800                 echo "failed - QOS mode won't be used"
10801                 simple_cleanup_common
10802                 skip "QOS imbalance criteria not met"
10803         fi
10804
10805         MINI1=$MINI
10806         MINV1=$MINV
10807         MAXI1=$MAXI
10808         MAXV1=$MAXV
10809
10810         # now fill using QOS
10811         $LFS setstripe -c 1 $DIR/$tdir
10812         FILL=$((FILL / 200))
10813         if [ $FILL -gt 600 ]; then
10814                 FILL=600
10815         fi
10816         echo "writing $FILL files to QOS-assigned OSTs"
10817         i=0
10818         while [ $i -lt $FILL ]; do
10819                 i=$((i + 1))
10820                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10821                         count=1 2>/dev/null
10822                 echo -n .
10823         done
10824         echo "wrote $i 200k files"
10825         sync
10826         sleep_maxage
10827
10828         echo "Note: free space may not be updated, so measurements might be off"
10829         free_min_max
10830         DIFF2=$((MAXV - MINV))
10831         echo "free space delta: orig $DIFF final $DIFF2"
10832         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10833         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10834         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10835         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10836         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10837         if [[ $DIFF -gt 0 ]]; then
10838                 FILL=$((DIFF2 * 100 / DIFF - 100))
10839                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10840         fi
10841
10842         # Figure out which files were written where
10843         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10844                awk '/'$MINI1': / {print $2; exit}')
10845         echo $UUID
10846         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10847         echo "$MINC files created on smaller OST $MINI1"
10848         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10849                awk '/'$MAXI1': / {print $2; exit}')
10850         echo $UUID
10851         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10852         echo "$MAXC files created on larger OST $MAXI1"
10853         if [[ $MINC -gt 0 ]]; then
10854                 FILL=$((MAXC * 100 / MINC - 100))
10855                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10856         fi
10857         [[ $MAXC -gt $MINC ]] ||
10858                 error_ignore LU-9 "stripe QOS didn't balance free space"
10859         simple_cleanup_common
10860 }
10861 run_test 116a "stripe QOS: free space balance ==================="
10862
10863 test_116b() { # LU-2093
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865         remote_mds_nodsh && skip "remote MDS with nodsh"
10866
10867 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10868         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10869                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10870         [ -z "$old_rr" ] && skip "no QOS"
10871         do_facet $SINGLEMDS lctl set_param \
10872                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10873         mkdir -p $DIR/$tdir
10874         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10875         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10876         do_facet $SINGLEMDS lctl set_param fail_loc=0
10877         rm -rf $DIR/$tdir
10878         do_facet $SINGLEMDS lctl set_param \
10879                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10880 }
10881 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10882
10883 test_117() # bug 10891
10884 {
10885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10886
10887         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10888         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10889         lctl set_param fail_loc=0x21e
10890         > $DIR/$tfile || error "truncate failed"
10891         lctl set_param fail_loc=0
10892         echo "Truncate succeeded."
10893         rm -f $DIR/$tfile
10894 }
10895 run_test 117 "verify osd extend =========="
10896
10897 NO_SLOW_RESENDCOUNT=4
10898 export OLD_RESENDCOUNT=""
10899 set_resend_count () {
10900         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10901         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10902         lctl set_param -n $PROC_RESENDCOUNT $1
10903         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10904 }
10905
10906 # for reduce test_118* time (b=14842)
10907 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10908
10909 # Reset async IO behavior after error case
10910 reset_async() {
10911         FILE=$DIR/reset_async
10912
10913         # Ensure all OSCs are cleared
10914         $LFS setstripe -c -1 $FILE
10915         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10916         sync
10917         rm $FILE
10918 }
10919
10920 test_118a() #bug 11710
10921 {
10922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10923
10924         reset_async
10925
10926         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10927         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10928         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10929
10930         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10931                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10932                 return 1;
10933         fi
10934         rm -f $DIR/$tfile
10935 }
10936 run_test 118a "verify O_SYNC works =========="
10937
10938 test_118b()
10939 {
10940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10941         remote_ost_nodsh && skip "remote OST with nodsh"
10942
10943         reset_async
10944
10945         #define OBD_FAIL_SRV_ENOENT 0x217
10946         set_nodes_failloc "$(osts_nodes)" 0x217
10947         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10948         RC=$?
10949         set_nodes_failloc "$(osts_nodes)" 0
10950         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10951         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10952                     grep -c writeback)
10953
10954         if [[ $RC -eq 0 ]]; then
10955                 error "Must return error due to dropped pages, rc=$RC"
10956                 return 1;
10957         fi
10958
10959         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10960                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10961                 return 1;
10962         fi
10963
10964         echo "Dirty pages not leaked on ENOENT"
10965
10966         # Due to the above error the OSC will issue all RPCs syncronously
10967         # until a subsequent RPC completes successfully without error.
10968         $MULTIOP $DIR/$tfile Ow4096yc
10969         rm -f $DIR/$tfile
10970
10971         return 0
10972 }
10973 run_test 118b "Reclaim dirty pages on fatal error =========="
10974
10975 test_118c()
10976 {
10977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10978
10979         # for 118c, restore the original resend count, LU-1940
10980         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10981                                 set_resend_count $OLD_RESENDCOUNT
10982         remote_ost_nodsh && skip "remote OST with nodsh"
10983
10984         reset_async
10985
10986         #define OBD_FAIL_OST_EROFS               0x216
10987         set_nodes_failloc "$(osts_nodes)" 0x216
10988
10989         # multiop should block due to fsync until pages are written
10990         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10991         MULTIPID=$!
10992         sleep 1
10993
10994         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10995                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10996         fi
10997
10998         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10999                     grep -c writeback)
11000         if [[ $WRITEBACK -eq 0 ]]; then
11001                 error "No page in writeback, writeback=$WRITEBACK"
11002         fi
11003
11004         set_nodes_failloc "$(osts_nodes)" 0
11005         wait $MULTIPID
11006         RC=$?
11007         if [[ $RC -ne 0 ]]; then
11008                 error "Multiop fsync failed, rc=$RC"
11009         fi
11010
11011         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11012         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11013                     grep -c writeback)
11014         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11015                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11016         fi
11017
11018         rm -f $DIR/$tfile
11019         echo "Dirty pages flushed via fsync on EROFS"
11020         return 0
11021 }
11022 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11023
11024 # continue to use small resend count to reduce test_118* time (b=14842)
11025 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11026
11027 test_118d()
11028 {
11029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11030         remote_ost_nodsh && skip "remote OST with nodsh"
11031
11032         reset_async
11033
11034         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11035         set_nodes_failloc "$(osts_nodes)" 0x214
11036         # multiop should block due to fsync until pages are written
11037         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11038         MULTIPID=$!
11039         sleep 1
11040
11041         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11042                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11043         fi
11044
11045         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11046                     grep -c writeback)
11047         if [[ $WRITEBACK -eq 0 ]]; then
11048                 error "No page in writeback, writeback=$WRITEBACK"
11049         fi
11050
11051         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11052         set_nodes_failloc "$(osts_nodes)" 0
11053
11054         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11055         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11056                     grep -c writeback)
11057         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11058                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11059         fi
11060
11061         rm -f $DIR/$tfile
11062         echo "Dirty pages gaurenteed flushed via fsync"
11063         return 0
11064 }
11065 run_test 118d "Fsync validation inject a delay of the bulk =========="
11066
11067 test_118f() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069
11070         reset_async
11071
11072         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11073         lctl set_param fail_loc=0x8000040a
11074
11075         # Should simulate EINVAL error which is fatal
11076         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11077         RC=$?
11078         if [[ $RC -eq 0 ]]; then
11079                 error "Must return error due to dropped pages, rc=$RC"
11080         fi
11081
11082         lctl set_param fail_loc=0x0
11083
11084         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11085         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11086         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11087                     grep -c writeback)
11088         if [[ $LOCKED -ne 0 ]]; then
11089                 error "Locked pages remain in cache, locked=$LOCKED"
11090         fi
11091
11092         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11093                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11094         fi
11095
11096         rm -f $DIR/$tfile
11097         echo "No pages locked after fsync"
11098
11099         reset_async
11100         return 0
11101 }
11102 run_test 118f "Simulate unrecoverable OSC side error =========="
11103
11104 test_118g() {
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106
11107         reset_async
11108
11109         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11110         lctl set_param fail_loc=0x406
11111
11112         # simulate local -ENOMEM
11113         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11114         RC=$?
11115
11116         lctl set_param fail_loc=0
11117         if [[ $RC -eq 0 ]]; then
11118                 error "Must return error due to dropped pages, rc=$RC"
11119         fi
11120
11121         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11122         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11123         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11124                         grep -c writeback)
11125         if [[ $LOCKED -ne 0 ]]; then
11126                 error "Locked pages remain in cache, locked=$LOCKED"
11127         fi
11128
11129         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11130                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11131         fi
11132
11133         rm -f $DIR/$tfile
11134         echo "No pages locked after fsync"
11135
11136         reset_async
11137         return 0
11138 }
11139 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11140
11141 test_118h() {
11142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11143         remote_ost_nodsh && skip "remote OST with nodsh"
11144
11145         reset_async
11146
11147         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11148         set_nodes_failloc "$(osts_nodes)" 0x20e
11149         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11150         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11151         RC=$?
11152
11153         set_nodes_failloc "$(osts_nodes)" 0
11154         if [[ $RC -eq 0 ]]; then
11155                 error "Must return error due to dropped pages, rc=$RC"
11156         fi
11157
11158         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11159         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11160         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11161                     grep -c writeback)
11162         if [[ $LOCKED -ne 0 ]]; then
11163                 error "Locked pages remain in cache, locked=$LOCKED"
11164         fi
11165
11166         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11167                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11168         fi
11169
11170         rm -f $DIR/$tfile
11171         echo "No pages locked after fsync"
11172
11173         return 0
11174 }
11175 run_test 118h "Verify timeout in handling recoverables errors  =========="
11176
11177 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11178
11179 test_118i() {
11180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11181         remote_ost_nodsh && skip "remote OST with nodsh"
11182
11183         reset_async
11184
11185         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11186         set_nodes_failloc "$(osts_nodes)" 0x20e
11187
11188         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11189         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11190         PID=$!
11191         sleep 5
11192         set_nodes_failloc "$(osts_nodes)" 0
11193
11194         wait $PID
11195         RC=$?
11196         if [[ $RC -ne 0 ]]; then
11197                 error "got error, but should be not, rc=$RC"
11198         fi
11199
11200         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11201         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11202         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11203         if [[ $LOCKED -ne 0 ]]; then
11204                 error "Locked pages remain in cache, locked=$LOCKED"
11205         fi
11206
11207         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11208                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11209         fi
11210
11211         rm -f $DIR/$tfile
11212         echo "No pages locked after fsync"
11213
11214         return 0
11215 }
11216 run_test 118i "Fix error before timeout in recoverable error  =========="
11217
11218 [ "$SLOW" = "no" ] && set_resend_count 4
11219
11220 test_118j() {
11221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11222         remote_ost_nodsh && skip "remote OST with nodsh"
11223
11224         reset_async
11225
11226         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11227         set_nodes_failloc "$(osts_nodes)" 0x220
11228
11229         # return -EIO from OST
11230         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11231         RC=$?
11232         set_nodes_failloc "$(osts_nodes)" 0x0
11233         if [[ $RC -eq 0 ]]; then
11234                 error "Must return error due to dropped pages, rc=$RC"
11235         fi
11236
11237         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11238         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11239         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11240         if [[ $LOCKED -ne 0 ]]; then
11241                 error "Locked pages remain in cache, locked=$LOCKED"
11242         fi
11243
11244         # in recoverable error on OST we want resend and stay until it finished
11245         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11246                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11247         fi
11248
11249         rm -f $DIR/$tfile
11250         echo "No pages locked after fsync"
11251
11252         return 0
11253 }
11254 run_test 118j "Simulate unrecoverable OST side error =========="
11255
11256 test_118k()
11257 {
11258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11259         remote_ost_nodsh && skip "remote OSTs with nodsh"
11260
11261         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11262         set_nodes_failloc "$(osts_nodes)" 0x20e
11263         test_mkdir $DIR/$tdir
11264
11265         for ((i=0;i<10;i++)); do
11266                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11267                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11268                 SLEEPPID=$!
11269                 sleep 0.500s
11270                 kill $SLEEPPID
11271                 wait $SLEEPPID
11272         done
11273
11274         set_nodes_failloc "$(osts_nodes)" 0
11275         rm -rf $DIR/$tdir
11276 }
11277 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11278
11279 test_118l() # LU-646
11280 {
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282
11283         test_mkdir $DIR/$tdir
11284         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11285         rm -rf $DIR/$tdir
11286 }
11287 run_test 118l "fsync dir"
11288
11289 test_118m() # LU-3066
11290 {
11291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11292
11293         test_mkdir $DIR/$tdir
11294         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11295         rm -rf $DIR/$tdir
11296 }
11297 run_test 118m "fdatasync dir ========="
11298
11299 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11300
11301 test_118n()
11302 {
11303         local begin
11304         local end
11305
11306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11307         remote_ost_nodsh && skip "remote OSTs with nodsh"
11308
11309         # Sleep to avoid a cached response.
11310         #define OBD_STATFS_CACHE_SECONDS 1
11311         sleep 2
11312
11313         # Inject a 10 second delay in the OST_STATFS handler.
11314         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11315         set_nodes_failloc "$(osts_nodes)" 0x242
11316
11317         begin=$SECONDS
11318         stat --file-system $MOUNT > /dev/null
11319         end=$SECONDS
11320
11321         set_nodes_failloc "$(osts_nodes)" 0
11322
11323         if ((end - begin > 20)); then
11324             error "statfs took $((end - begin)) seconds, expected 10"
11325         fi
11326 }
11327 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11328
11329 test_119a() # bug 11737
11330 {
11331         BSIZE=$((512 * 1024))
11332         directio write $DIR/$tfile 0 1 $BSIZE
11333         # We ask to read two blocks, which is more than a file size.
11334         # directio will indicate an error when requested and actual
11335         # sizes aren't equeal (a normal situation in this case) and
11336         # print actual read amount.
11337         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11338         if [ "$NOB" != "$BSIZE" ]; then
11339                 error "read $NOB bytes instead of $BSIZE"
11340         fi
11341         rm -f $DIR/$tfile
11342 }
11343 run_test 119a "Short directIO read must return actual read amount"
11344
11345 test_119b() # bug 11737
11346 {
11347         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11348
11349         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11350         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11351         sync
11352         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11353                 error "direct read failed"
11354         rm -f $DIR/$tfile
11355 }
11356 run_test 119b "Sparse directIO read must return actual read amount"
11357
11358 test_119c() # bug 13099
11359 {
11360         BSIZE=1048576
11361         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11362         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11363         rm -f $DIR/$tfile
11364 }
11365 run_test 119c "Testing for direct read hitting hole"
11366
11367 test_119d() # bug 15950
11368 {
11369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11370
11371         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11372         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11373         BSIZE=1048576
11374         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11375         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11376         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11377         lctl set_param fail_loc=0x40d
11378         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11379         pid_dio=$!
11380         sleep 1
11381         cat $DIR/$tfile > /dev/null &
11382         lctl set_param fail_loc=0
11383         pid_reads=$!
11384         wait $pid_dio
11385         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11386         sleep 2
11387         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11388         error "the read rpcs have not completed in 2s"
11389         rm -f $DIR/$tfile
11390         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11391 }
11392 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11393
11394 test_120a() {
11395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11396         remote_mds_nodsh && skip "remote MDS with nodsh"
11397         test_mkdir -i0 -c1 $DIR/$tdir
11398         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11399                 skip_env "no early lock cancel on server"
11400
11401         lru_resize_disable mdc
11402         lru_resize_disable osc
11403         cancel_lru_locks mdc
11404         # asynchronous object destroy at MDT could cause bl ast to client
11405         cancel_lru_locks osc
11406
11407         stat $DIR/$tdir > /dev/null
11408         can1=$(do_facet mds1 \
11409                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11410                awk '/ldlm_cancel/ {print $2}')
11411         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11412                awk '/ldlm_bl_callback/ {print $2}')
11413         test_mkdir -i0 -c1 $DIR/$tdir/d1
11414         can2=$(do_facet mds1 \
11415                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11416                awk '/ldlm_cancel/ {print $2}')
11417         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11418                awk '/ldlm_bl_callback/ {print $2}')
11419         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11420         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11421         lru_resize_enable mdc
11422         lru_resize_enable osc
11423 }
11424 run_test 120a "Early Lock Cancel: mkdir test"
11425
11426 test_120b() {
11427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11428         remote_mds_nodsh && skip "remote MDS with nodsh"
11429         test_mkdir $DIR/$tdir
11430         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11431                 skip_env "no early lock cancel on server"
11432
11433         lru_resize_disable mdc
11434         lru_resize_disable osc
11435         cancel_lru_locks mdc
11436         stat $DIR/$tdir > /dev/null
11437         can1=$(do_facet $SINGLEMDS \
11438                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11439                awk '/ldlm_cancel/ {print $2}')
11440         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11441                awk '/ldlm_bl_callback/ {print $2}')
11442         touch $DIR/$tdir/f1
11443         can2=$(do_facet $SINGLEMDS \
11444                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11445                awk '/ldlm_cancel/ {print $2}')
11446         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11447                awk '/ldlm_bl_callback/ {print $2}')
11448         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11449         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11450         lru_resize_enable mdc
11451         lru_resize_enable osc
11452 }
11453 run_test 120b "Early Lock Cancel: create test"
11454
11455 test_120c() {
11456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11457         remote_mds_nodsh && skip "remote MDS with nodsh"
11458         test_mkdir -i0 -c1 $DIR/$tdir
11459         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11460                 skip "no early lock cancel on server"
11461
11462         lru_resize_disable mdc
11463         lru_resize_disable osc
11464         test_mkdir -i0 -c1 $DIR/$tdir/d1
11465         test_mkdir -i0 -c1 $DIR/$tdir/d2
11466         touch $DIR/$tdir/d1/f1
11467         cancel_lru_locks mdc
11468         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11469         can1=$(do_facet mds1 \
11470                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11471                awk '/ldlm_cancel/ {print $2}')
11472         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11473                awk '/ldlm_bl_callback/ {print $2}')
11474         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11475         can2=$(do_facet mds1 \
11476                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11477                awk '/ldlm_cancel/ {print $2}')
11478         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11479                awk '/ldlm_bl_callback/ {print $2}')
11480         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11481         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11482         lru_resize_enable mdc
11483         lru_resize_enable osc
11484 }
11485 run_test 120c "Early Lock Cancel: link test"
11486
11487 test_120d() {
11488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11489         remote_mds_nodsh && skip "remote MDS with nodsh"
11490         test_mkdir -i0 -c1 $DIR/$tdir
11491         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11492                 skip_env "no early lock cancel on server"
11493
11494         lru_resize_disable mdc
11495         lru_resize_disable osc
11496         touch $DIR/$tdir
11497         cancel_lru_locks mdc
11498         stat $DIR/$tdir > /dev/null
11499         can1=$(do_facet mds1 \
11500                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11501                awk '/ldlm_cancel/ {print $2}')
11502         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11503                awk '/ldlm_bl_callback/ {print $2}')
11504         chmod a+x $DIR/$tdir
11505         can2=$(do_facet mds1 \
11506                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11507                awk '/ldlm_cancel/ {print $2}')
11508         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11509                awk '/ldlm_bl_callback/ {print $2}')
11510         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11511         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11512         lru_resize_enable mdc
11513         lru_resize_enable osc
11514 }
11515 run_test 120d "Early Lock Cancel: setattr test"
11516
11517 test_120e() {
11518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11519         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11520                 skip_env "no early lock cancel on server"
11521         remote_mds_nodsh && skip "remote MDS with nodsh"
11522
11523         local dlmtrace_set=false
11524
11525         test_mkdir -i0 -c1 $DIR/$tdir
11526         lru_resize_disable mdc
11527         lru_resize_disable osc
11528         ! $LCTL get_param debug | grep -q dlmtrace &&
11529                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11530         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11531         cancel_lru_locks mdc
11532         cancel_lru_locks osc
11533         dd if=$DIR/$tdir/f1 of=/dev/null
11534         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11535         # XXX client can not do early lock cancel of OST lock
11536         # during unlink (LU-4206), so cancel osc lock now.
11537         sleep 2
11538         cancel_lru_locks osc
11539         can1=$(do_facet mds1 \
11540                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11541                awk '/ldlm_cancel/ {print $2}')
11542         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11543                awk '/ldlm_bl_callback/ {print $2}')
11544         unlink $DIR/$tdir/f1
11545         sleep 5
11546         can2=$(do_facet mds1 \
11547                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11548                awk '/ldlm_cancel/ {print $2}')
11549         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11550                awk '/ldlm_bl_callback/ {print $2}')
11551         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11552                 $LCTL dk $TMP/cancel.debug.txt
11553         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11554                 $LCTL dk $TMP/blocking.debug.txt
11555         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11556         lru_resize_enable mdc
11557         lru_resize_enable osc
11558 }
11559 run_test 120e "Early Lock Cancel: unlink test"
11560
11561 test_120f() {
11562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11563         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11564                 skip_env "no early lock cancel on server"
11565         remote_mds_nodsh && skip "remote MDS with nodsh"
11566
11567         test_mkdir -i0 -c1 $DIR/$tdir
11568         lru_resize_disable mdc
11569         lru_resize_disable osc
11570         test_mkdir -i0 -c1 $DIR/$tdir/d1
11571         test_mkdir -i0 -c1 $DIR/$tdir/d2
11572         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11573         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11574         cancel_lru_locks mdc
11575         cancel_lru_locks osc
11576         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11577         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11578         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11579         # XXX client can not do early lock cancel of OST lock
11580         # during rename (LU-4206), so cancel osc lock now.
11581         sleep 2
11582         cancel_lru_locks osc
11583         can1=$(do_facet mds1 \
11584                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11585                awk '/ldlm_cancel/ {print $2}')
11586         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11587                awk '/ldlm_bl_callback/ {print $2}')
11588         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11589         sleep 5
11590         can2=$(do_facet mds1 \
11591                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11592                awk '/ldlm_cancel/ {print $2}')
11593         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11594                awk '/ldlm_bl_callback/ {print $2}')
11595         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11596         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11597         lru_resize_enable mdc
11598         lru_resize_enable osc
11599 }
11600 run_test 120f "Early Lock Cancel: rename test"
11601
11602 test_120g() {
11603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11604         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11605                 skip_env "no early lock cancel on server"
11606         remote_mds_nodsh && skip "remote MDS with nodsh"
11607
11608         lru_resize_disable mdc
11609         lru_resize_disable osc
11610         count=10000
11611         echo create $count files
11612         test_mkdir $DIR/$tdir
11613         cancel_lru_locks mdc
11614         cancel_lru_locks osc
11615         t0=$(date +%s)
11616
11617         can0=$(do_facet $SINGLEMDS \
11618                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11619                awk '/ldlm_cancel/ {print $2}')
11620         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11621                awk '/ldlm_bl_callback/ {print $2}')
11622         createmany -o $DIR/$tdir/f $count
11623         sync
11624         can1=$(do_facet $SINGLEMDS \
11625                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11626                awk '/ldlm_cancel/ {print $2}')
11627         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11628                awk '/ldlm_bl_callback/ {print $2}')
11629         t1=$(date +%s)
11630         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11631         echo rm $count files
11632         rm -r $DIR/$tdir
11633         sync
11634         can2=$(do_facet $SINGLEMDS \
11635                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11636                awk '/ldlm_cancel/ {print $2}')
11637         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11638                awk '/ldlm_bl_callback/ {print $2}')
11639         t2=$(date +%s)
11640         echo total: $count removes in $((t2-t1))
11641         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11642         sleep 2
11643         # wait for commitment of removal
11644         lru_resize_enable mdc
11645         lru_resize_enable osc
11646 }
11647 run_test 120g "Early Lock Cancel: performance test"
11648
11649 test_121() { #bug #10589
11650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11651
11652         rm -rf $DIR/$tfile
11653         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11654 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11655         lctl set_param fail_loc=0x310
11656         cancel_lru_locks osc > /dev/null
11657         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11658         lctl set_param fail_loc=0
11659         [[ $reads -eq $writes ]] ||
11660                 error "read $reads blocks, must be $writes blocks"
11661 }
11662 run_test 121 "read cancel race ========="
11663
11664 test_123a_base() { # was test 123, statahead(bug 11401)
11665         local lsx="$1"
11666
11667         SLOWOK=0
11668         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11669                 log "testing UP system. Performance may be lower than expected."
11670                 SLOWOK=1
11671         fi
11672
11673         rm -rf $DIR/$tdir
11674         test_mkdir $DIR/$tdir
11675         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11676         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11677         MULT=10
11678         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11679                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11680
11681                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11682                 lctl set_param -n llite.*.statahead_max 0
11683                 lctl get_param llite.*.statahead_max
11684                 cancel_lru_locks mdc
11685                 cancel_lru_locks osc
11686                 stime=$(date +%s)
11687                 time $lsx $DIR/$tdir | wc -l
11688                 etime=$(date +%s)
11689                 delta=$((etime - stime))
11690                 log "$lsx $i files without statahead: $delta sec"
11691                 lctl set_param llite.*.statahead_max=$max
11692
11693                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11694                         grep "statahead wrong:" | awk '{print $3}')
11695                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11696                 cancel_lru_locks mdc
11697                 cancel_lru_locks osc
11698                 stime=$(date +%s)
11699                 time $lsx $DIR/$tdir | wc -l
11700                 etime=$(date +%s)
11701                 delta_sa=$((etime - stime))
11702                 log "$lsx $i files with statahead: $delta_sa sec"
11703                 lctl get_param -n llite.*.statahead_stats
11704                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11705                         grep "statahead wrong:" | awk '{print $3}')
11706
11707                 [[ $swrong -lt $ewrong ]] &&
11708                         log "statahead was stopped, maybe too many locks held!"
11709                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11710
11711                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11712                         max=$(lctl get_param -n llite.*.statahead_max |
11713                                 head -n 1)
11714                         lctl set_param -n llite.*.statahead_max 0
11715                         lctl get_param llite.*.statahead_max
11716                         cancel_lru_locks mdc
11717                         cancel_lru_locks osc
11718                         stime=$(date +%s)
11719                         time $lsx $DIR/$tdir | wc -l
11720                         etime=$(date +%s)
11721                         delta=$((etime - stime))
11722                         log "$lsx $i files again without statahead: $delta sec"
11723                         lctl set_param llite.*.statahead_max=$max
11724                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11725                                 if [  $SLOWOK -eq 0 ]; then
11726                                         error "$lsx $i files is slower with statahead!"
11727                                 else
11728                                         log "$lsx $i files is slower with statahead!"
11729                                 fi
11730                                 break
11731                         fi
11732                 fi
11733
11734                 [ $delta -gt 20 ] && break
11735                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11736                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11737         done
11738         log "$lsx done"
11739
11740         stime=$(date +%s)
11741         rm -r $DIR/$tdir
11742         sync
11743         etime=$(date +%s)
11744         delta=$((etime - stime))
11745         log "rm -r $DIR/$tdir/: $delta seconds"
11746         log "rm done"
11747         lctl get_param -n llite.*.statahead_stats
11748 }
11749
11750 test_123aa() {
11751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11752
11753         test_123a_base "ls -l"
11754 }
11755 run_test 123aa "verify statahead work"
11756
11757 test_123ab() {
11758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11759
11760         statx_supported || skip_env "Test must be statx() syscall supported"
11761
11762         test_123a_base "$STATX -l"
11763 }
11764 run_test 123ab "verify statahead work by using statx"
11765
11766 test_123ac() {
11767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11768
11769         statx_supported || skip_env "Test must be statx() syscall supported"
11770
11771         local rpcs_before
11772         local rpcs_after
11773         local agl_before
11774         local agl_after
11775
11776         cancel_lru_locks $OSC
11777         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11778         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11779                 awk '/agl.total:/ {print $3}')
11780         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11781         test_123a_base "$STATX --cached=always -D"
11782         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11783                 awk '/agl.total:/ {print $3}')
11784         [ $agl_before -eq $agl_after ] ||
11785                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11786         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11787         [ $rpcs_after -eq $rpcs_before ] ||
11788                 error "$STATX should not send glimpse RPCs to $OSC"
11789 }
11790 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11791
11792 test_123b () { # statahead(bug 15027)
11793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11794
11795         test_mkdir $DIR/$tdir
11796         createmany -o $DIR/$tdir/$tfile-%d 1000
11797
11798         cancel_lru_locks mdc
11799         cancel_lru_locks osc
11800
11801 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11802         lctl set_param fail_loc=0x80000803
11803         ls -lR $DIR/$tdir > /dev/null
11804         log "ls done"
11805         lctl set_param fail_loc=0x0
11806         lctl get_param -n llite.*.statahead_stats
11807         rm -r $DIR/$tdir
11808         sync
11809
11810 }
11811 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11812
11813 test_123c() {
11814         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11815
11816         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11817         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11818         touch $DIR/$tdir.1/{1..3}
11819         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11820
11821         remount_client $MOUNT
11822
11823         $MULTIOP $DIR/$tdir.0 Q
11824
11825         # let statahead to complete
11826         ls -l $DIR/$tdir.0 > /dev/null
11827
11828         testid=$(echo $TESTNAME | tr '_' ' ')
11829         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11830                 error "statahead warning" || true
11831 }
11832 run_test 123c "Can not initialize inode warning on DNE statahead"
11833
11834 test_124a() {
11835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11836         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11837                 skip_env "no lru resize on server"
11838
11839         local NR=2000
11840
11841         test_mkdir $DIR/$tdir
11842
11843         log "create $NR files at $DIR/$tdir"
11844         createmany -o $DIR/$tdir/f $NR ||
11845                 error "failed to create $NR files in $DIR/$tdir"
11846
11847         cancel_lru_locks mdc
11848         ls -l $DIR/$tdir > /dev/null
11849
11850         local NSDIR=""
11851         local LRU_SIZE=0
11852         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11853                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11854                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11855                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11856                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11857                         log "NSDIR=$NSDIR"
11858                         log "NS=$(basename $NSDIR)"
11859                         break
11860                 fi
11861         done
11862
11863         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11864                 skip "Not enough cached locks created!"
11865         fi
11866         log "LRU=$LRU_SIZE"
11867
11868         local SLEEP=30
11869
11870         # We know that lru resize allows one client to hold $LIMIT locks
11871         # for 10h. After that locks begin to be killed by client.
11872         local MAX_HRS=10
11873         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11874         log "LIMIT=$LIMIT"
11875         if [ $LIMIT -lt $LRU_SIZE ]; then
11876                 skip "Limit is too small $LIMIT"
11877         fi
11878
11879         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11880         # killing locks. Some time was spent for creating locks. This means
11881         # that up to the moment of sleep finish we must have killed some of
11882         # them (10-100 locks). This depends on how fast ther were created.
11883         # Many of them were touched in almost the same moment and thus will
11884         # be killed in groups.
11885         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11886
11887         # Use $LRU_SIZE_B here to take into account real number of locks
11888         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11889         local LRU_SIZE_B=$LRU_SIZE
11890         log "LVF=$LVF"
11891         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11892         log "OLD_LVF=$OLD_LVF"
11893         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11894
11895         # Let's make sure that we really have some margin. Client checks
11896         # cached locks every 10 sec.
11897         SLEEP=$((SLEEP+20))
11898         log "Sleep ${SLEEP} sec"
11899         local SEC=0
11900         while ((SEC<$SLEEP)); do
11901                 echo -n "..."
11902                 sleep 5
11903                 SEC=$((SEC+5))
11904                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11905                 echo -n "$LRU_SIZE"
11906         done
11907         echo ""
11908         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11909         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11910
11911         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11912                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11913                 unlinkmany $DIR/$tdir/f $NR
11914                 return
11915         }
11916
11917         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11918         log "unlink $NR files at $DIR/$tdir"
11919         unlinkmany $DIR/$tdir/f $NR
11920 }
11921 run_test 124a "lru resize ======================================="
11922
11923 get_max_pool_limit()
11924 {
11925         local limit=$($LCTL get_param \
11926                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11927         local max=0
11928         for l in $limit; do
11929                 if [[ $l -gt $max ]]; then
11930                         max=$l
11931                 fi
11932         done
11933         echo $max
11934 }
11935
11936 test_124b() {
11937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11938         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11939                 skip_env "no lru resize on server"
11940
11941         LIMIT=$(get_max_pool_limit)
11942
11943         NR=$(($(default_lru_size)*20))
11944         if [[ $NR -gt $LIMIT ]]; then
11945                 log "Limit lock number by $LIMIT locks"
11946                 NR=$LIMIT
11947         fi
11948
11949         IFree=$(mdsrate_inodes_available)
11950         if [ $IFree -lt $NR ]; then
11951                 log "Limit lock number by $IFree inodes"
11952                 NR=$IFree
11953         fi
11954
11955         lru_resize_disable mdc
11956         test_mkdir -p $DIR/$tdir/disable_lru_resize
11957
11958         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11959         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11960         cancel_lru_locks mdc
11961         stime=`date +%s`
11962         PID=""
11963         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11964         PID="$PID $!"
11965         sleep 2
11966         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11967         PID="$PID $!"
11968         sleep 2
11969         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11970         PID="$PID $!"
11971         wait $PID
11972         etime=`date +%s`
11973         nolruresize_delta=$((etime-stime))
11974         log "ls -la time: $nolruresize_delta seconds"
11975         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11976         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11977
11978         lru_resize_enable mdc
11979         test_mkdir -p $DIR/$tdir/enable_lru_resize
11980
11981         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11982         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11983         cancel_lru_locks mdc
11984         stime=`date +%s`
11985         PID=""
11986         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11987         PID="$PID $!"
11988         sleep 2
11989         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11990         PID="$PID $!"
11991         sleep 2
11992         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11993         PID="$PID $!"
11994         wait $PID
11995         etime=`date +%s`
11996         lruresize_delta=$((etime-stime))
11997         log "ls -la time: $lruresize_delta seconds"
11998         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11999
12000         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12001                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12002         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12003                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12004         else
12005                 log "lru resize performs the same with no lru resize"
12006         fi
12007         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12008 }
12009 run_test 124b "lru resize (performance test) ======================="
12010
12011 test_124c() {
12012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12013         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12014                 skip_env "no lru resize on server"
12015
12016         # cache ununsed locks on client
12017         local nr=100
12018         cancel_lru_locks mdc
12019         test_mkdir $DIR/$tdir
12020         createmany -o $DIR/$tdir/f $nr ||
12021                 error "failed to create $nr files in $DIR/$tdir"
12022         ls -l $DIR/$tdir > /dev/null
12023
12024         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12025         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12026         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12027         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12028         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12029
12030         # set lru_max_age to 1 sec
12031         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12032         echo "sleep $((recalc_p * 2)) seconds..."
12033         sleep $((recalc_p * 2))
12034
12035         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12036         # restore lru_max_age
12037         $LCTL set_param -n $nsdir.lru_max_age $max_age
12038         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12039         unlinkmany $DIR/$tdir/f $nr
12040 }
12041 run_test 124c "LRUR cancel very aged locks"
12042
12043 test_124d() {
12044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12045         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12046                 skip_env "no lru resize on server"
12047
12048         # cache ununsed locks on client
12049         local nr=100
12050
12051         lru_resize_disable mdc
12052         stack_trap "lru_resize_enable mdc" EXIT
12053
12054         cancel_lru_locks mdc
12055
12056         # asynchronous object destroy at MDT could cause bl ast to client
12057         test_mkdir $DIR/$tdir
12058         createmany -o $DIR/$tdir/f $nr ||
12059                 error "failed to create $nr files in $DIR/$tdir"
12060         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12061
12062         ls -l $DIR/$tdir > /dev/null
12063
12064         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12065         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12066         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12067         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12068
12069         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12070
12071         # set lru_max_age to 1 sec
12072         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12073         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12074
12075         echo "sleep $((recalc_p * 2)) seconds..."
12076         sleep $((recalc_p * 2))
12077
12078         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12079
12080         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12081 }
12082 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12083
12084 test_125() { # 13358
12085         $LCTL get_param -n llite.*.client_type | grep -q local ||
12086                 skip "must run as local client"
12087         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12088                 skip_env "must have acl enabled"
12089         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12090
12091         test_mkdir $DIR/$tdir
12092         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12093         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12094         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12095 }
12096 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12097
12098 test_126() { # bug 12829/13455
12099         $GSS && skip_env "must run as gss disabled"
12100         $LCTL get_param -n llite.*.client_type | grep -q local ||
12101                 skip "must run as local client"
12102         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12103
12104         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12105         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12106         rm -f $DIR/$tfile
12107         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12108 }
12109 run_test 126 "check that the fsgid provided by the client is taken into account"
12110
12111 test_127a() { # bug 15521
12112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12113         local name count samp unit min max sum sumsq
12114
12115         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12116         echo "stats before reset"
12117         $LCTL get_param osc.*.stats
12118         $LCTL set_param osc.*.stats=0
12119         local fsize=$((2048 * 1024))
12120
12121         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12122         cancel_lru_locks osc
12123         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12124
12125         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12126         stack_trap "rm -f $TMP/$tfile.tmp"
12127         while read name count samp unit min max sum sumsq; do
12128                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12129                 [ ! $min ] && error "Missing min value for $name proc entry"
12130                 eval $name=$count || error "Wrong proc format"
12131
12132                 case $name in
12133                 read_bytes|write_bytes)
12134                         [[ "$unit" =~ "bytes" ]] ||
12135                                 error "unit is not 'bytes': $unit"
12136                         (( $min >= 4096 )) || error "min is too small: $min"
12137                         (( $min <= $fsize )) || error "min is too big: $min"
12138                         (( $max >= 4096 )) || error "max is too small: $max"
12139                         (( $max <= $fsize )) || error "max is too big: $max"
12140                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12141                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12142                                 error "sumsquare is too small: $sumsq"
12143                         (( $sumsq <= $fsize * $fsize )) ||
12144                                 error "sumsquare is too big: $sumsq"
12145                         ;;
12146                 ost_read|ost_write)
12147                         [[ "$unit" =~ "usec" ]] ||
12148                                 error "unit is not 'usec': $unit"
12149                         ;;
12150                 *)      ;;
12151                 esac
12152         done < $DIR/$tfile.tmp
12153
12154         #check that we actually got some stats
12155         [ "$read_bytes" ] || error "Missing read_bytes stats"
12156         [ "$write_bytes" ] || error "Missing write_bytes stats"
12157         [ "$read_bytes" != 0 ] || error "no read done"
12158         [ "$write_bytes" != 0 ] || error "no write done"
12159 }
12160 run_test 127a "verify the client stats are sane"
12161
12162 test_127b() { # bug LU-333
12163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12164         local name count samp unit min max sum sumsq
12165
12166         echo "stats before reset"
12167         $LCTL get_param llite.*.stats
12168         $LCTL set_param llite.*.stats=0
12169
12170         # perform 2 reads and writes so MAX is different from SUM.
12171         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12172         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12173         cancel_lru_locks osc
12174         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12175         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12176
12177         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12178         stack_trap "rm -f $TMP/$tfile.tmp"
12179         while read name count samp unit min max sum sumsq; do
12180                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12181                 eval $name=$count || error "Wrong proc format"
12182
12183                 case $name in
12184                 read_bytes|write_bytes)
12185                         [[ "$unit" =~ "bytes" ]] ||
12186                                 error "unit is not 'bytes': $unit"
12187                         (( $count == 2 )) || error "count is not 2: $count"
12188                         (( $min == $PAGE_SIZE )) ||
12189                                 error "min is not $PAGE_SIZE: $min"
12190                         (( $max == $PAGE_SIZE )) ||
12191                                 error "max is not $PAGE_SIZE: $max"
12192                         (( $sum == $PAGE_SIZE * 2 )) ||
12193                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12194                         ;;
12195                 read|write)
12196                         [[ "$unit" =~ "usec" ]] ||
12197                                 error "unit is not 'usec': $unit"
12198                         ;;
12199                 *)      ;;
12200                 esac
12201         done < $TMP/$tfile.tmp
12202
12203         #check that we actually got some stats
12204         [ "$read_bytes" ] || error "Missing read_bytes stats"
12205         [ "$write_bytes" ] || error "Missing write_bytes stats"
12206         [ "$read_bytes" != 0 ] || error "no read done"
12207         [ "$write_bytes" != 0 ] || error "no write done"
12208 }
12209 run_test 127b "verify the llite client stats are sane"
12210
12211 test_127c() { # LU-12394
12212         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12213         local size
12214         local bsize
12215         local reads
12216         local writes
12217         local count
12218
12219         $LCTL set_param llite.*.extents_stats=1
12220         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12221
12222         # Use two stripes so there is enough space in default config
12223         $LFS setstripe -c 2 $DIR/$tfile
12224
12225         # Extent stats start at 0-4K and go in power of two buckets
12226         # LL_HIST_START = 12 --> 2^12 = 4K
12227         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12228         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12229         # small configs
12230         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12231                 do
12232                 # Write and read, 2x each, second time at a non-zero offset
12233                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12234                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12235                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12236                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12237                 rm -f $DIR/$tfile
12238         done
12239
12240         $LCTL get_param llite.*.extents_stats
12241
12242         count=2
12243         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12244                 do
12245                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12246                                 grep -m 1 $bsize)
12247                 reads=$(echo $bucket | awk '{print $5}')
12248                 writes=$(echo $bucket | awk '{print $9}')
12249                 [ "$reads" -eq $count ] ||
12250                         error "$reads reads in < $bsize bucket, expect $count"
12251                 [ "$writes" -eq $count ] ||
12252                         error "$writes writes in < $bsize bucket, expect $count"
12253         done
12254
12255         # Test mmap write and read
12256         $LCTL set_param llite.*.extents_stats=c
12257         size=512
12258         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12259         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12260         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12261
12262         $LCTL get_param llite.*.extents_stats
12263
12264         count=$(((size*1024) / PAGE_SIZE))
12265
12266         bsize=$((2 * PAGE_SIZE / 1024))K
12267
12268         bucket=$($LCTL get_param -n llite.*.extents_stats |
12269                         grep -m 1 $bsize)
12270         reads=$(echo $bucket | awk '{print $5}')
12271         writes=$(echo $bucket | awk '{print $9}')
12272         # mmap writes fault in the page first, creating an additonal read
12273         [ "$reads" -eq $((2 * count)) ] ||
12274                 error "$reads reads in < $bsize bucket, expect $count"
12275         [ "$writes" -eq $count ] ||
12276                 error "$writes writes in < $bsize bucket, expect $count"
12277 }
12278 run_test 127c "test llite extent stats with regular & mmap i/o"
12279
12280 test_128() { # bug 15212
12281         touch $DIR/$tfile
12282         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12283                 find $DIR/$tfile
12284                 find $DIR/$tfile
12285         EOF
12286
12287         result=$(grep error $TMP/$tfile.log)
12288         rm -f $DIR/$tfile $TMP/$tfile.log
12289         [ -z "$result" ] ||
12290                 error "consecutive find's under interactive lfs failed"
12291 }
12292 run_test 128 "interactive lfs for 2 consecutive find's"
12293
12294 set_dir_limits () {
12295         local mntdev
12296         local canondev
12297         local node
12298
12299         local ldproc=/proc/fs/ldiskfs
12300         local facets=$(get_facets MDS)
12301
12302         for facet in ${facets//,/ }; do
12303                 canondev=$(ldiskfs_canon \
12304                            *.$(convert_facet2label $facet).mntdev $facet)
12305                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12306                         ldproc=/sys/fs/ldiskfs
12307                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12308                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12309         done
12310 }
12311
12312 check_mds_dmesg() {
12313         local facets=$(get_facets MDS)
12314         for facet in ${facets//,/ }; do
12315                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12316         done
12317         return 1
12318 }
12319
12320 test_129() {
12321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12322         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12323                 skip "Need MDS version with at least 2.5.56"
12324         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12325                 skip_env "ldiskfs only test"
12326         fi
12327         remote_mds_nodsh && skip "remote MDS with nodsh"
12328
12329         local ENOSPC=28
12330         local has_warning=false
12331
12332         rm -rf $DIR/$tdir
12333         mkdir -p $DIR/$tdir
12334
12335         # block size of mds1
12336         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12337         set_dir_limits $maxsize $((maxsize * 6 / 8))
12338         stack_trap "set_dir_limits 0 0"
12339         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12340         local dirsize=$(stat -c%s "$DIR/$tdir")
12341         local nfiles=0
12342         while (( $dirsize <= $maxsize )); do
12343                 $MCREATE $DIR/$tdir/file_base_$nfiles
12344                 rc=$?
12345                 # check two errors:
12346                 # ENOSPC for ext4 max_dir_size, which has been used since
12347                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12348                 if (( rc == ENOSPC )); then
12349                         set_dir_limits 0 0
12350                         echo "rc=$rc returned as expected after $nfiles files"
12351
12352                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12353                                 error "create failed w/o dir size limit"
12354
12355                         # messages may be rate limited if test is run repeatedly
12356                         check_mds_dmesg '"is approaching max"' ||
12357                                 echo "warning message should be output"
12358                         check_mds_dmesg '"has reached max"' ||
12359                                 echo "reached message should be output"
12360
12361                         dirsize=$(stat -c%s "$DIR/$tdir")
12362
12363                         [[ $dirsize -ge $maxsize ]] && return 0
12364                         error "dirsize $dirsize < $maxsize after $nfiles files"
12365                 elif (( rc != 0 )); then
12366                         break
12367                 fi
12368                 nfiles=$((nfiles + 1))
12369                 dirsize=$(stat -c%s "$DIR/$tdir")
12370         done
12371
12372         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12373 }
12374 run_test 129 "test directory size limit ========================"
12375
12376 OLDIFS="$IFS"
12377 cleanup_130() {
12378         trap 0
12379         IFS="$OLDIFS"
12380 }
12381
12382 test_130a() {
12383         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12384         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12385
12386         trap cleanup_130 EXIT RETURN
12387
12388         local fm_file=$DIR/$tfile
12389         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12390         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12391                 error "dd failed for $fm_file"
12392
12393         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12394         filefrag -ves $fm_file
12395         RC=$?
12396         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12397                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12398         [ $RC != 0 ] && error "filefrag $fm_file failed"
12399
12400         filefrag_op=$(filefrag -ve -k $fm_file |
12401                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12402         lun=$($LFS getstripe -i $fm_file)
12403
12404         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12405         IFS=$'\n'
12406         tot_len=0
12407         for line in $filefrag_op
12408         do
12409                 frag_lun=`echo $line | cut -d: -f5`
12410                 ext_len=`echo $line | cut -d: -f4`
12411                 if (( $frag_lun != $lun )); then
12412                         cleanup_130
12413                         error "FIEMAP on 1-stripe file($fm_file) failed"
12414                         return
12415                 fi
12416                 (( tot_len += ext_len ))
12417         done
12418
12419         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12420                 cleanup_130
12421                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12422                 return
12423         fi
12424
12425         cleanup_130
12426
12427         echo "FIEMAP on single striped file succeeded"
12428 }
12429 run_test 130a "FIEMAP (1-stripe file)"
12430
12431 test_130b() {
12432         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12433
12434         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12435         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12436
12437         trap cleanup_130 EXIT RETURN
12438
12439         local fm_file=$DIR/$tfile
12440         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12441                         error "setstripe on $fm_file"
12442         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12443                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12444
12445         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12446                 error "dd failed on $fm_file"
12447
12448         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12449         filefrag_op=$(filefrag -ve -k $fm_file |
12450                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12451
12452         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12453                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12454
12455         IFS=$'\n'
12456         tot_len=0
12457         num_luns=1
12458         for line in $filefrag_op
12459         do
12460                 frag_lun=$(echo $line | cut -d: -f5 |
12461                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12462                 ext_len=$(echo $line | cut -d: -f4)
12463                 if (( $frag_lun != $last_lun )); then
12464                         if (( tot_len != 1024 )); then
12465                                 cleanup_130
12466                                 error "FIEMAP on $fm_file failed; returned " \
12467                                 "len $tot_len for OST $last_lun instead of 1024"
12468                                 return
12469                         else
12470                                 (( num_luns += 1 ))
12471                                 tot_len=0
12472                         fi
12473                 fi
12474                 (( tot_len += ext_len ))
12475                 last_lun=$frag_lun
12476         done
12477         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12478                 cleanup_130
12479                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12480                         "luns or wrong len for OST $last_lun"
12481                 return
12482         fi
12483
12484         cleanup_130
12485
12486         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12487 }
12488 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12489
12490 test_130c() {
12491         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12492
12493         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12494         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12495
12496         trap cleanup_130 EXIT RETURN
12497
12498         local fm_file=$DIR/$tfile
12499         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12500         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12501                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12502
12503         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12504                         error "dd failed on $fm_file"
12505
12506         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12507         filefrag_op=$(filefrag -ve -k $fm_file |
12508                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12509
12510         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12511                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12512
12513         IFS=$'\n'
12514         tot_len=0
12515         num_luns=1
12516         for line in $filefrag_op
12517         do
12518                 frag_lun=$(echo $line | cut -d: -f5 |
12519                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12520                 ext_len=$(echo $line | cut -d: -f4)
12521                 if (( $frag_lun != $last_lun )); then
12522                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12523                         if (( logical != 512 )); then
12524                                 cleanup_130
12525                                 error "FIEMAP on $fm_file failed; returned " \
12526                                 "logical start for lun $logical instead of 512"
12527                                 return
12528                         fi
12529                         if (( tot_len != 512 )); then
12530                                 cleanup_130
12531                                 error "FIEMAP on $fm_file failed; returned " \
12532                                 "len $tot_len for OST $last_lun instead of 1024"
12533                                 return
12534                         else
12535                                 (( num_luns += 1 ))
12536                                 tot_len=0
12537                         fi
12538                 fi
12539                 (( tot_len += ext_len ))
12540                 last_lun=$frag_lun
12541         done
12542         if (( num_luns != 2 || tot_len != 512 )); then
12543                 cleanup_130
12544                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12545                         "luns or wrong len for OST $last_lun"
12546                 return
12547         fi
12548
12549         cleanup_130
12550
12551         echo "FIEMAP on 2-stripe file with hole succeeded"
12552 }
12553 run_test 130c "FIEMAP (2-stripe file with hole)"
12554
12555 test_130d() {
12556         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12557
12558         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12559         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12560
12561         trap cleanup_130 EXIT RETURN
12562
12563         local fm_file=$DIR/$tfile
12564         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12565                         error "setstripe on $fm_file"
12566         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12567                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12568
12569         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12570         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12571                 error "dd failed on $fm_file"
12572
12573         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12574         filefrag_op=$(filefrag -ve -k $fm_file |
12575                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12576
12577         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12578                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12579
12580         IFS=$'\n'
12581         tot_len=0
12582         num_luns=1
12583         for line in $filefrag_op
12584         do
12585                 frag_lun=$(echo $line | cut -d: -f5 |
12586                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12587                 ext_len=$(echo $line | cut -d: -f4)
12588                 if (( $frag_lun != $last_lun )); then
12589                         if (( tot_len != 1024 )); then
12590                                 cleanup_130
12591                                 error "FIEMAP on $fm_file failed; returned " \
12592                                 "len $tot_len for OST $last_lun instead of 1024"
12593                                 return
12594                         else
12595                                 (( num_luns += 1 ))
12596                                 tot_len=0
12597                         fi
12598                 fi
12599                 (( tot_len += ext_len ))
12600                 last_lun=$frag_lun
12601         done
12602         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12603                 cleanup_130
12604                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12605                         "luns or wrong len for OST $last_lun"
12606                 return
12607         fi
12608
12609         cleanup_130
12610
12611         echo "FIEMAP on N-stripe file succeeded"
12612 }
12613 run_test 130d "FIEMAP (N-stripe file)"
12614
12615 test_130e() {
12616         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12617
12618         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12619         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12620
12621         trap cleanup_130 EXIT RETURN
12622
12623         local fm_file=$DIR/$tfile
12624         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12625         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12626                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12627
12628         NUM_BLKS=512
12629         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12630         for ((i = 0; i < $NUM_BLKS; i++))
12631         do
12632                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12633         done
12634
12635         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12636         filefrag_op=$(filefrag -ve -k $fm_file |
12637                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12638
12639         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12640                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12641
12642         IFS=$'\n'
12643         tot_len=0
12644         num_luns=1
12645         for line in $filefrag_op
12646         do
12647                 frag_lun=$(echo $line | cut -d: -f5 |
12648                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12649                 ext_len=$(echo $line | cut -d: -f4)
12650                 if (( $frag_lun != $last_lun )); then
12651                         if (( tot_len != $EXPECTED_LEN )); then
12652                                 cleanup_130
12653                                 error "FIEMAP on $fm_file failed; returned " \
12654                                 "len $tot_len for OST $last_lun instead " \
12655                                 "of $EXPECTED_LEN"
12656                                 return
12657                         else
12658                                 (( num_luns += 1 ))
12659                                 tot_len=0
12660                         fi
12661                 fi
12662                 (( tot_len += ext_len ))
12663                 last_lun=$frag_lun
12664         done
12665         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12666                 cleanup_130
12667                 error "FIEMAP on $fm_file failed; returned wrong number " \
12668                         "of luns or wrong len for OST $last_lun"
12669                 return
12670         fi
12671
12672         cleanup_130
12673
12674         echo "FIEMAP with continuation calls succeeded"
12675 }
12676 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12677
12678 test_130f() {
12679         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12680         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12681
12682         local fm_file=$DIR/$tfile
12683         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12684                 error "multiop create with lov_delay_create on $fm_file"
12685
12686         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12687         filefrag_extents=$(filefrag -vek $fm_file |
12688                            awk '/extents? found/ { print $2 }')
12689         if [[ "$filefrag_extents" != "0" ]]; then
12690                 error "FIEMAP on $fm_file failed; " \
12691                       "returned $filefrag_extents expected 0"
12692         fi
12693
12694         rm -f $fm_file
12695 }
12696 run_test 130f "FIEMAP (unstriped file)"
12697
12698 # Test for writev/readv
12699 test_131a() {
12700         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12701                 error "writev test failed"
12702         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12703                 error "readv failed"
12704         rm -f $DIR/$tfile
12705 }
12706 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12707
12708 test_131b() {
12709         local fsize=$((524288 + 1048576 + 1572864))
12710         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12711                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12712                         error "append writev test failed"
12713
12714         ((fsize += 1572864 + 1048576))
12715         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12716                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12717                         error "append writev test failed"
12718         rm -f $DIR/$tfile
12719 }
12720 run_test 131b "test append writev"
12721
12722 test_131c() {
12723         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12724         error "NOT PASS"
12725 }
12726 run_test 131c "test read/write on file w/o objects"
12727
12728 test_131d() {
12729         rwv -f $DIR/$tfile -w -n 1 1572864
12730         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12731         if [ "$NOB" != 1572864 ]; then
12732                 error "Short read filed: read $NOB bytes instead of 1572864"
12733         fi
12734         rm -f $DIR/$tfile
12735 }
12736 run_test 131d "test short read"
12737
12738 test_131e() {
12739         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12740         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12741         error "read hitting hole failed"
12742         rm -f $DIR/$tfile
12743 }
12744 run_test 131e "test read hitting hole"
12745
12746 check_stats() {
12747         local facet=$1
12748         local op=$2
12749         local want=${3:-0}
12750         local res
12751
12752         case $facet in
12753         mds*) res=$(do_facet $facet \
12754                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12755                  ;;
12756         ost*) res=$(do_facet $facet \
12757                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12758                  ;;
12759         *) error "Wrong facet '$facet'" ;;
12760         esac
12761         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12762         # if the argument $3 is zero, it means any stat increment is ok.
12763         if [[ $want -gt 0 ]]; then
12764                 local count=$(echo $res | awk '{ print $2 }')
12765                 [[ $count -ne $want ]] &&
12766                         error "The $op counter on $facet is $count, not $want"
12767         fi
12768 }
12769
12770 test_133a() {
12771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12772         remote_ost_nodsh && skip "remote OST with nodsh"
12773         remote_mds_nodsh && skip "remote MDS with nodsh"
12774         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12775                 skip_env "MDS doesn't support rename stats"
12776
12777         local testdir=$DIR/${tdir}/stats_testdir
12778
12779         mkdir -p $DIR/${tdir}
12780
12781         # clear stats.
12782         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12783         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12784
12785         # verify mdt stats first.
12786         mkdir ${testdir} || error "mkdir failed"
12787         check_stats $SINGLEMDS "mkdir" 1
12788         touch ${testdir}/${tfile} || error "touch failed"
12789         check_stats $SINGLEMDS "open" 1
12790         check_stats $SINGLEMDS "close" 1
12791         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12792                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12793                 check_stats $SINGLEMDS "mknod" 2
12794         }
12795         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12796         check_stats $SINGLEMDS "unlink" 1
12797         rm -f ${testdir}/${tfile} || error "file remove failed"
12798         check_stats $SINGLEMDS "unlink" 2
12799
12800         # remove working dir and check mdt stats again.
12801         rmdir ${testdir} || error "rmdir failed"
12802         check_stats $SINGLEMDS "rmdir" 1
12803
12804         local testdir1=$DIR/${tdir}/stats_testdir1
12805         mkdir -p ${testdir}
12806         mkdir -p ${testdir1}
12807         touch ${testdir1}/test1
12808         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12809         check_stats $SINGLEMDS "crossdir_rename" 1
12810
12811         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12812         check_stats $SINGLEMDS "samedir_rename" 1
12813
12814         rm -rf $DIR/${tdir}
12815 }
12816 run_test 133a "Verifying MDT stats ========================================"
12817
12818 test_133b() {
12819         local res
12820
12821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12822         remote_ost_nodsh && skip "remote OST with nodsh"
12823         remote_mds_nodsh && skip "remote MDS with nodsh"
12824
12825         local testdir=$DIR/${tdir}/stats_testdir
12826
12827         mkdir -p ${testdir} || error "mkdir failed"
12828         touch ${testdir}/${tfile} || error "touch failed"
12829         cancel_lru_locks mdc
12830
12831         # clear stats.
12832         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12833         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12834
12835         # extra mdt stats verification.
12836         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12837         check_stats $SINGLEMDS "setattr" 1
12838         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12839         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12840         then            # LU-1740
12841                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12842                 check_stats $SINGLEMDS "getattr" 1
12843         fi
12844         rm -rf $DIR/${tdir}
12845
12846         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12847         # so the check below is not reliable
12848         [ $MDSCOUNT -eq 1 ] || return 0
12849
12850         # Sleep to avoid a cached response.
12851         #define OBD_STATFS_CACHE_SECONDS 1
12852         sleep 2
12853         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12854         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12855         $LFS df || error "lfs failed"
12856         check_stats $SINGLEMDS "statfs" 1
12857
12858         # check aggregated statfs (LU-10018)
12859         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12860                 return 0
12861         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12862                 return 0
12863         sleep 2
12864         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12865         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12866         df $DIR
12867         check_stats $SINGLEMDS "statfs" 1
12868
12869         # We want to check that the client didn't send OST_STATFS to
12870         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12871         # extra care is needed here.
12872         if remote_mds; then
12873                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12874                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12875
12876                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12877                 [ "$res" ] && error "OST got STATFS"
12878         fi
12879
12880         return 0
12881 }
12882 run_test 133b "Verifying extra MDT stats =================================="
12883
12884 test_133c() {
12885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12886         remote_ost_nodsh && skip "remote OST with nodsh"
12887         remote_mds_nodsh && skip "remote MDS with nodsh"
12888
12889         local testdir=$DIR/$tdir/stats_testdir
12890
12891         test_mkdir -p $testdir
12892
12893         # verify obdfilter stats.
12894         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12895         sync
12896         cancel_lru_locks osc
12897         wait_delete_completed
12898
12899         # clear stats.
12900         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12901         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12902
12903         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12904                 error "dd failed"
12905         sync
12906         cancel_lru_locks osc
12907         check_stats ost1 "write" 1
12908
12909         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12910         check_stats ost1 "read" 1
12911
12912         > $testdir/$tfile || error "truncate failed"
12913         check_stats ost1 "punch" 1
12914
12915         rm -f $testdir/$tfile || error "file remove failed"
12916         wait_delete_completed
12917         check_stats ost1 "destroy" 1
12918
12919         rm -rf $DIR/$tdir
12920 }
12921 run_test 133c "Verifying OST stats ========================================"
12922
12923 order_2() {
12924         local value=$1
12925         local orig=$value
12926         local order=1
12927
12928         while [ $value -ge 2 ]; do
12929                 order=$((order*2))
12930                 value=$((value/2))
12931         done
12932
12933         if [ $orig -gt $order ]; then
12934                 order=$((order*2))
12935         fi
12936         echo $order
12937 }
12938
12939 size_in_KMGT() {
12940     local value=$1
12941     local size=('K' 'M' 'G' 'T');
12942     local i=0
12943     local size_string=$value
12944
12945     while [ $value -ge 1024 ]; do
12946         if [ $i -gt 3 ]; then
12947             #T is the biggest unit we get here, if that is bigger,
12948             #just return XXXT
12949             size_string=${value}T
12950             break
12951         fi
12952         value=$((value >> 10))
12953         if [ $value -lt 1024 ]; then
12954             size_string=${value}${size[$i]}
12955             break
12956         fi
12957         i=$((i + 1))
12958     done
12959
12960     echo $size_string
12961 }
12962
12963 get_rename_size() {
12964         local size=$1
12965         local context=${2:-.}
12966         local sample=$(do_facet $SINGLEMDS $LCTL \
12967                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12968                 grep -A1 $context |
12969                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12970         echo $sample
12971 }
12972
12973 test_133d() {
12974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12975         remote_ost_nodsh && skip "remote OST with nodsh"
12976         remote_mds_nodsh && skip "remote MDS with nodsh"
12977         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12978                 skip_env "MDS doesn't support rename stats"
12979
12980         local testdir1=$DIR/${tdir}/stats_testdir1
12981         local testdir2=$DIR/${tdir}/stats_testdir2
12982         mkdir -p $DIR/${tdir}
12983
12984         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12985
12986         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12987         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12988
12989         createmany -o $testdir1/test 512 || error "createmany failed"
12990
12991         # check samedir rename size
12992         mv ${testdir1}/test0 ${testdir1}/test_0
12993
12994         local testdir1_size=$(ls -l $DIR/${tdir} |
12995                 awk '/stats_testdir1/ {print $5}')
12996         local testdir2_size=$(ls -l $DIR/${tdir} |
12997                 awk '/stats_testdir2/ {print $5}')
12998
12999         testdir1_size=$(order_2 $testdir1_size)
13000         testdir2_size=$(order_2 $testdir2_size)
13001
13002         testdir1_size=$(size_in_KMGT $testdir1_size)
13003         testdir2_size=$(size_in_KMGT $testdir2_size)
13004
13005         echo "source rename dir size: ${testdir1_size}"
13006         echo "target rename dir size: ${testdir2_size}"
13007
13008         local cmd="do_facet $SINGLEMDS $LCTL "
13009         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13010
13011         eval $cmd || error "$cmd failed"
13012         local samedir=$($cmd | grep 'same_dir')
13013         local same_sample=$(get_rename_size $testdir1_size)
13014         [ -z "$samedir" ] && error "samedir_rename_size count error"
13015         [[ $same_sample -eq 1 ]] ||
13016                 error "samedir_rename_size error $same_sample"
13017         echo "Check same dir rename stats success"
13018
13019         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13020
13021         # check crossdir rename size
13022         mv ${testdir1}/test_0 ${testdir2}/test_0
13023
13024         testdir1_size=$(ls -l $DIR/${tdir} |
13025                 awk '/stats_testdir1/ {print $5}')
13026         testdir2_size=$(ls -l $DIR/${tdir} |
13027                 awk '/stats_testdir2/ {print $5}')
13028
13029         testdir1_size=$(order_2 $testdir1_size)
13030         testdir2_size=$(order_2 $testdir2_size)
13031
13032         testdir1_size=$(size_in_KMGT $testdir1_size)
13033         testdir2_size=$(size_in_KMGT $testdir2_size)
13034
13035         echo "source rename dir size: ${testdir1_size}"
13036         echo "target rename dir size: ${testdir2_size}"
13037
13038         eval $cmd || error "$cmd failed"
13039         local crossdir=$($cmd | grep 'crossdir')
13040         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13041         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13042         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13043         [[ $src_sample -eq 1 ]] ||
13044                 error "crossdir_rename_size error $src_sample"
13045         [[ $tgt_sample -eq 1 ]] ||
13046                 error "crossdir_rename_size error $tgt_sample"
13047         echo "Check cross dir rename stats success"
13048         rm -rf $DIR/${tdir}
13049 }
13050 run_test 133d "Verifying rename_stats ========================================"
13051
13052 test_133e() {
13053         remote_mds_nodsh && skip "remote MDS with nodsh"
13054         remote_ost_nodsh && skip "remote OST with nodsh"
13055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13056
13057         local testdir=$DIR/${tdir}/stats_testdir
13058         local ctr f0 f1 bs=32768 count=42 sum
13059
13060         mkdir -p ${testdir} || error "mkdir failed"
13061
13062         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13063
13064         for ctr in {write,read}_bytes; do
13065                 sync
13066                 cancel_lru_locks osc
13067
13068                 do_facet ost1 $LCTL set_param -n \
13069                         "obdfilter.*.exports.clear=clear"
13070
13071                 if [ $ctr = write_bytes ]; then
13072                         f0=/dev/zero
13073                         f1=${testdir}/${tfile}
13074                 else
13075                         f0=${testdir}/${tfile}
13076                         f1=/dev/null
13077                 fi
13078
13079                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13080                         error "dd failed"
13081                 sync
13082                 cancel_lru_locks osc
13083
13084                 sum=$(do_facet ost1 $LCTL get_param \
13085                         "obdfilter.*.exports.*.stats" |
13086                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13087                                 $1 == ctr { sum += $7 }
13088                                 END { printf("%0.0f", sum) }')
13089
13090                 if ((sum != bs * count)); then
13091                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13092                 fi
13093         done
13094
13095         rm -rf $DIR/${tdir}
13096 }
13097 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13098
13099 test_133f() {
13100         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13101                 skip "too old lustre for get_param -R ($facet_ver)"
13102
13103         # verifying readability.
13104         $LCTL get_param -R '*' &> /dev/null
13105
13106         # Verifing writability with badarea_io.
13107         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13108                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13109                 error "client badarea_io failed"
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 133f "Check reads/writes of client lustre proc files with bad area io"
13116
13117 test_133g() {
13118         remote_mds_nodsh && skip "remote MDS with nodsh"
13119         remote_ost_nodsh && skip "remote OST with nodsh"
13120
13121         local facet
13122         for facet in mds1 ost1; do
13123                 local facet_ver=$(lustre_version_code $facet)
13124                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13125                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13126                 else
13127                         log "$facet: too old lustre for get_param -R"
13128                 fi
13129                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13130                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13131                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13132                                 xargs badarea_io" ||
13133                                         error "$facet badarea_io failed"
13134                 else
13135                         skip_noexit "$facet: too old lustre for get_param -R"
13136                 fi
13137         done
13138
13139         # remount the FS in case writes/reads /proc break the FS
13140         cleanup || error "failed to unmount"
13141         setup || error "failed to setup"
13142 }
13143 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13144
13145 test_133h() {
13146         remote_mds_nodsh && skip "remote MDS with nodsh"
13147         remote_ost_nodsh && skip "remote OST with nodsh"
13148         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13149                 skip "Need MDS version at least 2.9.54"
13150
13151         local facet
13152         for facet in client mds1 ost1; do
13153                 # Get the list of files that are missing the terminating newline
13154                 local plist=$(do_facet $facet
13155                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13156                 local ent
13157                 for ent in $plist; do
13158                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13159                                 awk -v FS='\v' -v RS='\v\v' \
13160                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13161                                         print FILENAME}'" 2>/dev/null)
13162                         [ -z $missing ] || {
13163                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13164                                 error "file does not end with newline: $facet-$ent"
13165                         }
13166                 done
13167         done
13168 }
13169 run_test 133h "Proc files should end with newlines"
13170
13171 test_134a() {
13172         remote_mds_nodsh && skip "remote MDS with nodsh"
13173         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13174                 skip "Need MDS version at least 2.7.54"
13175
13176         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13177         cancel_lru_locks mdc
13178
13179         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13180         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13181         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13182
13183         local nr=1000
13184         createmany -o $DIR/$tdir/f $nr ||
13185                 error "failed to create $nr files in $DIR/$tdir"
13186         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13187
13188         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13189         do_facet mds1 $LCTL set_param fail_loc=0x327
13190         do_facet mds1 $LCTL set_param fail_val=500
13191         touch $DIR/$tdir/m
13192
13193         echo "sleep 10 seconds ..."
13194         sleep 10
13195         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13196
13197         do_facet mds1 $LCTL set_param fail_loc=0
13198         do_facet mds1 $LCTL set_param fail_val=0
13199         [ $lck_cnt -lt $unused ] ||
13200                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13201
13202         rm $DIR/$tdir/m
13203         unlinkmany $DIR/$tdir/f $nr
13204 }
13205 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13206
13207 test_134b() {
13208         remote_mds_nodsh && skip "remote MDS with nodsh"
13209         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13210                 skip "Need MDS version at least 2.7.54"
13211
13212         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13213         cancel_lru_locks mdc
13214
13215         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13216                         ldlm.lock_reclaim_threshold_mb)
13217         # disable reclaim temporarily
13218         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13219
13220         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13221         do_facet mds1 $LCTL set_param fail_loc=0x328
13222         do_facet mds1 $LCTL set_param fail_val=500
13223
13224         $LCTL set_param debug=+trace
13225
13226         local nr=600
13227         createmany -o $DIR/$tdir/f $nr &
13228         local create_pid=$!
13229
13230         echo "Sleep $TIMEOUT seconds ..."
13231         sleep $TIMEOUT
13232         if ! ps -p $create_pid  > /dev/null 2>&1; then
13233                 do_facet mds1 $LCTL set_param fail_loc=0
13234                 do_facet mds1 $LCTL set_param fail_val=0
13235                 do_facet mds1 $LCTL set_param \
13236                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13237                 error "createmany finished incorrectly!"
13238         fi
13239         do_facet mds1 $LCTL set_param fail_loc=0
13240         do_facet mds1 $LCTL set_param fail_val=0
13241         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13242         wait $create_pid || return 1
13243
13244         unlinkmany $DIR/$tdir/f $nr
13245 }
13246 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13247
13248 test_135() {
13249         remote_mds_nodsh && skip "remote MDS with nodsh"
13250         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13251                 skip "Need MDS version at least 2.13.50"
13252         local fname
13253
13254         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13255
13256 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13257         #set only one record at plain llog
13258         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13259
13260         #fill already existed plain llog each 64767
13261         #wrapping whole catalog
13262         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13263
13264         createmany -o $DIR/$tdir/$tfile_ 64700
13265         for (( i = 0; i < 64700; i = i + 2 ))
13266         do
13267                 rm $DIR/$tdir/$tfile_$i &
13268                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13269                 local pid=$!
13270                 wait $pid
13271         done
13272
13273         #waiting osp synchronization
13274         wait_delete_completed
13275 }
13276 run_test 135 "Race catalog processing"
13277
13278 test_136() {
13279         remote_mds_nodsh && skip "remote MDS with nodsh"
13280         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13281                 skip "Need MDS version at least 2.13.50"
13282         local fname
13283
13284         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13285         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13286         #set only one record at plain llog
13287 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13288         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13289
13290         #fill already existed 2 plain llogs each 64767
13291         #wrapping whole catalog
13292         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13293         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13294         wait_delete_completed
13295
13296         createmany -o $DIR/$tdir/$tfile_ 10
13297         sleep 25
13298
13299         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13300         for (( i = 0; i < 10; i = i + 3 ))
13301         do
13302                 rm $DIR/$tdir/$tfile_$i &
13303                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13304                 local pid=$!
13305                 wait $pid
13306                 sleep 7
13307                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13308         done
13309
13310         #waiting osp synchronization
13311         wait_delete_completed
13312 }
13313 run_test 136 "Race catalog processing 2"
13314
13315 test_140() { #bug-17379
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317
13318         test_mkdir $DIR/$tdir
13319         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13320         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13321
13322         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13323         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13324         local i=0
13325         while i=$((i + 1)); do
13326                 test_mkdir $i
13327                 cd $i || error "Changing to $i"
13328                 ln -s ../stat stat || error "Creating stat symlink"
13329                 # Read the symlink until ELOOP present,
13330                 # not LBUGing the system is considered success,
13331                 # we didn't overrun the stack.
13332                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13333                 if [ $ret -ne 0 ]; then
13334                         if [ $ret -eq 40 ]; then
13335                                 break  # -ELOOP
13336                         else
13337                                 error "Open stat symlink"
13338                                         return
13339                         fi
13340                 fi
13341         done
13342         i=$((i - 1))
13343         echo "The symlink depth = $i"
13344         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13345                 error "Invalid symlink depth"
13346
13347         # Test recursive symlink
13348         ln -s symlink_self symlink_self
13349         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13350         echo "open symlink_self returns $ret"
13351         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13352 }
13353 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13354
13355 test_150a() {
13356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13357
13358         local TF="$TMP/$tfile"
13359
13360         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13361         cp $TF $DIR/$tfile
13362         cancel_lru_locks $OSC
13363         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13364         remount_client $MOUNT
13365         df -P $MOUNT
13366         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13367
13368         $TRUNCATE $TF 6000
13369         $TRUNCATE $DIR/$tfile 6000
13370         cancel_lru_locks $OSC
13371         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13372
13373         echo "12345" >>$TF
13374         echo "12345" >>$DIR/$tfile
13375         cancel_lru_locks $OSC
13376         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13377
13378         echo "12345" >>$TF
13379         echo "12345" >>$DIR/$tfile
13380         cancel_lru_locks $OSC
13381         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13382
13383         rm -f $TF
13384         true
13385 }
13386 run_test 150a "truncate/append tests"
13387
13388 test_150b() {
13389         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13390         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13391                 skip "Need OST version at least 2.13.53"
13392         touch $DIR/$tfile
13393         check_fallocate $DIR/$tfile || error "fallocate failed"
13394 }
13395 run_test 150b "Verify fallocate (prealloc) functionality"
13396
13397 test_150c() {
13398         local bytes
13399         local want
13400
13401         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13402         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13403                 skip "Need OST version at least 2.13.53"
13404
13405         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13406         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13407         sync; sync_all_data
13408         cancel_lru_locks $OSC
13409         sleep 5
13410         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13411         want=$((OSTCOUNT * 1048576))
13412
13413         # Must allocate all requested space, not more than 5% extra
13414         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13415                 error "bytes $bytes is not $want"
13416 }
13417 run_test 150c "Verify fallocate Size and Blocks"
13418
13419 test_150d() {
13420         local bytes
13421         local want
13422
13423         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13424         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13425                 skip "Need OST version at least 2.13.53"
13426
13427         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13428         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13429         sync; sync_all_data
13430         cancel_lru_locks $OSC
13431         sleep 5
13432         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13433         want=$((OSTCOUNT * 1048576))
13434
13435         # Must allocate all requested space, not more than 5% extra
13436         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13437                 error "bytes $bytes is not $want"
13438 }
13439 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13440
13441 test_150e() {
13442         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13443         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13444                 skip "Need OST version at least 2.13.55"
13445
13446         echo "df before:"
13447         $LFS df
13448         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13449                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13450
13451         # Find OST with Minimum Size
13452         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13453                        sort -un | head -1)
13454
13455         # Get 90% of the available space
13456         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13457
13458         fallocate -l${space}k $DIR/$tfile ||
13459                 error "fallocate ${space}k $DIR/$tfile failed"
13460         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13461
13462         # get size immediately after fallocate. This should be correctly
13463         # updated
13464         local size=$(stat -c '%s' $DIR/$tfile)
13465         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13466
13467         # Sleep for a while for statfs to get updated. And not pull from cache.
13468         sleep 2
13469
13470         echo "df after fallocate:"
13471         $LFS df
13472
13473         (( size / 1024 == space )) || error "size $size != requested $space"
13474         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13475                 error "used $used < space $space"
13476
13477         rm $DIR/$tfile || error "rm failed"
13478         sync
13479         wait_delete_completed
13480
13481         echo "df after unlink:"
13482         $LFS df
13483 }
13484 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13485
13486 #LU-2902 roc_hit was not able to read all values from lproc
13487 function roc_hit_init() {
13488         local list=$(comma_list $(osts_nodes))
13489         local dir=$DIR/$tdir-check
13490         local file=$dir/$tfile
13491         local BEFORE
13492         local AFTER
13493         local idx
13494
13495         test_mkdir $dir
13496         #use setstripe to do a write to every ost
13497         for i in $(seq 0 $((OSTCOUNT-1))); do
13498                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13499                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13500                 idx=$(printf %04x $i)
13501                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13502                         awk '$1 == "cache_access" {sum += $7}
13503                                 END { printf("%0.0f", sum) }')
13504
13505                 cancel_lru_locks osc
13506                 cat $file >/dev/null
13507
13508                 AFTER=$(get_osd_param $list *OST*$idx stats |
13509                         awk '$1 == "cache_access" {sum += $7}
13510                                 END { printf("%0.0f", sum) }')
13511
13512                 echo BEFORE:$BEFORE AFTER:$AFTER
13513                 if ! let "AFTER - BEFORE == 4"; then
13514                         rm -rf $dir
13515                         error "roc_hit is not safe to use"
13516                 fi
13517                 rm $file
13518         done
13519
13520         rm -rf $dir
13521 }
13522
13523 function roc_hit() {
13524         local list=$(comma_list $(osts_nodes))
13525         echo $(get_osd_param $list '' stats |
13526                 awk '$1 == "cache_hit" {sum += $7}
13527                         END { printf("%0.0f", sum) }')
13528 }
13529
13530 function set_cache() {
13531         local on=1
13532
13533         if [ "$2" == "off" ]; then
13534                 on=0;
13535         fi
13536         local list=$(comma_list $(osts_nodes))
13537         set_osd_param $list '' $1_cache_enable $on
13538
13539         cancel_lru_locks osc
13540 }
13541
13542 test_151() {
13543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13544         remote_ost_nodsh && skip "remote OST with nodsh"
13545
13546         local CPAGES=3
13547         local list=$(comma_list $(osts_nodes))
13548
13549         # check whether obdfilter is cache capable at all
13550         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13551                 skip "not cache-capable obdfilter"
13552         fi
13553
13554         # check cache is enabled on all obdfilters
13555         if get_osd_param $list '' read_cache_enable | grep 0; then
13556                 skip "oss cache is disabled"
13557         fi
13558
13559         set_osd_param $list '' writethrough_cache_enable 1
13560
13561         # check write cache is enabled on all obdfilters
13562         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13563                 skip "oss write cache is NOT enabled"
13564         fi
13565
13566         roc_hit_init
13567
13568         #define OBD_FAIL_OBD_NO_LRU  0x609
13569         do_nodes $list $LCTL set_param fail_loc=0x609
13570
13571         # pages should be in the case right after write
13572         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13573                 error "dd failed"
13574
13575         local BEFORE=$(roc_hit)
13576         cancel_lru_locks osc
13577         cat $DIR/$tfile >/dev/null
13578         local AFTER=$(roc_hit)
13579
13580         do_nodes $list $LCTL set_param fail_loc=0
13581
13582         if ! let "AFTER - BEFORE == CPAGES"; then
13583                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13584         fi
13585
13586         cancel_lru_locks osc
13587         # invalidates OST cache
13588         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13589         set_osd_param $list '' read_cache_enable 0
13590         cat $DIR/$tfile >/dev/null
13591
13592         # now data shouldn't be found in the cache
13593         BEFORE=$(roc_hit)
13594         cancel_lru_locks osc
13595         cat $DIR/$tfile >/dev/null
13596         AFTER=$(roc_hit)
13597         if let "AFTER - BEFORE != 0"; then
13598                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13599         fi
13600
13601         set_osd_param $list '' read_cache_enable 1
13602         rm -f $DIR/$tfile
13603 }
13604 run_test 151 "test cache on oss and controls ==============================="
13605
13606 test_152() {
13607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13608
13609         local TF="$TMP/$tfile"
13610
13611         # simulate ENOMEM during write
13612 #define OBD_FAIL_OST_NOMEM      0x226
13613         lctl set_param fail_loc=0x80000226
13614         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13615         cp $TF $DIR/$tfile
13616         sync || error "sync failed"
13617         lctl set_param fail_loc=0
13618
13619         # discard client's cache
13620         cancel_lru_locks osc
13621
13622         # simulate ENOMEM during read
13623         lctl set_param fail_loc=0x80000226
13624         cmp $TF $DIR/$tfile || error "cmp failed"
13625         lctl set_param fail_loc=0
13626
13627         rm -f $TF
13628 }
13629 run_test 152 "test read/write with enomem ============================"
13630
13631 test_153() {
13632         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13633 }
13634 run_test 153 "test if fdatasync does not crash ======================="
13635
13636 dot_lustre_fid_permission_check() {
13637         local fid=$1
13638         local ffid=$MOUNT/.lustre/fid/$fid
13639         local test_dir=$2
13640
13641         echo "stat fid $fid"
13642         stat $ffid > /dev/null || error "stat $ffid failed."
13643         echo "touch fid $fid"
13644         touch $ffid || error "touch $ffid failed."
13645         echo "write to fid $fid"
13646         cat /etc/hosts > $ffid || error "write $ffid failed."
13647         echo "read fid $fid"
13648         diff /etc/hosts $ffid || error "read $ffid failed."
13649         echo "append write to fid $fid"
13650         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13651         echo "rename fid $fid"
13652         mv $ffid $test_dir/$tfile.1 &&
13653                 error "rename $ffid to $tfile.1 should fail."
13654         touch $test_dir/$tfile.1
13655         mv $test_dir/$tfile.1 $ffid &&
13656                 error "rename $tfile.1 to $ffid should fail."
13657         rm -f $test_dir/$tfile.1
13658         echo "truncate fid $fid"
13659         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13660         echo "link fid $fid"
13661         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13662         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13663                 echo "setfacl fid $fid"
13664                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13665                 echo "getfacl fid $fid"
13666                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13667         fi
13668         echo "unlink fid $fid"
13669         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13670         echo "mknod fid $fid"
13671         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13672
13673         fid=[0xf00000400:0x1:0x0]
13674         ffid=$MOUNT/.lustre/fid/$fid
13675
13676         echo "stat non-exist fid $fid"
13677         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13678         echo "write to non-exist fid $fid"
13679         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13680         echo "link new fid $fid"
13681         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13682
13683         mkdir -p $test_dir/$tdir
13684         touch $test_dir/$tdir/$tfile
13685         fid=$($LFS path2fid $test_dir/$tdir)
13686         rc=$?
13687         [ $rc -ne 0 ] &&
13688                 error "error: could not get fid for $test_dir/$dir/$tfile."
13689
13690         ffid=$MOUNT/.lustre/fid/$fid
13691
13692         echo "ls $fid"
13693         ls $ffid > /dev/null || error "ls $ffid failed."
13694         echo "touch $fid/$tfile.1"
13695         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13696
13697         echo "touch $MOUNT/.lustre/fid/$tfile"
13698         touch $MOUNT/.lustre/fid/$tfile && \
13699                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13700
13701         echo "setxattr to $MOUNT/.lustre/fid"
13702         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13703
13704         echo "listxattr for $MOUNT/.lustre/fid"
13705         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13706
13707         echo "delxattr from $MOUNT/.lustre/fid"
13708         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13709
13710         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13711         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13712                 error "touch invalid fid should fail."
13713
13714         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13715         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13716                 error "touch non-normal fid should fail."
13717
13718         echo "rename $tdir to $MOUNT/.lustre/fid"
13719         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13720                 error "rename to $MOUNT/.lustre/fid should fail."
13721
13722         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13723         then            # LU-3547
13724                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13725                 local new_obf_mode=777
13726
13727                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13728                 chmod $new_obf_mode $DIR/.lustre/fid ||
13729                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13730
13731                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13732                 [ $obf_mode -eq $new_obf_mode ] ||
13733                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13734
13735                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13736                 chmod $old_obf_mode $DIR/.lustre/fid ||
13737                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13738         fi
13739
13740         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13741         fid=$($LFS path2fid $test_dir/$tfile-2)
13742
13743         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13744         then # LU-5424
13745                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13746                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13747                         error "create lov data thru .lustre failed"
13748         fi
13749         echo "cp /etc/passwd $test_dir/$tfile-2"
13750         cp /etc/passwd $test_dir/$tfile-2 ||
13751                 error "copy to $test_dir/$tfile-2 failed."
13752         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13753         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13754                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13755
13756         rm -rf $test_dir/tfile.lnk
13757         rm -rf $test_dir/$tfile-2
13758 }
13759
13760 test_154A() {
13761         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13762                 skip "Need MDS version at least 2.4.1"
13763
13764         local tf=$DIR/$tfile
13765         touch $tf
13766
13767         local fid=$($LFS path2fid $tf)
13768         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13769
13770         # check that we get the same pathname back
13771         local rootpath
13772         local found
13773         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13774                 echo "$rootpath $fid"
13775                 found=$($LFS fid2path $rootpath "$fid")
13776                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13777                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13778         done
13779
13780         # check wrong root path format
13781         rootpath=$MOUNT"_wrong"
13782         found=$($LFS fid2path $rootpath "$fid")
13783         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13784 }
13785 run_test 154A "lfs path2fid and fid2path basic checks"
13786
13787 test_154B() {
13788         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13789                 skip "Need MDS version at least 2.4.1"
13790
13791         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13792         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13793         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13794         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13795
13796         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13797         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13798
13799         # check that we get the same pathname
13800         echo "PFID: $PFID, name: $name"
13801         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13802         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13803         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13804                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13805
13806         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13807 }
13808 run_test 154B "verify the ll_decode_linkea tool"
13809
13810 test_154a() {
13811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13812         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13813         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13814                 skip "Need MDS version at least 2.2.51"
13815         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13816
13817         cp /etc/hosts $DIR/$tfile
13818
13819         fid=$($LFS path2fid $DIR/$tfile)
13820         rc=$?
13821         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13822
13823         dot_lustre_fid_permission_check "$fid" $DIR ||
13824                 error "dot lustre permission check $fid failed"
13825
13826         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13827
13828         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13829
13830         touch $MOUNT/.lustre/file &&
13831                 error "creation is not allowed under .lustre"
13832
13833         mkdir $MOUNT/.lustre/dir &&
13834                 error "mkdir is not allowed under .lustre"
13835
13836         rm -rf $DIR/$tfile
13837 }
13838 run_test 154a "Open-by-FID"
13839
13840 test_154b() {
13841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13842         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13843         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13844         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13845                 skip "Need MDS version at least 2.2.51"
13846
13847         local remote_dir=$DIR/$tdir/remote_dir
13848         local MDTIDX=1
13849         local rc=0
13850
13851         mkdir -p $DIR/$tdir
13852         $LFS mkdir -i $MDTIDX $remote_dir ||
13853                 error "create remote directory failed"
13854
13855         cp /etc/hosts $remote_dir/$tfile
13856
13857         fid=$($LFS path2fid $remote_dir/$tfile)
13858         rc=$?
13859         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13860
13861         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13862                 error "dot lustre permission check $fid failed"
13863         rm -rf $DIR/$tdir
13864 }
13865 run_test 154b "Open-by-FID for remote directory"
13866
13867 test_154c() {
13868         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13869                 skip "Need MDS version at least 2.4.1"
13870
13871         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13872         local FID1=$($LFS path2fid $DIR/$tfile.1)
13873         local FID2=$($LFS path2fid $DIR/$tfile.2)
13874         local FID3=$($LFS path2fid $DIR/$tfile.3)
13875
13876         local N=1
13877         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13878                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13879                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13880                 local want=FID$N
13881                 [ "$FID" = "${!want}" ] ||
13882                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13883                 N=$((N + 1))
13884         done
13885
13886         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13887         do
13888                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13889                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13890                 N=$((N + 1))
13891         done
13892 }
13893 run_test 154c "lfs path2fid and fid2path multiple arguments"
13894
13895 test_154d() {
13896         remote_mds_nodsh && skip "remote MDS with nodsh"
13897         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13898                 skip "Need MDS version at least 2.5.53"
13899
13900         if remote_mds; then
13901                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13902         else
13903                 nid="0@lo"
13904         fi
13905         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13906         local fd
13907         local cmd
13908
13909         rm -f $DIR/$tfile
13910         touch $DIR/$tfile
13911
13912         local fid=$($LFS path2fid $DIR/$tfile)
13913         # Open the file
13914         fd=$(free_fd)
13915         cmd="exec $fd<$DIR/$tfile"
13916         eval $cmd
13917         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13918         echo "$fid_list" | grep "$fid"
13919         rc=$?
13920
13921         cmd="exec $fd>/dev/null"
13922         eval $cmd
13923         if [ $rc -ne 0 ]; then
13924                 error "FID $fid not found in open files list $fid_list"
13925         fi
13926 }
13927 run_test 154d "Verify open file fid"
13928
13929 test_154e()
13930 {
13931         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13932                 skip "Need MDS version at least 2.6.50"
13933
13934         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13935                 error ".lustre returned by readdir"
13936         fi
13937 }
13938 run_test 154e ".lustre is not returned by readdir"
13939
13940 test_154f() {
13941         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13942
13943         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13944         test_mkdir -p -c1 $DIR/$tdir/d
13945         # test dirs inherit from its stripe
13946         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13947         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13948         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13949         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13950         touch $DIR/f
13951
13952         # get fid of parents
13953         local FID0=$($LFS path2fid $DIR/$tdir/d)
13954         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13955         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13956         local FID3=$($LFS path2fid $DIR)
13957
13958         # check that path2fid --parents returns expected <parent_fid>/name
13959         # 1) test for a directory (single parent)
13960         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13961         [ "$parent" == "$FID0/foo1" ] ||
13962                 error "expected parent: $FID0/foo1, got: $parent"
13963
13964         # 2) test for a file with nlink > 1 (multiple parents)
13965         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13966         echo "$parent" | grep -F "$FID1/$tfile" ||
13967                 error "$FID1/$tfile not returned in parent list"
13968         echo "$parent" | grep -F "$FID2/link" ||
13969                 error "$FID2/link not returned in parent list"
13970
13971         # 3) get parent by fid
13972         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13973         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13974         echo "$parent" | grep -F "$FID1/$tfile" ||
13975                 error "$FID1/$tfile not returned in parent list (by fid)"
13976         echo "$parent" | grep -F "$FID2/link" ||
13977                 error "$FID2/link not returned in parent list (by fid)"
13978
13979         # 4) test for entry in root directory
13980         parent=$($LFS path2fid --parents $DIR/f)
13981         echo "$parent" | grep -F "$FID3/f" ||
13982                 error "$FID3/f not returned in parent list"
13983
13984         # 5) test it on root directory
13985         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13986                 error "$MOUNT should not have parents"
13987
13988         # enable xattr caching and check that linkea is correctly updated
13989         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13990         save_lustre_params client "llite.*.xattr_cache" > $save
13991         lctl set_param llite.*.xattr_cache 1
13992
13993         # 6.1) linkea update on rename
13994         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13995
13996         # get parents by fid
13997         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13998         # foo1 should no longer be returned in parent list
13999         echo "$parent" | grep -F "$FID1" &&
14000                 error "$FID1 should no longer be in parent list"
14001         # the new path should appear
14002         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14003                 error "$FID2/$tfile.moved is not in parent list"
14004
14005         # 6.2) linkea update on unlink
14006         rm -f $DIR/$tdir/d/foo2/link
14007         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14008         # foo2/link should no longer be returned in parent list
14009         echo "$parent" | grep -F "$FID2/link" &&
14010                 error "$FID2/link should no longer be in parent list"
14011         true
14012
14013         rm -f $DIR/f
14014         restore_lustre_params < $save
14015         rm -f $save
14016 }
14017 run_test 154f "get parent fids by reading link ea"
14018
14019 test_154g()
14020 {
14021         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14022         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14023            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14024                 skip "Need MDS version at least 2.6.92"
14025
14026         mkdir -p $DIR/$tdir
14027         llapi_fid_test -d $DIR/$tdir
14028 }
14029 run_test 154g "various llapi FID tests"
14030
14031 test_155_small_load() {
14032     local temp=$TMP/$tfile
14033     local file=$DIR/$tfile
14034
14035     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14036         error "dd of=$temp bs=6096 count=1 failed"
14037     cp $temp $file
14038     cancel_lru_locks $OSC
14039     cmp $temp $file || error "$temp $file differ"
14040
14041     $TRUNCATE $temp 6000
14042     $TRUNCATE $file 6000
14043     cmp $temp $file || error "$temp $file differ (truncate1)"
14044
14045     echo "12345" >>$temp
14046     echo "12345" >>$file
14047     cmp $temp $file || error "$temp $file differ (append1)"
14048
14049     echo "12345" >>$temp
14050     echo "12345" >>$file
14051     cmp $temp $file || error "$temp $file differ (append2)"
14052
14053     rm -f $temp $file
14054     true
14055 }
14056
14057 test_155_big_load() {
14058         remote_ost_nodsh && skip "remote OST with nodsh"
14059
14060         local temp=$TMP/$tfile
14061         local file=$DIR/$tfile
14062
14063         free_min_max
14064         local cache_size=$(do_facet ost$((MAXI+1)) \
14065                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14066         local large_file_size=$((cache_size * 2))
14067
14068         echo "OSS cache size: $cache_size KB"
14069         echo "Large file size: $large_file_size KB"
14070
14071         [ $MAXV -le $large_file_size ] &&
14072                 skip_env "max available OST size needs > $large_file_size KB"
14073
14074         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14075
14076         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14077                 error "dd of=$temp bs=$large_file_size count=1k failed"
14078         cp $temp $file
14079         ls -lh $temp $file
14080         cancel_lru_locks osc
14081         cmp $temp $file || error "$temp $file differ"
14082
14083         rm -f $temp $file
14084         true
14085 }
14086
14087 save_writethrough() {
14088         local facets=$(get_facets OST)
14089
14090         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14091 }
14092
14093 test_155a() {
14094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14095
14096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14097
14098         save_writethrough $p
14099
14100         set_cache read on
14101         set_cache writethrough on
14102         test_155_small_load
14103         restore_lustre_params < $p
14104         rm -f $p
14105 }
14106 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14107
14108 test_155b() {
14109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14110
14111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14112
14113         save_writethrough $p
14114
14115         set_cache read on
14116         set_cache writethrough off
14117         test_155_small_load
14118         restore_lustre_params < $p
14119         rm -f $p
14120 }
14121 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14122
14123 test_155c() {
14124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14125
14126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14127
14128         save_writethrough $p
14129
14130         set_cache read off
14131         set_cache writethrough on
14132         test_155_small_load
14133         restore_lustre_params < $p
14134         rm -f $p
14135 }
14136 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14137
14138 test_155d() {
14139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14140
14141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14142
14143         save_writethrough $p
14144
14145         set_cache read off
14146         set_cache writethrough off
14147         test_155_small_load
14148         restore_lustre_params < $p
14149         rm -f $p
14150 }
14151 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14152
14153 test_155e() {
14154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14155
14156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14157
14158         save_writethrough $p
14159
14160         set_cache read on
14161         set_cache writethrough on
14162         test_155_big_load
14163         restore_lustre_params < $p
14164         rm -f $p
14165 }
14166 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14167
14168 test_155f() {
14169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14170
14171         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14172
14173         save_writethrough $p
14174
14175         set_cache read on
14176         set_cache writethrough off
14177         test_155_big_load
14178         restore_lustre_params < $p
14179         rm -f $p
14180 }
14181 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14182
14183 test_155g() {
14184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14185
14186         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14187
14188         save_writethrough $p
14189
14190         set_cache read off
14191         set_cache writethrough on
14192         test_155_big_load
14193         restore_lustre_params < $p
14194         rm -f $p
14195 }
14196 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14197
14198 test_155h() {
14199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14200
14201         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14202
14203         save_writethrough $p
14204
14205         set_cache read off
14206         set_cache writethrough off
14207         test_155_big_load
14208         restore_lustre_params < $p
14209         rm -f $p
14210 }
14211 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14212
14213 test_156() {
14214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14215         remote_ost_nodsh && skip "remote OST with nodsh"
14216         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14217                 skip "stats not implemented on old servers"
14218         [ "$ost1_FSTYPE" = "zfs" ] &&
14219                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14220
14221         local CPAGES=3
14222         local BEFORE
14223         local AFTER
14224         local file="$DIR/$tfile"
14225         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14226
14227         save_writethrough $p
14228         roc_hit_init
14229
14230         log "Turn on read and write cache"
14231         set_cache read on
14232         set_cache writethrough on
14233
14234         log "Write data and read it back."
14235         log "Read should be satisfied from the cache."
14236         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14237         BEFORE=$(roc_hit)
14238         cancel_lru_locks osc
14239         cat $file >/dev/null
14240         AFTER=$(roc_hit)
14241         if ! let "AFTER - BEFORE == CPAGES"; then
14242                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14243         else
14244                 log "cache hits: before: $BEFORE, after: $AFTER"
14245         fi
14246
14247         log "Read again; it should be satisfied from the cache."
14248         BEFORE=$AFTER
14249         cancel_lru_locks osc
14250         cat $file >/dev/null
14251         AFTER=$(roc_hit)
14252         if ! let "AFTER - BEFORE == CPAGES"; then
14253                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14254         else
14255                 log "cache hits:: before: $BEFORE, after: $AFTER"
14256         fi
14257
14258         log "Turn off the read cache and turn on the write cache"
14259         set_cache read off
14260         set_cache writethrough on
14261
14262         log "Read again; it should be satisfied from the cache."
14263         BEFORE=$(roc_hit)
14264         cancel_lru_locks osc
14265         cat $file >/dev/null
14266         AFTER=$(roc_hit)
14267         if ! let "AFTER - BEFORE == CPAGES"; then
14268                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14269         else
14270                 log "cache hits:: before: $BEFORE, after: $AFTER"
14271         fi
14272
14273         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14274                 # > 2.12.56 uses pagecache if cached
14275                 log "Read again; it should not be satisfied from the cache."
14276                 BEFORE=$AFTER
14277                 cancel_lru_locks osc
14278                 cat $file >/dev/null
14279                 AFTER=$(roc_hit)
14280                 if ! let "AFTER - BEFORE == 0"; then
14281                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14282                 else
14283                         log "cache hits:: before: $BEFORE, after: $AFTER"
14284                 fi
14285         fi
14286
14287         log "Write data and read it back."
14288         log "Read should be satisfied from the cache."
14289         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14290         BEFORE=$(roc_hit)
14291         cancel_lru_locks osc
14292         cat $file >/dev/null
14293         AFTER=$(roc_hit)
14294         if ! let "AFTER - BEFORE == CPAGES"; then
14295                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14296         else
14297                 log "cache hits:: before: $BEFORE, after: $AFTER"
14298         fi
14299
14300         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14301                 # > 2.12.56 uses pagecache if cached
14302                 log "Read again; it should not be satisfied from the cache."
14303                 BEFORE=$AFTER
14304                 cancel_lru_locks osc
14305                 cat $file >/dev/null
14306                 AFTER=$(roc_hit)
14307                 if ! let "AFTER - BEFORE == 0"; then
14308                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14309                 else
14310                         log "cache hits:: before: $BEFORE, after: $AFTER"
14311                 fi
14312         fi
14313
14314         log "Turn off read and write cache"
14315         set_cache read off
14316         set_cache writethrough off
14317
14318         log "Write data and read it back"
14319         log "It should not be satisfied from the cache."
14320         rm -f $file
14321         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14322         cancel_lru_locks osc
14323         BEFORE=$(roc_hit)
14324         cat $file >/dev/null
14325         AFTER=$(roc_hit)
14326         if ! let "AFTER - BEFORE == 0"; then
14327                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14328         else
14329                 log "cache hits:: before: $BEFORE, after: $AFTER"
14330         fi
14331
14332         log "Turn on the read cache and turn off the write cache"
14333         set_cache read on
14334         set_cache writethrough off
14335
14336         log "Write data and read it back"
14337         log "It should not be satisfied from the cache."
14338         rm -f $file
14339         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14340         BEFORE=$(roc_hit)
14341         cancel_lru_locks osc
14342         cat $file >/dev/null
14343         AFTER=$(roc_hit)
14344         if ! let "AFTER - BEFORE == 0"; then
14345                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14346         else
14347                 log "cache hits:: before: $BEFORE, after: $AFTER"
14348         fi
14349
14350         log "Read again; it should be satisfied from the cache."
14351         BEFORE=$(roc_hit)
14352         cancel_lru_locks osc
14353         cat $file >/dev/null
14354         AFTER=$(roc_hit)
14355         if ! let "AFTER - BEFORE == CPAGES"; then
14356                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14357         else
14358                 log "cache hits:: before: $BEFORE, after: $AFTER"
14359         fi
14360
14361         restore_lustre_params < $p
14362         rm -f $p $file
14363 }
14364 run_test 156 "Verification of tunables"
14365
14366 test_160a() {
14367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14368         remote_mds_nodsh && skip "remote MDS with nodsh"
14369         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14370                 skip "Need MDS version at least 2.2.0"
14371
14372         changelog_register || error "changelog_register failed"
14373         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14374         changelog_users $SINGLEMDS | grep -q $cl_user ||
14375                 error "User $cl_user not found in changelog_users"
14376
14377         # change something
14378         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14379         changelog_clear 0 || error "changelog_clear failed"
14380         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14381         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14382         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14383         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14384         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14385         rm $DIR/$tdir/pics/desktop.jpg
14386
14387         changelog_dump | tail -10
14388
14389         echo "verifying changelog mask"
14390         changelog_chmask "-MKDIR"
14391         changelog_chmask "-CLOSE"
14392
14393         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14394         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14395
14396         changelog_chmask "+MKDIR"
14397         changelog_chmask "+CLOSE"
14398
14399         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14400         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14401
14402         changelog_dump | tail -10
14403         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14404         CLOSES=$(changelog_dump | grep -c "CLOSE")
14405         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14406         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14407
14408         # verify contents
14409         echo "verifying target fid"
14410         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14411         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14412         [ "$fidc" == "$fidf" ] ||
14413                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14414         echo "verifying parent fid"
14415         # The FID returned from the Changelog may be the directory shard on
14416         # a different MDT, and not the FID returned by path2fid on the parent.
14417         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14418         # since this is what will matter when recreating this file in the tree.
14419         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14420         local pathp=$($LFS fid2path $MOUNT "$fidp")
14421         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14422                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14423
14424         echo "getting records for $cl_user"
14425         changelog_users $SINGLEMDS
14426         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14427         local nclr=3
14428         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14429                 error "changelog_clear failed"
14430         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14431         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14432         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14433                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14434
14435         local min0_rec=$(changelog_users $SINGLEMDS |
14436                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14437         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14438                           awk '{ print $1; exit; }')
14439
14440         changelog_dump | tail -n 5
14441         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14442         [ $first_rec == $((min0_rec + 1)) ] ||
14443                 error "first index should be $min0_rec + 1 not $first_rec"
14444
14445         # LU-3446 changelog index reset on MDT restart
14446         local cur_rec1=$(changelog_users $SINGLEMDS |
14447                          awk '/^current.index:/ { print $NF }')
14448         changelog_clear 0 ||
14449                 error "clear all changelog records for $cl_user failed"
14450         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14451         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14452                 error "Fail to start $SINGLEMDS"
14453         local cur_rec2=$(changelog_users $SINGLEMDS |
14454                          awk '/^current.index:/ { print $NF }')
14455         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14456         [ $cur_rec1 == $cur_rec2 ] ||
14457                 error "current index should be $cur_rec1 not $cur_rec2"
14458
14459         echo "verifying users from this test are deregistered"
14460         changelog_deregister || error "changelog_deregister failed"
14461         changelog_users $SINGLEMDS | grep -q $cl_user &&
14462                 error "User '$cl_user' still in changelog_users"
14463
14464         # lctl get_param -n mdd.*.changelog_users
14465         # current index: 144
14466         # ID    index (idle seconds)
14467         # cl3   144 (2)
14468         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14469                 # this is the normal case where all users were deregistered
14470                 # make sure no new records are added when no users are present
14471                 local last_rec1=$(changelog_users $SINGLEMDS |
14472                                   awk '/^current.index:/ { print $NF }')
14473                 touch $DIR/$tdir/chloe
14474                 local last_rec2=$(changelog_users $SINGLEMDS |
14475                                   awk '/^current.index:/ { print $NF }')
14476                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14477                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14478         else
14479                 # any changelog users must be leftovers from a previous test
14480                 changelog_users $SINGLEMDS
14481                 echo "other changelog users; can't verify off"
14482         fi
14483 }
14484 run_test 160a "changelog sanity"
14485
14486 test_160b() { # LU-3587
14487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14488         remote_mds_nodsh && skip "remote MDS with nodsh"
14489         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14490                 skip "Need MDS version at least 2.2.0"
14491
14492         changelog_register || error "changelog_register failed"
14493         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14494         changelog_users $SINGLEMDS | grep -q $cl_user ||
14495                 error "User '$cl_user' not found in changelog_users"
14496
14497         local longname1=$(str_repeat a 255)
14498         local longname2=$(str_repeat b 255)
14499
14500         cd $DIR
14501         echo "creating very long named file"
14502         touch $longname1 || error "create of '$longname1' failed"
14503         echo "renaming very long named file"
14504         mv $longname1 $longname2
14505
14506         changelog_dump | grep RENME | tail -n 5
14507         rm -f $longname2
14508 }
14509 run_test 160b "Verify that very long rename doesn't crash in changelog"
14510
14511 test_160c() {
14512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14513         remote_mds_nodsh && skip "remote MDS with nodsh"
14514
14515         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14516                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14517                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14518                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14519
14520         local rc=0
14521
14522         # Registration step
14523         changelog_register || error "changelog_register failed"
14524
14525         rm -rf $DIR/$tdir
14526         mkdir -p $DIR/$tdir
14527         $MCREATE $DIR/$tdir/foo_160c
14528         changelog_chmask "-TRUNC"
14529         $TRUNCATE $DIR/$tdir/foo_160c 200
14530         changelog_chmask "+TRUNC"
14531         $TRUNCATE $DIR/$tdir/foo_160c 199
14532         changelog_dump | tail -n 5
14533         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14534         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14535 }
14536 run_test 160c "verify that changelog log catch the truncate event"
14537
14538 test_160d() {
14539         remote_mds_nodsh && skip "remote MDS with nodsh"
14540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14542         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14543                 skip "Need MDS version at least 2.7.60"
14544
14545         # Registration step
14546         changelog_register || error "changelog_register failed"
14547
14548         mkdir -p $DIR/$tdir/migrate_dir
14549         changelog_clear 0 || error "changelog_clear failed"
14550
14551         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14552         changelog_dump | tail -n 5
14553         local migrates=$(changelog_dump | grep -c "MIGRT")
14554         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14555 }
14556 run_test 160d "verify that changelog log catch the migrate event"
14557
14558 test_160e() {
14559         remote_mds_nodsh && skip "remote MDS with nodsh"
14560
14561         # Create a user
14562         changelog_register || error "changelog_register failed"
14563
14564         # Delete a future user (expect fail)
14565         local MDT0=$(facet_svc $SINGLEMDS)
14566         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14567         local rc=$?
14568
14569         if [ $rc -eq 0 ]; then
14570                 error "Deleted non-existant user cl77"
14571         elif [ $rc -ne 2 ]; then
14572                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14573         fi
14574
14575         # Clear to a bad index (1 billion should be safe)
14576         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14577         rc=$?
14578
14579         if [ $rc -eq 0 ]; then
14580                 error "Successfully cleared to invalid CL index"
14581         elif [ $rc -ne 22 ]; then
14582                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14583         fi
14584 }
14585 run_test 160e "changelog negative testing (should return errors)"
14586
14587 test_160f() {
14588         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14589         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14590                 skip "Need MDS version at least 2.10.56"
14591
14592         local mdts=$(comma_list $(mdts_nodes))
14593
14594         # Create a user
14595         changelog_register || error "first changelog_register failed"
14596         changelog_register || error "second changelog_register failed"
14597         local cl_users
14598         declare -A cl_user1
14599         declare -A cl_user2
14600         local user_rec1
14601         local user_rec2
14602         local i
14603
14604         # generate some changelog records to accumulate on each MDT
14605         # use fnv1a because created files should be evenly distributed
14606         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14607                 error "test_mkdir $tdir failed"
14608         log "$(date +%s): creating first files"
14609         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14610                 error "create $DIR/$tdir/$tfile failed"
14611
14612         # check changelogs have been generated
14613         local start=$SECONDS
14614         local idle_time=$((MDSCOUNT * 5 + 5))
14615         local nbcl=$(changelog_dump | wc -l)
14616         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14617
14618         for param in "changelog_max_idle_time=$idle_time" \
14619                      "changelog_gc=1" \
14620                      "changelog_min_gc_interval=2" \
14621                      "changelog_min_free_cat_entries=3"; do
14622                 local MDT0=$(facet_svc $SINGLEMDS)
14623                 local var="${param%=*}"
14624                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14625
14626                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14627                 do_nodes $mdts $LCTL set_param mdd.*.$param
14628         done
14629
14630         # force cl_user2 to be idle (1st part), but also cancel the
14631         # cl_user1 records so that it is not evicted later in the test.
14632         local sleep1=$((idle_time / 2))
14633         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14634         sleep $sleep1
14635
14636         # simulate changelog catalog almost full
14637         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14638         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14639
14640         for i in $(seq $MDSCOUNT); do
14641                 cl_users=(${CL_USERS[mds$i]})
14642                 cl_user1[mds$i]="${cl_users[0]}"
14643                 cl_user2[mds$i]="${cl_users[1]}"
14644
14645                 [ -n "${cl_user1[mds$i]}" ] ||
14646                         error "mds$i: no user registered"
14647                 [ -n "${cl_user2[mds$i]}" ] ||
14648                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14649
14650                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14651                 [ -n "$user_rec1" ] ||
14652                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14653                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14654                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14655                 [ -n "$user_rec2" ] ||
14656                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14657                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14658                      "$user_rec1 + 2 == $user_rec2"
14659                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14660                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14661                               "$user_rec1 + 2, but is $user_rec2"
14662                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14663                 [ -n "$user_rec2" ] ||
14664                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14665                 [ $user_rec1 == $user_rec2 ] ||
14666                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14667                               "$user_rec1, but is $user_rec2"
14668         done
14669
14670         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14671         local sleep2=$((idle_time - (SECONDS - start) + 1))
14672         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14673         sleep $sleep2
14674
14675         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14676         # cl_user1 should be OK because it recently processed records.
14677         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14678         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14679                 error "create $DIR/$tdir/${tfile}b failed"
14680
14681         # ensure gc thread is done
14682         for i in $(mdts_nodes); do
14683                 wait_update $i \
14684                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14685                         error "$i: GC-thread not done"
14686         done
14687
14688         local first_rec
14689         for i in $(seq $MDSCOUNT); do
14690                 # check cl_user1 still registered
14691                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14692                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14693                 # check cl_user2 unregistered
14694                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14695                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14696
14697                 # check changelogs are present and starting at $user_rec1 + 1
14698                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14699                 [ -n "$user_rec1" ] ||
14700                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14701                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14702                             awk '{ print $1; exit; }')
14703
14704                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14705                 [ $((user_rec1 + 1)) == $first_rec ] ||
14706                         error "mds$i: first index should be $user_rec1 + 1, " \
14707                               "but is $first_rec"
14708         done
14709 }
14710 run_test 160f "changelog garbage collect (timestamped users)"
14711
14712 test_160g() {
14713         remote_mds_nodsh && skip "remote MDS with nodsh"
14714         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14715                 skip "Need MDS version at least 2.10.56"
14716
14717         local mdts=$(comma_list $(mdts_nodes))
14718
14719         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14720         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14721
14722         # Create a user
14723         changelog_register || error "first changelog_register failed"
14724         changelog_register || error "second changelog_register failed"
14725         local cl_users
14726         declare -A cl_user1
14727         declare -A cl_user2
14728         local user_rec1
14729         local user_rec2
14730         local i
14731
14732         # generate some changelog records to accumulate on each MDT
14733         # use fnv1a because created files should be evenly distributed
14734         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14735                 error "mkdir $tdir failed"
14736         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14737                 error "create $DIR/$tdir/$tfile failed"
14738
14739         # check changelogs have been generated
14740         local nbcl=$(changelog_dump | wc -l)
14741         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14742
14743         # reduce the max_idle_indexes value to make sure we exceed it
14744         max_ndx=$((nbcl / 2 - 1))
14745
14746         for param in "changelog_max_idle_indexes=$max_ndx" \
14747                      "changelog_gc=1" \
14748                      "changelog_min_gc_interval=2" \
14749                      "changelog_min_free_cat_entries=3"; do
14750                 local MDT0=$(facet_svc $SINGLEMDS)
14751                 local var="${param%=*}"
14752                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14753
14754                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14755                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14756                         error "unable to set mdd.*.$param"
14757         done
14758
14759         # simulate changelog catalog almost full
14760         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14761         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14762
14763         for i in $(seq $MDSCOUNT); do
14764                 cl_users=(${CL_USERS[mds$i]})
14765                 cl_user1[mds$i]="${cl_users[0]}"
14766                 cl_user2[mds$i]="${cl_users[1]}"
14767
14768                 [ -n "${cl_user1[mds$i]}" ] ||
14769                         error "mds$i: no user registered"
14770                 [ -n "${cl_user2[mds$i]}" ] ||
14771                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14772
14773                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14774                 [ -n "$user_rec1" ] ||
14775                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14776                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14777                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14778                 [ -n "$user_rec2" ] ||
14779                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14780                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14781                      "$user_rec1 + 2 == $user_rec2"
14782                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14783                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14784                               "$user_rec1 + 2, but is $user_rec2"
14785                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14786                 [ -n "$user_rec2" ] ||
14787                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14788                 [ $user_rec1 == $user_rec2 ] ||
14789                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14790                               "$user_rec1, but is $user_rec2"
14791         done
14792
14793         # ensure we are past the previous changelog_min_gc_interval set above
14794         sleep 2
14795
14796         # generate one more changelog to trigger fail_loc
14797         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14798                 error "create $DIR/$tdir/${tfile}bis failed"
14799
14800         # ensure gc thread is done
14801         for i in $(mdts_nodes); do
14802                 wait_update $i \
14803                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14804                         error "$i: GC-thread not done"
14805         done
14806
14807         local first_rec
14808         for i in $(seq $MDSCOUNT); do
14809                 # check cl_user1 still registered
14810                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14811                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14812                 # check cl_user2 unregistered
14813                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14814                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14815
14816                 # check changelogs are present and starting at $user_rec1 + 1
14817                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14818                 [ -n "$user_rec1" ] ||
14819                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14820                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14821                             awk '{ print $1; exit; }')
14822
14823                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14824                 [ $((user_rec1 + 1)) == $first_rec ] ||
14825                         error "mds$i: first index should be $user_rec1 + 1, " \
14826                               "but is $first_rec"
14827         done
14828 }
14829 run_test 160g "changelog garbage collect (old users)"
14830
14831 test_160h() {
14832         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14833         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14834                 skip "Need MDS version at least 2.10.56"
14835
14836         local mdts=$(comma_list $(mdts_nodes))
14837
14838         # Create a user
14839         changelog_register || error "first changelog_register failed"
14840         changelog_register || error "second changelog_register failed"
14841         local cl_users
14842         declare -A cl_user1
14843         declare -A cl_user2
14844         local user_rec1
14845         local user_rec2
14846         local i
14847
14848         # generate some changelog records to accumulate on each MDT
14849         # use fnv1a because created files should be evenly distributed
14850         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14851                 error "test_mkdir $tdir failed"
14852         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14853                 error "create $DIR/$tdir/$tfile failed"
14854
14855         # check changelogs have been generated
14856         local nbcl=$(changelog_dump | wc -l)
14857         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14858
14859         for param in "changelog_max_idle_time=10" \
14860                      "changelog_gc=1" \
14861                      "changelog_min_gc_interval=2"; do
14862                 local MDT0=$(facet_svc $SINGLEMDS)
14863                 local var="${param%=*}"
14864                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14865
14866                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14867                 do_nodes $mdts $LCTL set_param mdd.*.$param
14868         done
14869
14870         # force cl_user2 to be idle (1st part)
14871         sleep 9
14872
14873         for i in $(seq $MDSCOUNT); do
14874                 cl_users=(${CL_USERS[mds$i]})
14875                 cl_user1[mds$i]="${cl_users[0]}"
14876                 cl_user2[mds$i]="${cl_users[1]}"
14877
14878                 [ -n "${cl_user1[mds$i]}" ] ||
14879                         error "mds$i: no user registered"
14880                 [ -n "${cl_user2[mds$i]}" ] ||
14881                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14882
14883                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14884                 [ -n "$user_rec1" ] ||
14885                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14886                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14887                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14888                 [ -n "$user_rec2" ] ||
14889                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14890                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14891                      "$user_rec1 + 2 == $user_rec2"
14892                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14893                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14894                               "$user_rec1 + 2, but is $user_rec2"
14895                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14896                 [ -n "$user_rec2" ] ||
14897                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14898                 [ $user_rec1 == $user_rec2 ] ||
14899                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14900                               "$user_rec1, but is $user_rec2"
14901         done
14902
14903         # force cl_user2 to be idle (2nd part) and to reach
14904         # changelog_max_idle_time
14905         sleep 2
14906
14907         # force each GC-thread start and block then
14908         # one per MDT/MDD, set fail_val accordingly
14909         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14910         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14911
14912         # generate more changelogs to trigger fail_loc
14913         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14914                 error "create $DIR/$tdir/${tfile}bis failed"
14915
14916         # stop MDT to stop GC-thread, should be done in back-ground as it will
14917         # block waiting for the thread to be released and exit
14918         declare -A stop_pids
14919         for i in $(seq $MDSCOUNT); do
14920                 stop mds$i &
14921                 stop_pids[mds$i]=$!
14922         done
14923
14924         for i in $(mdts_nodes); do
14925                 local facet
14926                 local nb=0
14927                 local facets=$(facets_up_on_host $i)
14928
14929                 for facet in ${facets//,/ }; do
14930                         if [[ $facet == mds* ]]; then
14931                                 nb=$((nb + 1))
14932                         fi
14933                 done
14934                 # ensure each MDS's gc threads are still present and all in "R"
14935                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14936                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14937                         error "$i: expected $nb GC-thread"
14938                 wait_update $i \
14939                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14940                         "R" 20 ||
14941                         error "$i: GC-thread not found in R-state"
14942                 # check umounts of each MDT on MDS have reached kthread_stop()
14943                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14944                         error "$i: expected $nb umount"
14945                 wait_update $i \
14946                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14947                         error "$i: umount not found in D-state"
14948         done
14949
14950         # release all GC-threads
14951         do_nodes $mdts $LCTL set_param fail_loc=0
14952
14953         # wait for MDT stop to complete
14954         for i in $(seq $MDSCOUNT); do
14955                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14956         done
14957
14958         # XXX
14959         # may try to check if any orphan changelog records are present
14960         # via ldiskfs/zfs and llog_reader...
14961
14962         # re-start/mount MDTs
14963         for i in $(seq $MDSCOUNT); do
14964                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14965                         error "Fail to start mds$i"
14966         done
14967
14968         local first_rec
14969         for i in $(seq $MDSCOUNT); do
14970                 # check cl_user1 still registered
14971                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14972                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14973                 # check cl_user2 unregistered
14974                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14975                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14976
14977                 # check changelogs are present and starting at $user_rec1 + 1
14978                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14979                 [ -n "$user_rec1" ] ||
14980                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14981                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14982                             awk '{ print $1; exit; }')
14983
14984                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14985                 [ $((user_rec1 + 1)) == $first_rec ] ||
14986                         error "mds$i: first index should be $user_rec1 + 1, " \
14987                               "but is $first_rec"
14988         done
14989 }
14990 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14991               "during mount"
14992
14993 test_160i() {
14994
14995         local mdts=$(comma_list $(mdts_nodes))
14996
14997         changelog_register || error "first changelog_register failed"
14998
14999         # generate some changelog records to accumulate on each MDT
15000         # use fnv1a because created files should be evenly distributed
15001         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15002                 error "mkdir $tdir failed"
15003         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15004                 error "create $DIR/$tdir/$tfile failed"
15005
15006         # check changelogs have been generated
15007         local nbcl=$(changelog_dump | wc -l)
15008         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15009
15010         # simulate race between register and unregister
15011         # XXX as fail_loc is set per-MDS, with DNE configs the race
15012         # simulation will only occur for one MDT per MDS and for the
15013         # others the normal race scenario will take place
15014         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15015         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15016         do_nodes $mdts $LCTL set_param fail_val=1
15017
15018         # unregister 1st user
15019         changelog_deregister &
15020         local pid1=$!
15021         # wait some time for deregister work to reach race rdv
15022         sleep 2
15023         # register 2nd user
15024         changelog_register || error "2nd user register failed"
15025
15026         wait $pid1 || error "1st user deregister failed"
15027
15028         local i
15029         local last_rec
15030         declare -A LAST_REC
15031         for i in $(seq $MDSCOUNT); do
15032                 if changelog_users mds$i | grep "^cl"; then
15033                         # make sure new records are added with one user present
15034                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15035                                           awk '/^current.index:/ { print $NF }')
15036                 else
15037                         error "mds$i has no user registered"
15038                 fi
15039         done
15040
15041         # generate more changelog records to accumulate on each MDT
15042         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15043                 error "create $DIR/$tdir/${tfile}bis failed"
15044
15045         for i in $(seq $MDSCOUNT); do
15046                 last_rec=$(changelog_users $SINGLEMDS |
15047                            awk '/^current.index:/ { print $NF }')
15048                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15049                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15050                         error "changelogs are off on mds$i"
15051         done
15052 }
15053 run_test 160i "changelog user register/unregister race"
15054
15055 test_160j() {
15056         remote_mds_nodsh && skip "remote MDS with nodsh"
15057         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15058                 skip "Need MDS version at least 2.12.56"
15059
15060         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15061         stack_trap "umount $MOUNT2" EXIT
15062
15063         changelog_register || error "first changelog_register failed"
15064         stack_trap "changelog_deregister" EXIT
15065
15066         # generate some changelog
15067         # use fnv1a because created files should be evenly distributed
15068         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15069                 error "mkdir $tdir failed"
15070         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15071                 error "create $DIR/$tdir/${tfile}bis failed"
15072
15073         # open the changelog device
15074         exec 3>/dev/changelog-$FSNAME-MDT0000
15075         stack_trap "exec 3>&-" EXIT
15076         exec 4</dev/changelog-$FSNAME-MDT0000
15077         stack_trap "exec 4<&-" EXIT
15078
15079         # umount the first lustre mount
15080         umount $MOUNT
15081         stack_trap "mount_client $MOUNT" EXIT
15082
15083         # read changelog
15084         cat <&4 >/dev/null || error "read changelog failed"
15085
15086         # clear changelog
15087         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15088         changelog_users $SINGLEMDS | grep -q $cl_user ||
15089                 error "User $cl_user not found in changelog_users"
15090
15091         printf 'clear:'$cl_user':0' >&3
15092 }
15093 run_test 160j "client can be umounted  while its chanangelog is being used"
15094
15095 test_160k() {
15096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15097         remote_mds_nodsh && skip "remote MDS with nodsh"
15098
15099         mkdir -p $DIR/$tdir/1/1
15100
15101         changelog_register || error "changelog_register failed"
15102         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15103
15104         changelog_users $SINGLEMDS | grep -q $cl_user ||
15105                 error "User '$cl_user' not found in changelog_users"
15106 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15107         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15108         rmdir $DIR/$tdir/1/1 & sleep 1
15109         mkdir $DIR/$tdir/2
15110         touch $DIR/$tdir/2/2
15111         rm -rf $DIR/$tdir/2
15112
15113         wait
15114         sleep 4
15115
15116         changelog_dump | grep rmdir || error "rmdir not recorded"
15117
15118         rm -rf $DIR/$tdir
15119         changelog_deregister
15120 }
15121 run_test 160k "Verify that changelog records are not lost"
15122
15123 # Verifies that a file passed as a parameter has recently had an operation
15124 # performed on it that has generated an MTIME changelog which contains the
15125 # correct parent FID. As files might reside on a different MDT from the
15126 # parent directory in DNE configurations, the FIDs are translated to paths
15127 # before being compared, which should be identical
15128 compare_mtime_changelog() {
15129         local file="${1}"
15130         local mdtidx
15131         local mtime
15132         local cl_fid
15133         local pdir
15134         local dir
15135
15136         mdtidx=$($LFS getstripe --mdt-index $file)
15137         mdtidx=$(printf "%04x" $mdtidx)
15138
15139         # Obtain the parent FID from the MTIME changelog
15140         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15141         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15142
15143         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15144         [ -z "$cl_fid" ] && error "parent FID not present"
15145
15146         # Verify that the path for the parent FID is the same as the path for
15147         # the test directory
15148         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15149
15150         dir=$(dirname $1)
15151
15152         [[ "${pdir%/}" == "$dir" ]] ||
15153                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15154 }
15155
15156 test_160l() {
15157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15158
15159         remote_mds_nodsh && skip "remote MDS with nodsh"
15160         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15161                 skip "Need MDS version at least 2.13.55"
15162
15163         local cl_user
15164
15165         changelog_register || error "changelog_register failed"
15166         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15167
15168         changelog_users $SINGLEMDS | grep -q $cl_user ||
15169                 error "User '$cl_user' not found in changelog_users"
15170
15171         # Clear some types so that MTIME changelogs are generated
15172         changelog_chmask "-CREAT"
15173         changelog_chmask "-CLOSE"
15174
15175         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15176
15177         # Test CL_MTIME during setattr
15178         touch $DIR/$tdir/$tfile
15179         compare_mtime_changelog $DIR/$tdir/$tfile
15180
15181         # Test CL_MTIME during close
15182         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15183                 error "cannot create file $DIR/$tdir/${tfile}_2"
15184         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15185 }
15186 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15187
15188 test_161a() {
15189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15190
15191         test_mkdir -c1 $DIR/$tdir
15192         cp /etc/hosts $DIR/$tdir/$tfile
15193         test_mkdir -c1 $DIR/$tdir/foo1
15194         test_mkdir -c1 $DIR/$tdir/foo2
15195         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15196         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15197         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15198         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15199         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15200         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15201                 $LFS fid2path $DIR $FID
15202                 error "bad link ea"
15203         fi
15204         # middle
15205         rm $DIR/$tdir/foo2/zachary
15206         # last
15207         rm $DIR/$tdir/foo2/thor
15208         # first
15209         rm $DIR/$tdir/$tfile
15210         # rename
15211         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15212         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15213                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15214         rm $DIR/$tdir/foo2/maggie
15215
15216         # overflow the EA
15217         local longname=$tfile.avg_len_is_thirty_two_
15218         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15219                 error_noexit 'failed to unlink many hardlinks'" EXIT
15220         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15221                 error "failed to hardlink many files"
15222         links=$($LFS fid2path $DIR $FID | wc -l)
15223         echo -n "${links}/1000 links in link EA"
15224         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15225 }
15226 run_test 161a "link ea sanity"
15227
15228 test_161b() {
15229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15230         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15231
15232         local MDTIDX=1
15233         local remote_dir=$DIR/$tdir/remote_dir
15234
15235         mkdir -p $DIR/$tdir
15236         $LFS mkdir -i $MDTIDX $remote_dir ||
15237                 error "create remote directory failed"
15238
15239         cp /etc/hosts $remote_dir/$tfile
15240         mkdir -p $remote_dir/foo1
15241         mkdir -p $remote_dir/foo2
15242         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15243         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15244         ln $remote_dir/$tfile $remote_dir/foo1/luna
15245         ln $remote_dir/$tfile $remote_dir/foo2/thor
15246
15247         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15248                      tr -d ']')
15249         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15250                 $LFS fid2path $DIR $FID
15251                 error "bad link ea"
15252         fi
15253         # middle
15254         rm $remote_dir/foo2/zachary
15255         # last
15256         rm $remote_dir/foo2/thor
15257         # first
15258         rm $remote_dir/$tfile
15259         # rename
15260         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15261         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15262         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15263                 $LFS fid2path $DIR $FID
15264                 error "bad link rename"
15265         fi
15266         rm $remote_dir/foo2/maggie
15267
15268         # overflow the EA
15269         local longname=filename_avg_len_is_thirty_two_
15270         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15271                 error "failed to hardlink many files"
15272         links=$($LFS fid2path $DIR $FID | wc -l)
15273         echo -n "${links}/1000 links in link EA"
15274         [[ ${links} -gt 60 ]] ||
15275                 error "expected at least 60 links in link EA"
15276         unlinkmany $remote_dir/foo2/$longname 1000 ||
15277         error "failed to unlink many hardlinks"
15278 }
15279 run_test 161b "link ea sanity under remote directory"
15280
15281 test_161c() {
15282         remote_mds_nodsh && skip "remote MDS with nodsh"
15283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15284         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15285                 skip "Need MDS version at least 2.1.5"
15286
15287         # define CLF_RENAME_LAST 0x0001
15288         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15289         changelog_register || error "changelog_register failed"
15290
15291         rm -rf $DIR/$tdir
15292         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15293         touch $DIR/$tdir/foo_161c
15294         touch $DIR/$tdir/bar_161c
15295         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15296         changelog_dump | grep RENME | tail -n 5
15297         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15298         changelog_clear 0 || error "changelog_clear failed"
15299         if [ x$flags != "x0x1" ]; then
15300                 error "flag $flags is not 0x1"
15301         fi
15302
15303         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15304         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15305         touch $DIR/$tdir/foo_161c
15306         touch $DIR/$tdir/bar_161c
15307         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15308         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15309         changelog_dump | grep RENME | tail -n 5
15310         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15311         changelog_clear 0 || error "changelog_clear failed"
15312         if [ x$flags != "x0x0" ]; then
15313                 error "flag $flags is not 0x0"
15314         fi
15315         echo "rename overwrite a target having nlink > 1," \
15316                 "changelog record has flags of $flags"
15317
15318         # rename doesn't overwrite a target (changelog flag 0x0)
15319         touch $DIR/$tdir/foo_161c
15320         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15321         changelog_dump | grep RENME | tail -n 5
15322         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15323         changelog_clear 0 || error "changelog_clear failed"
15324         if [ x$flags != "x0x0" ]; then
15325                 error "flag $flags is not 0x0"
15326         fi
15327         echo "rename doesn't overwrite a target," \
15328                 "changelog record has flags of $flags"
15329
15330         # define CLF_UNLINK_LAST 0x0001
15331         # unlink a file having nlink = 1 (changelog flag 0x1)
15332         rm -f $DIR/$tdir/foo2_161c
15333         changelog_dump | grep UNLNK | tail -n 5
15334         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15335         changelog_clear 0 || error "changelog_clear failed"
15336         if [ x$flags != "x0x1" ]; then
15337                 error "flag $flags is not 0x1"
15338         fi
15339         echo "unlink a file having nlink = 1," \
15340                 "changelog record has flags of $flags"
15341
15342         # unlink a file having nlink > 1 (changelog flag 0x0)
15343         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15344         rm -f $DIR/$tdir/foobar_161c
15345         changelog_dump | grep UNLNK | tail -n 5
15346         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15347         changelog_clear 0 || error "changelog_clear failed"
15348         if [ x$flags != "x0x0" ]; then
15349                 error "flag $flags is not 0x0"
15350         fi
15351         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15352 }
15353 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15354
15355 test_161d() {
15356         remote_mds_nodsh && skip "remote MDS with nodsh"
15357         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15358
15359         local pid
15360         local fid
15361
15362         changelog_register || error "changelog_register failed"
15363
15364         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15365         # interfer with $MOUNT/.lustre/fid/ access
15366         mkdir $DIR/$tdir
15367         [[ $? -eq 0 ]] || error "mkdir failed"
15368
15369         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15370         $LCTL set_param fail_loc=0x8000140c
15371         # 5s pause
15372         $LCTL set_param fail_val=5
15373
15374         # create file
15375         echo foofoo > $DIR/$tdir/$tfile &
15376         pid=$!
15377
15378         # wait for create to be delayed
15379         sleep 2
15380
15381         ps -p $pid
15382         [[ $? -eq 0 ]] || error "create should be blocked"
15383
15384         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15385         stack_trap "rm -f $tempfile"
15386         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15387         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15388         # some delay may occur during ChangeLog publishing and file read just
15389         # above, that could allow file write to happen finally
15390         [[ -s $tempfile ]] && echo "file should be empty"
15391
15392         $LCTL set_param fail_loc=0
15393
15394         wait $pid
15395         [[ $? -eq 0 ]] || error "create failed"
15396 }
15397 run_test 161d "create with concurrent .lustre/fid access"
15398
15399 check_path() {
15400         local expected="$1"
15401         shift
15402         local fid="$2"
15403
15404         local path
15405         path=$($LFS fid2path "$@")
15406         local rc=$?
15407
15408         if [ $rc -ne 0 ]; then
15409                 error "path looked up of '$expected' failed: rc=$rc"
15410         elif [ "$path" != "$expected" ]; then
15411                 error "path looked up '$path' instead of '$expected'"
15412         else
15413                 echo "FID '$fid' resolves to path '$path' as expected"
15414         fi
15415 }
15416
15417 test_162a() { # was test_162
15418         test_mkdir -p -c1 $DIR/$tdir/d2
15419         touch $DIR/$tdir/d2/$tfile
15420         touch $DIR/$tdir/d2/x1
15421         touch $DIR/$tdir/d2/x2
15422         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15423         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15424         # regular file
15425         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15426         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15427
15428         # softlink
15429         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15430         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15431         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15432
15433         # softlink to wrong file
15434         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15435         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15436         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15437
15438         # hardlink
15439         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15440         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15441         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15442         # fid2path dir/fsname should both work
15443         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15444         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15445
15446         # hardlink count: check that there are 2 links
15447         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15448         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15449
15450         # hardlink indexing: remove the first link
15451         rm $DIR/$tdir/d2/p/q/r/hlink
15452         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15453 }
15454 run_test 162a "path lookup sanity"
15455
15456 test_162b() {
15457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15459
15460         mkdir $DIR/$tdir
15461         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15462                                 error "create striped dir failed"
15463
15464         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15465                                         tail -n 1 | awk '{print $2}')
15466         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15467
15468         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15469         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15470
15471         # regular file
15472         for ((i=0;i<5;i++)); do
15473                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15474                         error "get fid for f$i failed"
15475                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15476
15477                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15478                         error "get fid for d$i failed"
15479                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15480         done
15481
15482         return 0
15483 }
15484 run_test 162b "striped directory path lookup sanity"
15485
15486 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15487 test_162c() {
15488         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15489                 skip "Need MDS version at least 2.7.51"
15490
15491         local lpath=$tdir.local
15492         local rpath=$tdir.remote
15493
15494         test_mkdir $DIR/$lpath
15495         test_mkdir $DIR/$rpath
15496
15497         for ((i = 0; i <= 101; i++)); do
15498                 lpath="$lpath/$i"
15499                 mkdir $DIR/$lpath
15500                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15501                         error "get fid for local directory $DIR/$lpath failed"
15502                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15503
15504                 rpath="$rpath/$i"
15505                 test_mkdir $DIR/$rpath
15506                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15507                         error "get fid for remote directory $DIR/$rpath failed"
15508                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15509         done
15510
15511         return 0
15512 }
15513 run_test 162c "fid2path works with paths 100 or more directories deep"
15514
15515 oalr_event_count() {
15516         local event="${1}"
15517         local trace="${2}"
15518
15519         awk -v name="${FSNAME}-OST0000" \
15520             -v event="${event}" \
15521             '$1 == "TRACE" && $2 == event && $3 == name' \
15522             "${trace}" |
15523         wc -l
15524 }
15525
15526 oalr_expect_event_count() {
15527         local event="${1}"
15528         local trace="${2}"
15529         local expect="${3}"
15530         local count
15531
15532         count=$(oalr_event_count "${event}" "${trace}")
15533         if ((count == expect)); then
15534                 return 0
15535         fi
15536
15537         error_noexit "${event} event count was '${count}', expected ${expect}"
15538         cat "${trace}" >&2
15539         exit 1
15540 }
15541
15542 cleanup_165() {
15543         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15544         stop ost1
15545         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15546 }
15547
15548 setup_165() {
15549         sync # Flush previous IOs so we can count log entries.
15550         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15551         stack_trap cleanup_165 EXIT
15552 }
15553
15554 test_165a() {
15555         local trace="/tmp/${tfile}.trace"
15556         local rc
15557         local count
15558
15559         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15560                 skip "OFD access log unsupported"
15561
15562         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15563         setup_165
15564         sleep 5
15565
15566         do_facet ost1 ofd_access_log_reader --list
15567         stop ost1
15568
15569         do_facet ost1 killall -TERM ofd_access_log_reader
15570         wait
15571         rc=$?
15572
15573         if ((rc != 0)); then
15574                 error "ofd_access_log_reader exited with rc = '${rc}'"
15575         fi
15576
15577         # Parse trace file for discovery events:
15578         oalr_expect_event_count alr_log_add "${trace}" 1
15579         oalr_expect_event_count alr_log_eof "${trace}" 1
15580         oalr_expect_event_count alr_log_free "${trace}" 1
15581 }
15582 run_test 165a "ofd access log discovery"
15583
15584 test_165b() {
15585         local trace="/tmp/${tfile}.trace"
15586         local file="${DIR}/${tfile}"
15587         local pfid1
15588         local pfid2
15589         local -a entry
15590         local rc
15591         local count
15592         local size
15593         local flags
15594
15595         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15596                 skip "OFD access log unsupported"
15597
15598         setup_165
15599
15600         lfs setstripe -c 1 -i 0 "${file}"
15601         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15602                 error "cannot create '${file}'"
15603         do_facet ost1 ofd_access_log_reader --list
15604
15605         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15606         sleep 5
15607         do_facet ost1 killall -TERM ofd_access_log_reader
15608         wait
15609         rc=$?
15610
15611         if ((rc != 0)); then
15612                 error "ofd_access_log_reader exited with rc = '${rc}'"
15613         fi
15614
15615         oalr_expect_event_count alr_log_entry "${trace}" 1
15616
15617         pfid1=$($LFS path2fid "${file}")
15618
15619         # 1     2             3   4    5     6   7    8    9     10
15620         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15621         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15622
15623         echo "entry = '${entry[*]}'" >&2
15624
15625         pfid2=${entry[4]}
15626         if [[ "${pfid1}" != "${pfid2}" ]]; then
15627                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15628         fi
15629
15630         size=${entry[8]}
15631         if ((size != 1048576)); then
15632                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15633         fi
15634
15635         flags=${entry[10]}
15636         if [[ "${flags}" != "w" ]]; then
15637                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15638         fi
15639
15640         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15641         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15642                 error "cannot read '${file}'"
15643         sleep 5
15644         do_facet ost1 killall -TERM ofd_access_log_reader
15645         wait
15646         rc=$?
15647
15648         if ((rc != 0)); then
15649                 error "ofd_access_log_reader exited with rc = '${rc}'"
15650         fi
15651
15652         oalr_expect_event_count alr_log_entry "${trace}" 1
15653
15654         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15655         echo "entry = '${entry[*]}'" >&2
15656
15657         pfid2=${entry[4]}
15658         if [[ "${pfid1}" != "${pfid2}" ]]; then
15659                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15660         fi
15661
15662         size=${entry[8]}
15663         if ((size != 524288)); then
15664                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15665         fi
15666
15667         flags=${entry[10]}
15668         if [[ "${flags}" != "r" ]]; then
15669                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15670         fi
15671 }
15672 run_test 165b "ofd access log entries are produced and consumed"
15673
15674 test_165c() {
15675         local file="${DIR}/${tdir}/${tfile}"
15676
15677         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15678                 skip "OFD access log unsupported"
15679
15680         test_mkdir "${DIR}/${tdir}"
15681
15682         setup_165
15683
15684         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15685
15686         # 4096 / 64 = 64. Create twice as many entries.
15687         for ((i = 0; i < 128; i++)); do
15688                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15689                         error "cannot create file"
15690         done
15691
15692         sync
15693         do_facet ost1 ofd_access_log_reader --list
15694         unlinkmany  "${file}-%d" 128
15695 }
15696 run_test 165c "full ofd access logs do not block IOs"
15697
15698 oal_peek_entry_count() {
15699         do_facet ost1 ofd_access_log_reader --list |
15700                 awk '$1 == "_entry_count:" { print $2; }'
15701 }
15702
15703 oal_expect_entry_count() {
15704         local entry_count=$(oal_peek_entry_count)
15705         local expect="$1"
15706
15707         if ((entry_count == expect)); then
15708                 return 0
15709         fi
15710
15711         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15712         do_facet ost1 ofd_access_log_reader --list >&2
15713         exit 1
15714 }
15715
15716 test_165d() {
15717         local trace="/tmp/${tfile}.trace"
15718         local file="${DIR}/${tdir}/${tfile}"
15719         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15720         local entry_count
15721
15722         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15723                 skip "OFD access log unsupported"
15724
15725         test_mkdir "${DIR}/${tdir}"
15726
15727         setup_165
15728         lfs setstripe -c 1 -i 0 "${file}"
15729
15730         do_facet ost1 lctl set_param "${param}=rw"
15731         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15732                 error "cannot create '${file}'"
15733         oal_expect_entry_count 1
15734
15735         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15736                 error "cannot read '${file}'"
15737         oal_expect_entry_count 2
15738
15739         do_facet ost1 lctl set_param "${param}=r"
15740         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15741                 error "cannot create '${file}'"
15742         oal_expect_entry_count 2
15743
15744         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15745                 error "cannot read '${file}'"
15746         oal_expect_entry_count 3
15747
15748         do_facet ost1 lctl set_param "${param}=w"
15749         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15750                 error "cannot create '${file}'"
15751         oal_expect_entry_count 4
15752
15753         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15754                 error "cannot read '${file}'"
15755         oal_expect_entry_count 4
15756
15757         do_facet ost1 lctl set_param "${param}=0"
15758         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15759                 error "cannot create '${file}'"
15760         oal_expect_entry_count 4
15761
15762         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15763                 error "cannot read '${file}'"
15764         oal_expect_entry_count 4
15765 }
15766 run_test 165d "ofd_access_log mask works"
15767
15768 test_169() {
15769         # do directio so as not to populate the page cache
15770         log "creating a 10 Mb file"
15771         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15772                 error "multiop failed while creating a file"
15773         log "starting reads"
15774         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15775         log "truncating the file"
15776         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15777                 error "multiop failed while truncating the file"
15778         log "killing dd"
15779         kill %+ || true # reads might have finished
15780         echo "wait until dd is finished"
15781         wait
15782         log "removing the temporary file"
15783         rm -rf $DIR/$tfile || error "tmp file removal failed"
15784 }
15785 run_test 169 "parallel read and truncate should not deadlock"
15786
15787 test_170() {
15788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15789
15790         $LCTL clear     # bug 18514
15791         $LCTL debug_daemon start $TMP/${tfile}_log_good
15792         touch $DIR/$tfile
15793         $LCTL debug_daemon stop
15794         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15795                 error "sed failed to read log_good"
15796
15797         $LCTL debug_daemon start $TMP/${tfile}_log_good
15798         rm -rf $DIR/$tfile
15799         $LCTL debug_daemon stop
15800
15801         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15802                error "lctl df log_bad failed"
15803
15804         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15805         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15806
15807         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15808         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15809
15810         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15811                 error "bad_line good_line1 good_line2 are empty"
15812
15813         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15814         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15815         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15816
15817         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15818         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15819         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15820
15821         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15822                 error "bad_line_new good_line_new are empty"
15823
15824         local expected_good=$((good_line1 + good_line2*2))
15825
15826         rm -f $TMP/${tfile}*
15827         # LU-231, short malformed line may not be counted into bad lines
15828         if [ $bad_line -ne $bad_line_new ] &&
15829                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15830                 error "expected $bad_line bad lines, but got $bad_line_new"
15831                 return 1
15832         fi
15833
15834         if [ $expected_good -ne $good_line_new ]; then
15835                 error "expected $expected_good good lines, but got $good_line_new"
15836                 return 2
15837         fi
15838         true
15839 }
15840 run_test 170 "test lctl df to handle corrupted log ====================="
15841
15842 test_171() { # bug20592
15843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15844
15845         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15846         $LCTL set_param fail_loc=0x50e
15847         $LCTL set_param fail_val=3000
15848         multiop_bg_pause $DIR/$tfile O_s || true
15849         local MULTIPID=$!
15850         kill -USR1 $MULTIPID
15851         # cause log dump
15852         sleep 3
15853         wait $MULTIPID
15854         if dmesg | grep "recursive fault"; then
15855                 error "caught a recursive fault"
15856         fi
15857         $LCTL set_param fail_loc=0
15858         true
15859 }
15860 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15861
15862 # it would be good to share it with obdfilter-survey/iokit-libecho code
15863 setup_obdecho_osc () {
15864         local rc=0
15865         local ost_nid=$1
15866         local obdfilter_name=$2
15867         echo "Creating new osc for $obdfilter_name on $ost_nid"
15868         # make sure we can find loopback nid
15869         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15870
15871         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15872                            ${obdfilter_name}_osc_UUID || rc=2; }
15873         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15874                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15875         return $rc
15876 }
15877
15878 cleanup_obdecho_osc () {
15879         local obdfilter_name=$1
15880         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15881         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15882         return 0
15883 }
15884
15885 obdecho_test() {
15886         local OBD=$1
15887         local node=$2
15888         local pages=${3:-64}
15889         local rc=0
15890         local id
15891
15892         local count=10
15893         local obd_size=$(get_obd_size $node $OBD)
15894         local page_size=$(get_page_size $node)
15895         if [[ -n "$obd_size" ]]; then
15896                 local new_count=$((obd_size / (pages * page_size / 1024)))
15897                 [[ $new_count -ge $count ]] || count=$new_count
15898         fi
15899
15900         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15901         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15902                            rc=2; }
15903         if [ $rc -eq 0 ]; then
15904             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15905             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15906         fi
15907         echo "New object id is $id"
15908         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15909                            rc=4; }
15910         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15911                            "test_brw $count w v $pages $id" || rc=4; }
15912         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15913                            rc=4; }
15914         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15915                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15916         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15917                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15918         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15919         return $rc
15920 }
15921
15922 test_180a() {
15923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15924
15925         if ! [ -d /sys/fs/lustre/echo_client ] &&
15926            ! module_loaded obdecho; then
15927                 load_module obdecho/obdecho &&
15928                         stack_trap "rmmod obdecho" EXIT ||
15929                         error "unable to load obdecho on client"
15930         fi
15931
15932         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15933         local host=$($LCTL get_param -n osc.$osc.import |
15934                      awk '/current_connection:/ { print $2 }' )
15935         local target=$($LCTL get_param -n osc.$osc.import |
15936                        awk '/target:/ { print $2 }' )
15937         target=${target%_UUID}
15938
15939         if [ -n "$target" ]; then
15940                 setup_obdecho_osc $host $target &&
15941                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15942                         { error "obdecho setup failed with $?"; return; }
15943
15944                 obdecho_test ${target}_osc client ||
15945                         error "obdecho_test failed on ${target}_osc"
15946         else
15947                 $LCTL get_param osc.$osc.import
15948                 error "there is no osc.$osc.import target"
15949         fi
15950 }
15951 run_test 180a "test obdecho on osc"
15952
15953 test_180b() {
15954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15955         remote_ost_nodsh && skip "remote OST with nodsh"
15956
15957         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15958                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15959                 error "failed to load module obdecho"
15960
15961         local target=$(do_facet ost1 $LCTL dl |
15962                        awk '/obdfilter/ { print $4; exit; }')
15963
15964         if [ -n "$target" ]; then
15965                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15966         else
15967                 do_facet ost1 $LCTL dl
15968                 error "there is no obdfilter target on ost1"
15969         fi
15970 }
15971 run_test 180b "test obdecho directly on obdfilter"
15972
15973 test_180c() { # LU-2598
15974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15975         remote_ost_nodsh && skip "remote OST with nodsh"
15976         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15977                 skip "Need MDS version at least 2.4.0"
15978
15979         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15980                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15981                 error "failed to load module obdecho"
15982
15983         local target=$(do_facet ost1 $LCTL dl |
15984                        awk '/obdfilter/ { print $4; exit; }')
15985
15986         if [ -n "$target" ]; then
15987                 local pages=16384 # 64MB bulk I/O RPC size
15988
15989                 obdecho_test "$target" ost1 "$pages" ||
15990                         error "obdecho_test with pages=$pages failed with $?"
15991         else
15992                 do_facet ost1 $LCTL dl
15993                 error "there is no obdfilter target on ost1"
15994         fi
15995 }
15996 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15997
15998 test_181() { # bug 22177
15999         test_mkdir $DIR/$tdir
16000         # create enough files to index the directory
16001         createmany -o $DIR/$tdir/foobar 4000
16002         # print attributes for debug purpose
16003         lsattr -d .
16004         # open dir
16005         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16006         MULTIPID=$!
16007         # remove the files & current working dir
16008         unlinkmany $DIR/$tdir/foobar 4000
16009         rmdir $DIR/$tdir
16010         kill -USR1 $MULTIPID
16011         wait $MULTIPID
16012         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16013         return 0
16014 }
16015 run_test 181 "Test open-unlinked dir ========================"
16016
16017 test_182() {
16018         local fcount=1000
16019         local tcount=10
16020
16021         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16022
16023         $LCTL set_param mdc.*.rpc_stats=clear
16024
16025         for (( i = 0; i < $tcount; i++ )) ; do
16026                 mkdir $DIR/$tdir/$i
16027         done
16028
16029         for (( i = 0; i < $tcount; i++ )) ; do
16030                 createmany -o $DIR/$tdir/$i/f- $fcount &
16031         done
16032         wait
16033
16034         for (( i = 0; i < $tcount; i++ )) ; do
16035                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16036         done
16037         wait
16038
16039         $LCTL get_param mdc.*.rpc_stats
16040
16041         rm -rf $DIR/$tdir
16042 }
16043 run_test 182 "Test parallel modify metadata operations ================"
16044
16045 test_183() { # LU-2275
16046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16047         remote_mds_nodsh && skip "remote MDS with nodsh"
16048         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16049                 skip "Need MDS version at least 2.3.56"
16050
16051         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16052         echo aaa > $DIR/$tdir/$tfile
16053
16054 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16055         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16056
16057         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16058         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16059
16060         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16061
16062         # Flush negative dentry cache
16063         touch $DIR/$tdir/$tfile
16064
16065         # We are not checking for any leaked references here, they'll
16066         # become evident next time we do cleanup with module unload.
16067         rm -rf $DIR/$tdir
16068 }
16069 run_test 183 "No crash or request leak in case of strange dispositions ========"
16070
16071 # test suite 184 is for LU-2016, LU-2017
16072 test_184a() {
16073         check_swap_layouts_support
16074
16075         dir0=$DIR/$tdir/$testnum
16076         test_mkdir -p -c1 $dir0
16077         ref1=/etc/passwd
16078         ref2=/etc/group
16079         file1=$dir0/f1
16080         file2=$dir0/f2
16081         $LFS setstripe -c1 $file1
16082         cp $ref1 $file1
16083         $LFS setstripe -c2 $file2
16084         cp $ref2 $file2
16085         gen1=$($LFS getstripe -g $file1)
16086         gen2=$($LFS getstripe -g $file2)
16087
16088         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16089         gen=$($LFS getstripe -g $file1)
16090         [[ $gen1 != $gen ]] ||
16091                 "Layout generation on $file1 does not change"
16092         gen=$($LFS getstripe -g $file2)
16093         [[ $gen2 != $gen ]] ||
16094                 "Layout generation on $file2 does not change"
16095
16096         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16097         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16098
16099         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16100 }
16101 run_test 184a "Basic layout swap"
16102
16103 test_184b() {
16104         check_swap_layouts_support
16105
16106         dir0=$DIR/$tdir/$testnum
16107         mkdir -p $dir0 || error "creating dir $dir0"
16108         file1=$dir0/f1
16109         file2=$dir0/f2
16110         file3=$dir0/f3
16111         dir1=$dir0/d1
16112         dir2=$dir0/d2
16113         mkdir $dir1 $dir2
16114         $LFS setstripe -c1 $file1
16115         $LFS setstripe -c2 $file2
16116         $LFS setstripe -c1 $file3
16117         chown $RUNAS_ID $file3
16118         gen1=$($LFS getstripe -g $file1)
16119         gen2=$($LFS getstripe -g $file2)
16120
16121         $LFS swap_layouts $dir1 $dir2 &&
16122                 error "swap of directories layouts should fail"
16123         $LFS swap_layouts $dir1 $file1 &&
16124                 error "swap of directory and file layouts should fail"
16125         $RUNAS $LFS swap_layouts $file1 $file2 &&
16126                 error "swap of file we cannot write should fail"
16127         $LFS swap_layouts $file1 $file3 &&
16128                 error "swap of file with different owner should fail"
16129         /bin/true # to clear error code
16130 }
16131 run_test 184b "Forbidden layout swap (will generate errors)"
16132
16133 test_184c() {
16134         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16135         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16136         check_swap_layouts_support
16137         check_swap_layout_no_dom $DIR
16138
16139         local dir0=$DIR/$tdir/$testnum
16140         mkdir -p $dir0 || error "creating dir $dir0"
16141
16142         local ref1=$dir0/ref1
16143         local ref2=$dir0/ref2
16144         local file1=$dir0/file1
16145         local file2=$dir0/file2
16146         # create a file large enough for the concurrent test
16147         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16148         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16149         echo "ref file size: ref1($(stat -c %s $ref1))," \
16150              "ref2($(stat -c %s $ref2))"
16151
16152         cp $ref2 $file2
16153         dd if=$ref1 of=$file1 bs=16k &
16154         local DD_PID=$!
16155
16156         # Make sure dd starts to copy file, but wait at most 5 seconds
16157         local loops=0
16158         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16159
16160         $LFS swap_layouts $file1 $file2
16161         local rc=$?
16162         wait $DD_PID
16163         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16164         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16165
16166         # how many bytes copied before swapping layout
16167         local copied=$(stat -c %s $file2)
16168         local remaining=$(stat -c %s $ref1)
16169         remaining=$((remaining - copied))
16170         echo "Copied $copied bytes before swapping layout..."
16171
16172         cmp -n $copied $file1 $ref2 | grep differ &&
16173                 error "Content mismatch [0, $copied) of ref2 and file1"
16174         cmp -n $copied $file2 $ref1 ||
16175                 error "Content mismatch [0, $copied) of ref1 and file2"
16176         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16177                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16178
16179         # clean up
16180         rm -f $ref1 $ref2 $file1 $file2
16181 }
16182 run_test 184c "Concurrent write and layout swap"
16183
16184 test_184d() {
16185         check_swap_layouts_support
16186         check_swap_layout_no_dom $DIR
16187         [ -z "$(which getfattr 2>/dev/null)" ] &&
16188                 skip_env "no getfattr command"
16189
16190         local file1=$DIR/$tdir/$tfile-1
16191         local file2=$DIR/$tdir/$tfile-2
16192         local file3=$DIR/$tdir/$tfile-3
16193         local lovea1
16194         local lovea2
16195
16196         mkdir -p $DIR/$tdir
16197         touch $file1 || error "create $file1 failed"
16198         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16199                 error "create $file2 failed"
16200         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16201                 error "create $file3 failed"
16202         lovea1=$(get_layout_param $file1)
16203
16204         $LFS swap_layouts $file2 $file3 ||
16205                 error "swap $file2 $file3 layouts failed"
16206         $LFS swap_layouts $file1 $file2 ||
16207                 error "swap $file1 $file2 layouts failed"
16208
16209         lovea2=$(get_layout_param $file2)
16210         echo "$lovea1"
16211         echo "$lovea2"
16212         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16213
16214         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16215         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16216 }
16217 run_test 184d "allow stripeless layouts swap"
16218
16219 test_184e() {
16220         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16221                 skip "Need MDS version at least 2.6.94"
16222         check_swap_layouts_support
16223         check_swap_layout_no_dom $DIR
16224         [ -z "$(which getfattr 2>/dev/null)" ] &&
16225                 skip_env "no getfattr command"
16226
16227         local file1=$DIR/$tdir/$tfile-1
16228         local file2=$DIR/$tdir/$tfile-2
16229         local file3=$DIR/$tdir/$tfile-3
16230         local lovea
16231
16232         mkdir -p $DIR/$tdir
16233         touch $file1 || error "create $file1 failed"
16234         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16235                 error "create $file2 failed"
16236         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16237                 error "create $file3 failed"
16238
16239         $LFS swap_layouts $file1 $file2 ||
16240                 error "swap $file1 $file2 layouts failed"
16241
16242         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16243         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16244
16245         echo 123 > $file1 || error "Should be able to write into $file1"
16246
16247         $LFS swap_layouts $file1 $file3 ||
16248                 error "swap $file1 $file3 layouts failed"
16249
16250         echo 123 > $file1 || error "Should be able to write into $file1"
16251
16252         rm -rf $file1 $file2 $file3
16253 }
16254 run_test 184e "Recreate layout after stripeless layout swaps"
16255
16256 test_184f() {
16257         # Create a file with name longer than sizeof(struct stat) ==
16258         # 144 to see if we can get chars from the file name to appear
16259         # in the returned striping. Note that 'f' == 0x66.
16260         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16261
16262         mkdir -p $DIR/$tdir
16263         mcreate $DIR/$tdir/$file
16264         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16265                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16266         fi
16267 }
16268 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16269
16270 test_185() { # LU-2441
16271         # LU-3553 - no volatile file support in old servers
16272         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16273                 skip "Need MDS version at least 2.3.60"
16274
16275         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16276         touch $DIR/$tdir/spoo
16277         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16278         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16279                 error "cannot create/write a volatile file"
16280         [ "$FILESET" == "" ] &&
16281         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16282                 error "FID is still valid after close"
16283
16284         multiop_bg_pause $DIR/$tdir vVw4096_c
16285         local multi_pid=$!
16286
16287         local OLD_IFS=$IFS
16288         IFS=":"
16289         local fidv=($fid)
16290         IFS=$OLD_IFS
16291         # assume that the next FID for this client is sequential, since stdout
16292         # is unfortunately eaten by multiop_bg_pause
16293         local n=$((${fidv[1]} + 1))
16294         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16295         if [ "$FILESET" == "" ]; then
16296                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16297                         error "FID is missing before close"
16298         fi
16299         kill -USR1 $multi_pid
16300         # 1 second delay, so if mtime change we will see it
16301         sleep 1
16302         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16303         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16304 }
16305 run_test 185 "Volatile file support"
16306
16307 function create_check_volatile() {
16308         local idx=$1
16309         local tgt
16310
16311         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16312         local PID=$!
16313         sleep 1
16314         local FID=$(cat /tmp/${tfile}.fid)
16315         [ "$FID" == "" ] && error "can't get FID for volatile"
16316         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16317         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16318         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16319         kill -USR1 $PID
16320         wait
16321         sleep 1
16322         cancel_lru_locks mdc # flush opencache
16323         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16324         return 0
16325 }
16326
16327 test_185a(){
16328         # LU-12516 - volatile creation via .lustre
16329         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16330                 skip "Need MDS version at least 2.3.55"
16331
16332         create_check_volatile 0
16333         [ $MDSCOUNT -lt 2 ] && return 0
16334
16335         # DNE case
16336         create_check_volatile 1
16337
16338         return 0
16339 }
16340 run_test 185a "Volatile file creation in .lustre/fid/"
16341
16342 test_187a() {
16343         remote_mds_nodsh && skip "remote MDS with nodsh"
16344         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16345                 skip "Need MDS version at least 2.3.0"
16346
16347         local dir0=$DIR/$tdir/$testnum
16348         mkdir -p $dir0 || error "creating dir $dir0"
16349
16350         local file=$dir0/file1
16351         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16352         local dv1=$($LFS data_version $file)
16353         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16354         local dv2=$($LFS data_version $file)
16355         [[ $dv1 != $dv2 ]] ||
16356                 error "data version did not change on write $dv1 == $dv2"
16357
16358         # clean up
16359         rm -f $file1
16360 }
16361 run_test 187a "Test data version change"
16362
16363 test_187b() {
16364         remote_mds_nodsh && skip "remote MDS with nodsh"
16365         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16366                 skip "Need MDS version at least 2.3.0"
16367
16368         local dir0=$DIR/$tdir/$testnum
16369         mkdir -p $dir0 || error "creating dir $dir0"
16370
16371         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16372         [[ ${DV[0]} != ${DV[1]} ]] ||
16373                 error "data version did not change on write"\
16374                       " ${DV[0]} == ${DV[1]}"
16375
16376         # clean up
16377         rm -f $file1
16378 }
16379 run_test 187b "Test data version change on volatile file"
16380
16381 test_200() {
16382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16383         remote_mgs_nodsh && skip "remote MGS with nodsh"
16384         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16385
16386         local POOL=${POOL:-cea1}
16387         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16388         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16389         # Pool OST targets
16390         local first_ost=0
16391         local last_ost=$(($OSTCOUNT - 1))
16392         local ost_step=2
16393         local ost_list=$(seq $first_ost $ost_step $last_ost)
16394         local ost_range="$first_ost $last_ost $ost_step"
16395         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16396         local file_dir=$POOL_ROOT/file_tst
16397         local subdir=$test_path/subdir
16398         local rc=0
16399
16400         while : ; do
16401                 # former test_200a test_200b
16402                 pool_add $POOL                          || { rc=$? ; break; }
16403                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16404                 # former test_200c test_200d
16405                 mkdir -p $test_path
16406                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16407                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16408                 mkdir -p $subdir
16409                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16410                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16411                                                         || { rc=$? ; break; }
16412                 # former test_200e test_200f
16413                 local files=$((OSTCOUNT*3))
16414                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16415                                                         || { rc=$? ; break; }
16416                 pool_create_files $POOL $file_dir $files "$ost_list" \
16417                                                         || { rc=$? ; break; }
16418                 # former test_200g test_200h
16419                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16420                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16421
16422                 # former test_201a test_201b test_201c
16423                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16424
16425                 local f=$test_path/$tfile
16426                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16427                 pool_remove $POOL $f                    || { rc=$? ; break; }
16428                 break
16429         done
16430
16431         destroy_test_pools
16432
16433         return $rc
16434 }
16435 run_test 200 "OST pools"
16436
16437 # usage: default_attr <count | size | offset>
16438 default_attr() {
16439         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16440 }
16441
16442 # usage: check_default_stripe_attr
16443 check_default_stripe_attr() {
16444         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16445         case $1 in
16446         --stripe-count|-c)
16447                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16448         --stripe-size|-S)
16449                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16450         --stripe-index|-i)
16451                 EXPECTED=-1;;
16452         *)
16453                 error "unknown getstripe attr '$1'"
16454         esac
16455
16456         [ $ACTUAL == $EXPECTED ] ||
16457                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16458 }
16459
16460 test_204a() {
16461         test_mkdir $DIR/$tdir
16462         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16463
16464         check_default_stripe_attr --stripe-count
16465         check_default_stripe_attr --stripe-size
16466         check_default_stripe_attr --stripe-index
16467 }
16468 run_test 204a "Print default stripe attributes"
16469
16470 test_204b() {
16471         test_mkdir $DIR/$tdir
16472         $LFS setstripe --stripe-count 1 $DIR/$tdir
16473
16474         check_default_stripe_attr --stripe-size
16475         check_default_stripe_attr --stripe-index
16476 }
16477 run_test 204b "Print default stripe size and offset"
16478
16479 test_204c() {
16480         test_mkdir $DIR/$tdir
16481         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16482
16483         check_default_stripe_attr --stripe-count
16484         check_default_stripe_attr --stripe-index
16485 }
16486 run_test 204c "Print default stripe count and offset"
16487
16488 test_204d() {
16489         test_mkdir $DIR/$tdir
16490         $LFS setstripe --stripe-index 0 $DIR/$tdir
16491
16492         check_default_stripe_attr --stripe-count
16493         check_default_stripe_attr --stripe-size
16494 }
16495 run_test 204d "Print default stripe count and size"
16496
16497 test_204e() {
16498         test_mkdir $DIR/$tdir
16499         $LFS setstripe -d $DIR/$tdir
16500
16501         check_default_stripe_attr --stripe-count --raw
16502         check_default_stripe_attr --stripe-size --raw
16503         check_default_stripe_attr --stripe-index --raw
16504 }
16505 run_test 204e "Print raw stripe attributes"
16506
16507 test_204f() {
16508         test_mkdir $DIR/$tdir
16509         $LFS setstripe --stripe-count 1 $DIR/$tdir
16510
16511         check_default_stripe_attr --stripe-size --raw
16512         check_default_stripe_attr --stripe-index --raw
16513 }
16514 run_test 204f "Print raw stripe size and offset"
16515
16516 test_204g() {
16517         test_mkdir $DIR/$tdir
16518         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16519
16520         check_default_stripe_attr --stripe-count --raw
16521         check_default_stripe_attr --stripe-index --raw
16522 }
16523 run_test 204g "Print raw stripe count and offset"
16524
16525 test_204h() {
16526         test_mkdir $DIR/$tdir
16527         $LFS setstripe --stripe-index 0 $DIR/$tdir
16528
16529         check_default_stripe_attr --stripe-count --raw
16530         check_default_stripe_attr --stripe-size --raw
16531 }
16532 run_test 204h "Print raw stripe count and size"
16533
16534 # Figure out which job scheduler is being used, if any,
16535 # or use a fake one
16536 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16537         JOBENV=SLURM_JOB_ID
16538 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16539         JOBENV=LSB_JOBID
16540 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16541         JOBENV=PBS_JOBID
16542 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16543         JOBENV=LOADL_STEP_ID
16544 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16545         JOBENV=JOB_ID
16546 else
16547         $LCTL list_param jobid_name > /dev/null 2>&1
16548         if [ $? -eq 0 ]; then
16549                 JOBENV=nodelocal
16550         else
16551                 JOBENV=FAKE_JOBID
16552         fi
16553 fi
16554 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16555
16556 verify_jobstats() {
16557         local cmd=($1)
16558         shift
16559         local facets="$@"
16560
16561 # we don't really need to clear the stats for this test to work, since each
16562 # command has a unique jobid, but it makes debugging easier if needed.
16563 #       for facet in $facets; do
16564 #               local dev=$(convert_facet2label $facet)
16565 #               # clear old jobstats
16566 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16567 #       done
16568
16569         # use a new JobID for each test, or we might see an old one
16570         [ "$JOBENV" = "FAKE_JOBID" ] &&
16571                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16572
16573         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16574
16575         [ "$JOBENV" = "nodelocal" ] && {
16576                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16577                 $LCTL set_param jobid_name=$FAKE_JOBID
16578                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16579         }
16580
16581         log "Test: ${cmd[*]}"
16582         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16583
16584         if [ $JOBENV = "FAKE_JOBID" ]; then
16585                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16586         else
16587                 ${cmd[*]}
16588         fi
16589
16590         # all files are created on OST0000
16591         for facet in $facets; do
16592                 local stats="*.$(convert_facet2label $facet).job_stats"
16593
16594                 # strip out libtool wrappers for in-tree executables
16595                 if [ $(do_facet $facet lctl get_param $stats |
16596                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16597                         do_facet $facet lctl get_param $stats
16598                         error "No jobstats for $JOBVAL found on $facet::$stats"
16599                 fi
16600         done
16601 }
16602
16603 jobstats_set() {
16604         local new_jobenv=$1
16605
16606         set_persistent_param_and_check client "jobid_var" \
16607                 "$FSNAME.sys.jobid_var" $new_jobenv
16608 }
16609
16610 test_205a() { # Job stats
16611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16612         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16613                 skip "Need MDS version with at least 2.7.1"
16614         remote_mgs_nodsh && skip "remote MGS with nodsh"
16615         remote_mds_nodsh && skip "remote MDS with nodsh"
16616         remote_ost_nodsh && skip "remote OST with nodsh"
16617         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16618                 skip "Server doesn't support jobstats"
16619         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16620
16621         local old_jobenv=$($LCTL get_param -n jobid_var)
16622         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16623
16624         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16625                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16626         else
16627                 stack_trap "do_facet mgs $PERM_CMD \
16628                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16629         fi
16630         changelog_register
16631
16632         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16633                                 mdt.*.job_cleanup_interval | head -n 1)
16634         local new_interval=5
16635         do_facet $SINGLEMDS \
16636                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16637         stack_trap "do_facet $SINGLEMDS \
16638                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16639         local start=$SECONDS
16640
16641         local cmd
16642         # mkdir
16643         cmd="mkdir $DIR/$tdir"
16644         verify_jobstats "$cmd" "$SINGLEMDS"
16645         # rmdir
16646         cmd="rmdir $DIR/$tdir"
16647         verify_jobstats "$cmd" "$SINGLEMDS"
16648         # mkdir on secondary MDT
16649         if [ $MDSCOUNT -gt 1 ]; then
16650                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16651                 verify_jobstats "$cmd" "mds2"
16652         fi
16653         # mknod
16654         cmd="mknod $DIR/$tfile c 1 3"
16655         verify_jobstats "$cmd" "$SINGLEMDS"
16656         # unlink
16657         cmd="rm -f $DIR/$tfile"
16658         verify_jobstats "$cmd" "$SINGLEMDS"
16659         # create all files on OST0000 so verify_jobstats can find OST stats
16660         # open & close
16661         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16662         verify_jobstats "$cmd" "$SINGLEMDS"
16663         # setattr
16664         cmd="touch $DIR/$tfile"
16665         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16666         # write
16667         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16668         verify_jobstats "$cmd" "ost1"
16669         # read
16670         cancel_lru_locks osc
16671         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16672         verify_jobstats "$cmd" "ost1"
16673         # truncate
16674         cmd="$TRUNCATE $DIR/$tfile 0"
16675         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16676         # rename
16677         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16678         verify_jobstats "$cmd" "$SINGLEMDS"
16679         # jobstats expiry - sleep until old stats should be expired
16680         local left=$((new_interval + 5 - (SECONDS - start)))
16681         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16682                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16683                         "0" $left
16684         cmd="mkdir $DIR/$tdir.expire"
16685         verify_jobstats "$cmd" "$SINGLEMDS"
16686         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16687             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16688
16689         # Ensure that jobid are present in changelog (if supported by MDS)
16690         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16691                 changelog_dump | tail -10
16692                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16693                 [ $jobids -eq 9 ] ||
16694                         error "Wrong changelog jobid count $jobids != 9"
16695
16696                 # LU-5862
16697                 JOBENV="disable"
16698                 jobstats_set $JOBENV
16699                 touch $DIR/$tfile
16700                 changelog_dump | grep $tfile
16701                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16702                 [ $jobids -eq 0 ] ||
16703                         error "Unexpected jobids when jobid_var=$JOBENV"
16704         fi
16705
16706         # test '%j' access to environment variable - if supported
16707         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16708                 JOBENV="JOBCOMPLEX"
16709                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16710
16711                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16712         fi
16713
16714         # test '%j' access to per-session jobid - if supported
16715         if lctl list_param jobid_this_session > /dev/null 2>&1
16716         then
16717                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16718                 lctl set_param jobid_this_session=$USER
16719
16720                 JOBENV="JOBCOMPLEX"
16721                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16722
16723                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16724         fi
16725 }
16726 run_test 205a "Verify job stats"
16727
16728 # LU-13117, LU-13597
16729 test_205b() {
16730         job_stats="mdt.*.job_stats"
16731         $LCTL set_param $job_stats=clear
16732         # Setting jobid_var to USER might not be supported
16733         $LCTL set_param jobid_var=USER || true
16734         $LCTL set_param jobid_name="%e.%u"
16735         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16736         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16737                 grep "job_id:.*foolish" &&
16738                         error "Unexpected jobid found"
16739         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16740                 grep "open:.*min.*max.*sum" ||
16741                         error "wrong job_stats format found"
16742 }
16743 run_test 205b "Verify job stats jobid and output format"
16744
16745 # LU-13733
16746 test_205c() {
16747         $LCTL set_param llite.*.stats=0
16748         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16749         $LCTL get_param llite.*.stats
16750         $LCTL get_param llite.*.stats | grep \
16751                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16752                         error "wrong client stats format found"
16753 }
16754 run_test 205c "Verify client stats format"
16755
16756 # LU-1480, LU-1773 and LU-1657
16757 test_206() {
16758         mkdir -p $DIR/$tdir
16759         $LFS setstripe -c -1 $DIR/$tdir
16760 #define OBD_FAIL_LOV_INIT 0x1403
16761         $LCTL set_param fail_loc=0xa0001403
16762         $LCTL set_param fail_val=1
16763         touch $DIR/$tdir/$tfile || true
16764 }
16765 run_test 206 "fail lov_init_raid0() doesn't lbug"
16766
16767 test_207a() {
16768         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16769         local fsz=`stat -c %s $DIR/$tfile`
16770         cancel_lru_locks mdc
16771
16772         # do not return layout in getattr intent
16773 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16774         $LCTL set_param fail_loc=0x170
16775         local sz=`stat -c %s $DIR/$tfile`
16776
16777         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16778
16779         rm -rf $DIR/$tfile
16780 }
16781 run_test 207a "can refresh layout at glimpse"
16782
16783 test_207b() {
16784         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16785         local cksum=`md5sum $DIR/$tfile`
16786         local fsz=`stat -c %s $DIR/$tfile`
16787         cancel_lru_locks mdc
16788         cancel_lru_locks osc
16789
16790         # do not return layout in getattr intent
16791 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16792         $LCTL set_param fail_loc=0x171
16793
16794         # it will refresh layout after the file is opened but before read issues
16795         echo checksum is "$cksum"
16796         echo "$cksum" |md5sum -c --quiet || error "file differs"
16797
16798         rm -rf $DIR/$tfile
16799 }
16800 run_test 207b "can refresh layout at open"
16801
16802 test_208() {
16803         # FIXME: in this test suite, only RD lease is used. This is okay
16804         # for now as only exclusive open is supported. After generic lease
16805         # is done, this test suite should be revised. - Jinshan
16806
16807         remote_mds_nodsh && skip "remote MDS with nodsh"
16808         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16809                 skip "Need MDS version at least 2.4.52"
16810
16811         echo "==== test 1: verify get lease work"
16812         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16813
16814         echo "==== test 2: verify lease can be broken by upcoming open"
16815         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16816         local PID=$!
16817         sleep 1
16818
16819         $MULTIOP $DIR/$tfile oO_RDONLY:c
16820         kill -USR1 $PID && wait $PID || error "break lease error"
16821
16822         echo "==== test 3: verify lease can't be granted if an open already exists"
16823         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16824         local PID=$!
16825         sleep 1
16826
16827         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16828         kill -USR1 $PID && wait $PID || error "open file error"
16829
16830         echo "==== test 4: lease can sustain over recovery"
16831         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16832         PID=$!
16833         sleep 1
16834
16835         fail mds1
16836
16837         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16838
16839         echo "==== test 5: lease broken can't be regained by replay"
16840         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16841         PID=$!
16842         sleep 1
16843
16844         # open file to break lease and then recovery
16845         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16846         fail mds1
16847
16848         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16849
16850         rm -f $DIR/$tfile
16851 }
16852 run_test 208 "Exclusive open"
16853
16854 test_209() {
16855         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16856                 skip_env "must have disp_stripe"
16857
16858         touch $DIR/$tfile
16859         sync; sleep 5; sync;
16860
16861         echo 3 > /proc/sys/vm/drop_caches
16862         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16863                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16864         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16865
16866         # open/close 500 times
16867         for i in $(seq 500); do
16868                 cat $DIR/$tfile
16869         done
16870
16871         echo 3 > /proc/sys/vm/drop_caches
16872         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16873                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16874         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16875
16876         echo "before: $req_before, after: $req_after"
16877         [ $((req_after - req_before)) -ge 300 ] &&
16878                 error "open/close requests are not freed"
16879         return 0
16880 }
16881 run_test 209 "read-only open/close requests should be freed promptly"
16882
16883 test_210() {
16884         local pid
16885
16886         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16887         pid=$!
16888         sleep 1
16889
16890         $LFS getstripe $DIR/$tfile
16891         kill -USR1 $pid
16892         wait $pid || error "multiop failed"
16893
16894         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16895         pid=$!
16896         sleep 1
16897
16898         $LFS getstripe $DIR/$tfile
16899         kill -USR1 $pid
16900         wait $pid || error "multiop failed"
16901 }
16902 run_test 210 "lfs getstripe does not break leases"
16903
16904 test_212() {
16905         size=`date +%s`
16906         size=$((size % 8192 + 1))
16907         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16908         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16909         rm -f $DIR/f212 $DIR/f212.xyz
16910 }
16911 run_test 212 "Sendfile test ============================================"
16912
16913 test_213() {
16914         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16915         cancel_lru_locks osc
16916         lctl set_param fail_loc=0x8000040f
16917         # generate a read lock
16918         cat $DIR/$tfile > /dev/null
16919         # write to the file, it will try to cancel the above read lock.
16920         cat /etc/hosts >> $DIR/$tfile
16921 }
16922 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16923
16924 test_214() { # for bug 20133
16925         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16926         for (( i=0; i < 340; i++ )) ; do
16927                 touch $DIR/$tdir/d214c/a$i
16928         done
16929
16930         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16931         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16932         ls $DIR/d214c || error "ls $DIR/d214c failed"
16933         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16934         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16935 }
16936 run_test 214 "hash-indexed directory test - bug 20133"
16937
16938 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16939 create_lnet_proc_files() {
16940         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16941 }
16942
16943 # counterpart of create_lnet_proc_files
16944 remove_lnet_proc_files() {
16945         rm -f $TMP/lnet_$1.sys
16946 }
16947
16948 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16949 # 3rd arg as regexp for body
16950 check_lnet_proc_stats() {
16951         local l=$(cat "$TMP/lnet_$1" |wc -l)
16952         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16953
16954         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16955 }
16956
16957 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16958 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16959 # optional and can be regexp for 2nd line (lnet.routes case)
16960 check_lnet_proc_entry() {
16961         local blp=2          # blp stands for 'position of 1st line of body'
16962         [ -z "$5" ] || blp=3 # lnet.routes case
16963
16964         local l=$(cat "$TMP/lnet_$1" |wc -l)
16965         # subtracting one from $blp because the body can be empty
16966         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16967
16968         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16969                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16970
16971         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16972                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16973
16974         # bail out if any unexpected line happened
16975         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16976         [ "$?" != 0 ] || error "$2 misformatted"
16977 }
16978
16979 test_215() { # for bugs 18102, 21079, 21517
16980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16981
16982         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16983         local P='[1-9][0-9]*'           # positive numeric
16984         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16985         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16986         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16987         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16988
16989         local L1 # regexp for 1st line
16990         local L2 # regexp for 2nd line (optional)
16991         local BR # regexp for the rest (body)
16992
16993         # lnet.stats should look as 11 space-separated non-negative numerics
16994         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16995         create_lnet_proc_files "stats"
16996         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16997         remove_lnet_proc_files "stats"
16998
16999         # lnet.routes should look like this:
17000         # Routing disabled/enabled
17001         # net hops priority state router
17002         # where net is a string like tcp0, hops > 0, priority >= 0,
17003         # state is up/down,
17004         # router is a string like 192.168.1.1@tcp2
17005         L1="^Routing (disabled|enabled)$"
17006         L2="^net +hops +priority +state +router$"
17007         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17008         create_lnet_proc_files "routes"
17009         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17010         remove_lnet_proc_files "routes"
17011
17012         # lnet.routers should look like this:
17013         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17014         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17015         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17016         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17017         L1="^ref +rtr_ref +alive +router$"
17018         BR="^$P +$P +(up|down) +$NID$"
17019         create_lnet_proc_files "routers"
17020         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17021         remove_lnet_proc_files "routers"
17022
17023         # lnet.peers should look like this:
17024         # nid refs state last max rtr min tx min queue
17025         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17026         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17027         # numeric (0 or >0 or <0), queue >= 0.
17028         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17029         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17030         create_lnet_proc_files "peers"
17031         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17032         remove_lnet_proc_files "peers"
17033
17034         # lnet.buffers  should look like this:
17035         # pages count credits min
17036         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17037         L1="^pages +count +credits +min$"
17038         BR="^ +$N +$N +$I +$I$"
17039         create_lnet_proc_files "buffers"
17040         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17041         remove_lnet_proc_files "buffers"
17042
17043         # lnet.nis should look like this:
17044         # nid status alive refs peer rtr max tx min
17045         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17046         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17047         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17048         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17049         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17050         create_lnet_proc_files "nis"
17051         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17052         remove_lnet_proc_files "nis"
17053
17054         # can we successfully write to lnet.stats?
17055         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17056 }
17057 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17058
17059 test_216() { # bug 20317
17060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17061         remote_ost_nodsh && skip "remote OST with nodsh"
17062
17063         local node
17064         local facets=$(get_facets OST)
17065         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17066
17067         save_lustre_params client "osc.*.contention_seconds" > $p
17068         save_lustre_params $facets \
17069                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17070         save_lustre_params $facets \
17071                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17072         save_lustre_params $facets \
17073                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17074         clear_stats osc.*.osc_stats
17075
17076         # agressive lockless i/o settings
17077         do_nodes $(comma_list $(osts_nodes)) \
17078                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17079                         ldlm.namespaces.filter-*.contended_locks=0 \
17080                         ldlm.namespaces.filter-*.contention_seconds=60"
17081         lctl set_param -n osc.*.contention_seconds=60
17082
17083         $DIRECTIO write $DIR/$tfile 0 10 4096
17084         $CHECKSTAT -s 40960 $DIR/$tfile
17085
17086         # disable lockless i/o
17087         do_nodes $(comma_list $(osts_nodes)) \
17088                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17089                         ldlm.namespaces.filter-*.contended_locks=32 \
17090                         ldlm.namespaces.filter-*.contention_seconds=0"
17091         lctl set_param -n osc.*.contention_seconds=0
17092         clear_stats osc.*.osc_stats
17093
17094         dd if=/dev/zero of=$DIR/$tfile count=0
17095         $CHECKSTAT -s 0 $DIR/$tfile
17096
17097         restore_lustre_params <$p
17098         rm -f $p
17099         rm $DIR/$tfile
17100 }
17101 run_test 216 "check lockless direct write updates file size and kms correctly"
17102
17103 test_217() { # bug 22430
17104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17105
17106         local node
17107         local nid
17108
17109         for node in $(nodes_list); do
17110                 nid=$(host_nids_address $node $NETTYPE)
17111                 if [[ $nid = *-* ]] ; then
17112                         echo "lctl ping $(h2nettype $nid)"
17113                         lctl ping $(h2nettype $nid)
17114                 else
17115                         echo "skipping $node (no hyphen detected)"
17116                 fi
17117         done
17118 }
17119 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17120
17121 test_218() {
17122        # do directio so as not to populate the page cache
17123        log "creating a 10 Mb file"
17124        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17125        log "starting reads"
17126        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17127        log "truncating the file"
17128        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17129        log "killing dd"
17130        kill %+ || true # reads might have finished
17131        echo "wait until dd is finished"
17132        wait
17133        log "removing the temporary file"
17134        rm -rf $DIR/$tfile || error "tmp file removal failed"
17135 }
17136 run_test 218 "parallel read and truncate should not deadlock"
17137
17138 test_219() {
17139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17140
17141         # write one partial page
17142         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17143         # set no grant so vvp_io_commit_write will do sync write
17144         $LCTL set_param fail_loc=0x411
17145         # write a full page at the end of file
17146         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17147
17148         $LCTL set_param fail_loc=0
17149         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17150         $LCTL set_param fail_loc=0x411
17151         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17152
17153         # LU-4201
17154         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17155         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17156 }
17157 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17158
17159 test_220() { #LU-325
17160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17161         remote_ost_nodsh && skip "remote OST with nodsh"
17162         remote_mds_nodsh && skip "remote MDS with nodsh"
17163         remote_mgs_nodsh && skip "remote MGS with nodsh"
17164
17165         local OSTIDX=0
17166
17167         # create on MDT0000 so the last_id and next_id are correct
17168         mkdir $DIR/$tdir
17169         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17170         OST=${OST%_UUID}
17171
17172         # on the mdt's osc
17173         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17174         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17175                         osp.$mdtosc_proc1.prealloc_last_id)
17176         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17177                         osp.$mdtosc_proc1.prealloc_next_id)
17178
17179         $LFS df -i
17180
17181         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17182         #define OBD_FAIL_OST_ENOINO              0x229
17183         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17184         create_pool $FSNAME.$TESTNAME || return 1
17185         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17186
17187         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17188
17189         MDSOBJS=$((last_id - next_id))
17190         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17191
17192         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17193         echo "OST still has $count kbytes free"
17194
17195         echo "create $MDSOBJS files @next_id..."
17196         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17197
17198         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17199                         osp.$mdtosc_proc1.prealloc_last_id)
17200         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17201                         osp.$mdtosc_proc1.prealloc_next_id)
17202
17203         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17204         $LFS df -i
17205
17206         echo "cleanup..."
17207
17208         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17209         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17210
17211         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17212                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17213         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17214                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17215         echo "unlink $MDSOBJS files @$next_id..."
17216         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17217 }
17218 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17219
17220 test_221() {
17221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17222
17223         dd if=`which date` of=$MOUNT/date oflag=sync
17224         chmod +x $MOUNT/date
17225
17226         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17227         $LCTL set_param fail_loc=0x80001401
17228
17229         $MOUNT/date > /dev/null
17230         rm -f $MOUNT/date
17231 }
17232 run_test 221 "make sure fault and truncate race to not cause OOM"
17233
17234 test_222a () {
17235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17236
17237         rm -rf $DIR/$tdir
17238         test_mkdir $DIR/$tdir
17239         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17240         createmany -o $DIR/$tdir/$tfile 10
17241         cancel_lru_locks mdc
17242         cancel_lru_locks osc
17243         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17244         $LCTL set_param fail_loc=0x31a
17245         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17246         $LCTL set_param fail_loc=0
17247         rm -r $DIR/$tdir
17248 }
17249 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17250
17251 test_222b () {
17252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17253
17254         rm -rf $DIR/$tdir
17255         test_mkdir $DIR/$tdir
17256         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17257         createmany -o $DIR/$tdir/$tfile 10
17258         cancel_lru_locks mdc
17259         cancel_lru_locks osc
17260         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17261         $LCTL set_param fail_loc=0x31a
17262         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17263         $LCTL set_param fail_loc=0
17264 }
17265 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17266
17267 test_223 () {
17268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17269
17270         rm -rf $DIR/$tdir
17271         test_mkdir $DIR/$tdir
17272         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17273         createmany -o $DIR/$tdir/$tfile 10
17274         cancel_lru_locks mdc
17275         cancel_lru_locks osc
17276         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17277         $LCTL set_param fail_loc=0x31b
17278         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17279         $LCTL set_param fail_loc=0
17280         rm -r $DIR/$tdir
17281 }
17282 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17283
17284 test_224a() { # LU-1039, MRP-303
17285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17286
17287         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17288         $LCTL set_param fail_loc=0x508
17289         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17290         $LCTL set_param fail_loc=0
17291         df $DIR
17292 }
17293 run_test 224a "Don't panic on bulk IO failure"
17294
17295 test_224b() { # LU-1039, MRP-303
17296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17297
17298         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17299         cancel_lru_locks osc
17300         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17301         $LCTL set_param fail_loc=0x515
17302         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17303         $LCTL set_param fail_loc=0
17304         df $DIR
17305 }
17306 run_test 224b "Don't panic on bulk IO failure"
17307
17308 test_224c() { # LU-6441
17309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17310         remote_mds_nodsh && skip "remote MDS with nodsh"
17311
17312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17313         save_writethrough $p
17314         set_cache writethrough on
17315
17316         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17317         local at_max=$($LCTL get_param -n at_max)
17318         local timeout=$($LCTL get_param -n timeout)
17319         local test_at="at_max"
17320         local param_at="$FSNAME.sys.at_max"
17321         local test_timeout="timeout"
17322         local param_timeout="$FSNAME.sys.timeout"
17323
17324         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17325
17326         set_persistent_param_and_check client "$test_at" "$param_at" 0
17327         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17328
17329         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17330         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17331         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17332         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17333         sync
17334         do_facet ost1 "$LCTL set_param fail_loc=0"
17335
17336         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17337         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17338                 $timeout
17339
17340         $LCTL set_param -n $pages_per_rpc
17341         restore_lustre_params < $p
17342         rm -f $p
17343 }
17344 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17345
17346 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17347 test_225a () {
17348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17349         if [ -z ${MDSSURVEY} ]; then
17350                 skip_env "mds-survey not found"
17351         fi
17352         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17353                 skip "Need MDS version at least 2.2.51"
17354
17355         local mds=$(facet_host $SINGLEMDS)
17356         local target=$(do_nodes $mds 'lctl dl' |
17357                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17358
17359         local cmd1="file_count=1000 thrhi=4"
17360         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17361         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17362         local cmd="$cmd1 $cmd2 $cmd3"
17363
17364         rm -f ${TMP}/mds_survey*
17365         echo + $cmd
17366         eval $cmd || error "mds-survey with zero-stripe failed"
17367         cat ${TMP}/mds_survey*
17368         rm -f ${TMP}/mds_survey*
17369 }
17370 run_test 225a "Metadata survey sanity with zero-stripe"
17371
17372 test_225b () {
17373         if [ -z ${MDSSURVEY} ]; then
17374                 skip_env "mds-survey not found"
17375         fi
17376         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17377                 skip "Need MDS version at least 2.2.51"
17378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17379         remote_mds_nodsh && skip "remote MDS with nodsh"
17380         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17381                 skip_env "Need to mount OST to test"
17382         fi
17383
17384         local mds=$(facet_host $SINGLEMDS)
17385         local target=$(do_nodes $mds 'lctl dl' |
17386                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17387
17388         local cmd1="file_count=1000 thrhi=4"
17389         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17390         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17391         local cmd="$cmd1 $cmd2 $cmd3"
17392
17393         rm -f ${TMP}/mds_survey*
17394         echo + $cmd
17395         eval $cmd || error "mds-survey with stripe_count failed"
17396         cat ${TMP}/mds_survey*
17397         rm -f ${TMP}/mds_survey*
17398 }
17399 run_test 225b "Metadata survey sanity with stripe_count = 1"
17400
17401 mcreate_path2fid () {
17402         local mode=$1
17403         local major=$2
17404         local minor=$3
17405         local name=$4
17406         local desc=$5
17407         local path=$DIR/$tdir/$name
17408         local fid
17409         local rc
17410         local fid_path
17411
17412         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17413                 error "cannot create $desc"
17414
17415         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17416         rc=$?
17417         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17418
17419         fid_path=$($LFS fid2path $MOUNT $fid)
17420         rc=$?
17421         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17422
17423         [ "$path" == "$fid_path" ] ||
17424                 error "fid2path returned $fid_path, expected $path"
17425
17426         echo "pass with $path and $fid"
17427 }
17428
17429 test_226a () {
17430         rm -rf $DIR/$tdir
17431         mkdir -p $DIR/$tdir
17432
17433         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17434         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17435         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17436         mcreate_path2fid 0040666 0 0 dir "directory"
17437         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17438         mcreate_path2fid 0100666 0 0 file "regular file"
17439         mcreate_path2fid 0120666 0 0 link "symbolic link"
17440         mcreate_path2fid 0140666 0 0 sock "socket"
17441 }
17442 run_test 226a "call path2fid and fid2path on files of all type"
17443
17444 test_226b () {
17445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17446
17447         local MDTIDX=1
17448
17449         rm -rf $DIR/$tdir
17450         mkdir -p $DIR/$tdir
17451         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17452                 error "create remote directory failed"
17453         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17454         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17455                                 "character special file (null)"
17456         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17457                                 "character special file (no device)"
17458         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17459         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17460                                 "block special file (loop)"
17461         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17462         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17463         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17464 }
17465 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17466
17467 test_226c () {
17468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17469         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17470                 skip "Need MDS version at least 2.13.55"
17471
17472         local submnt=/mnt/submnt
17473         local srcfile=/etc/passwd
17474         local dstfile=$submnt/passwd
17475         local path
17476         local fid
17477
17478         rm -rf $DIR/$tdir
17479         rm -rf $submnt
17480         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17481                 error "create remote directory failed"
17482         mkdir -p $submnt || error "create $submnt failed"
17483         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17484                 error "mount $submnt failed"
17485         stack_trap "umount $submnt" EXIT
17486
17487         cp $srcfile $dstfile
17488         fid=$($LFS path2fid $dstfile)
17489         path=$($LFS fid2path $submnt "$fid")
17490         [ "$path" = "$dstfile" ] ||
17491                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17492 }
17493 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17494
17495 # LU-1299 Executing or running ldd on a truncated executable does not
17496 # cause an out-of-memory condition.
17497 test_227() {
17498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17499         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17500
17501         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17502         chmod +x $MOUNT/date
17503
17504         $MOUNT/date > /dev/null
17505         ldd $MOUNT/date > /dev/null
17506         rm -f $MOUNT/date
17507 }
17508 run_test 227 "running truncated executable does not cause OOM"
17509
17510 # LU-1512 try to reuse idle OI blocks
17511 test_228a() {
17512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17513         remote_mds_nodsh && skip "remote MDS with nodsh"
17514         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17515
17516         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17517         local myDIR=$DIR/$tdir
17518
17519         mkdir -p $myDIR
17520         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17521         $LCTL set_param fail_loc=0x80001002
17522         createmany -o $myDIR/t- 10000
17523         $LCTL set_param fail_loc=0
17524         # The guard is current the largest FID holder
17525         touch $myDIR/guard
17526         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17527                     tr -d '[')
17528         local IDX=$(($SEQ % 64))
17529
17530         do_facet $SINGLEMDS sync
17531         # Make sure journal flushed.
17532         sleep 6
17533         local blk1=$(do_facet $SINGLEMDS \
17534                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17535                      grep Blockcount | awk '{print $4}')
17536
17537         # Remove old files, some OI blocks will become idle.
17538         unlinkmany $myDIR/t- 10000
17539         # Create new files, idle OI blocks should be reused.
17540         createmany -o $myDIR/t- 2000
17541         do_facet $SINGLEMDS sync
17542         # Make sure journal flushed.
17543         sleep 6
17544         local blk2=$(do_facet $SINGLEMDS \
17545                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17546                      grep Blockcount | awk '{print $4}')
17547
17548         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17549 }
17550 run_test 228a "try to reuse idle OI blocks"
17551
17552 test_228b() {
17553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17554         remote_mds_nodsh && skip "remote MDS with nodsh"
17555         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17556
17557         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17558         local myDIR=$DIR/$tdir
17559
17560         mkdir -p $myDIR
17561         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17562         $LCTL set_param fail_loc=0x80001002
17563         createmany -o $myDIR/t- 10000
17564         $LCTL set_param fail_loc=0
17565         # The guard is current the largest FID holder
17566         touch $myDIR/guard
17567         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17568                     tr -d '[')
17569         local IDX=$(($SEQ % 64))
17570
17571         do_facet $SINGLEMDS sync
17572         # Make sure journal flushed.
17573         sleep 6
17574         local blk1=$(do_facet $SINGLEMDS \
17575                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17576                      grep Blockcount | awk '{print $4}')
17577
17578         # Remove old files, some OI blocks will become idle.
17579         unlinkmany $myDIR/t- 10000
17580
17581         # stop the MDT
17582         stop $SINGLEMDS || error "Fail to stop MDT."
17583         # remount the MDT
17584         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17585
17586         df $MOUNT || error "Fail to df."
17587         # Create new files, idle OI blocks should be reused.
17588         createmany -o $myDIR/t- 2000
17589         do_facet $SINGLEMDS sync
17590         # Make sure journal flushed.
17591         sleep 6
17592         local blk2=$(do_facet $SINGLEMDS \
17593                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17594                      grep Blockcount | awk '{print $4}')
17595
17596         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17597 }
17598 run_test 228b "idle OI blocks can be reused after MDT restart"
17599
17600 #LU-1881
17601 test_228c() {
17602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17603         remote_mds_nodsh && skip "remote MDS with nodsh"
17604         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17605
17606         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17607         local myDIR=$DIR/$tdir
17608
17609         mkdir -p $myDIR
17610         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17611         $LCTL set_param fail_loc=0x80001002
17612         # 20000 files can guarantee there are index nodes in the OI file
17613         createmany -o $myDIR/t- 20000
17614         $LCTL set_param fail_loc=0
17615         # The guard is current the largest FID holder
17616         touch $myDIR/guard
17617         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17618                     tr -d '[')
17619         local IDX=$(($SEQ % 64))
17620
17621         do_facet $SINGLEMDS sync
17622         # Make sure journal flushed.
17623         sleep 6
17624         local blk1=$(do_facet $SINGLEMDS \
17625                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17626                      grep Blockcount | awk '{print $4}')
17627
17628         # Remove old files, some OI blocks will become idle.
17629         unlinkmany $myDIR/t- 20000
17630         rm -f $myDIR/guard
17631         # The OI file should become empty now
17632
17633         # Create new files, idle OI blocks should be reused.
17634         createmany -o $myDIR/t- 2000
17635         do_facet $SINGLEMDS sync
17636         # Make sure journal flushed.
17637         sleep 6
17638         local blk2=$(do_facet $SINGLEMDS \
17639                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17640                      grep Blockcount | awk '{print $4}')
17641
17642         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17643 }
17644 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17645
17646 test_229() { # LU-2482, LU-3448
17647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17648         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17649         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17650                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17651
17652         rm -f $DIR/$tfile
17653
17654         # Create a file with a released layout and stripe count 2.
17655         $MULTIOP $DIR/$tfile H2c ||
17656                 error "failed to create file with released layout"
17657
17658         $LFS getstripe -v $DIR/$tfile
17659
17660         local pattern=$($LFS getstripe -L $DIR/$tfile)
17661         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17662
17663         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17664                 error "getstripe"
17665         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17666         stat $DIR/$tfile || error "failed to stat released file"
17667
17668         chown $RUNAS_ID $DIR/$tfile ||
17669                 error "chown $RUNAS_ID $DIR/$tfile failed"
17670
17671         chgrp $RUNAS_ID $DIR/$tfile ||
17672                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17673
17674         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17675         rm $DIR/$tfile || error "failed to remove released file"
17676 }
17677 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17678
17679 test_230a() {
17680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17681         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17682         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17683                 skip "Need MDS version at least 2.11.52"
17684
17685         local MDTIDX=1
17686
17687         test_mkdir $DIR/$tdir
17688         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17689         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17690         [ $mdt_idx -ne 0 ] &&
17691                 error "create local directory on wrong MDT $mdt_idx"
17692
17693         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17694                         error "create remote directory failed"
17695         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17696         [ $mdt_idx -ne $MDTIDX ] &&
17697                 error "create remote directory on wrong MDT $mdt_idx"
17698
17699         createmany -o $DIR/$tdir/test_230/t- 10 ||
17700                 error "create files on remote directory failed"
17701         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17702         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17703         rm -r $DIR/$tdir || error "unlink remote directory failed"
17704 }
17705 run_test 230a "Create remote directory and files under the remote directory"
17706
17707 test_230b() {
17708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17710         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17711                 skip "Need MDS version at least 2.11.52"
17712
17713         local MDTIDX=1
17714         local mdt_index
17715         local i
17716         local file
17717         local pid
17718         local stripe_count
17719         local migrate_dir=$DIR/$tdir/migrate_dir
17720         local other_dir=$DIR/$tdir/other_dir
17721
17722         test_mkdir $DIR/$tdir
17723         test_mkdir -i0 -c1 $migrate_dir
17724         test_mkdir -i0 -c1 $other_dir
17725         for ((i=0; i<10; i++)); do
17726                 mkdir -p $migrate_dir/dir_${i}
17727                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17728                         error "create files under remote dir failed $i"
17729         done
17730
17731         cp /etc/passwd $migrate_dir/$tfile
17732         cp /etc/passwd $other_dir/$tfile
17733         chattr +SAD $migrate_dir
17734         chattr +SAD $migrate_dir/$tfile
17735
17736         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17737         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17738         local old_dir_mode=$(stat -c%f $migrate_dir)
17739         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17740
17741         mkdir -p $migrate_dir/dir_default_stripe2
17742         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17743         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17744
17745         mkdir -p $other_dir
17746         ln $migrate_dir/$tfile $other_dir/luna
17747         ln $migrate_dir/$tfile $migrate_dir/sofia
17748         ln $other_dir/$tfile $migrate_dir/david
17749         ln -s $migrate_dir/$tfile $other_dir/zachary
17750         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17751         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17752
17753         local len
17754         local lnktgt
17755
17756         # inline symlink
17757         for len in 58 59 60; do
17758                 lnktgt=$(str_repeat 'l' $len)
17759                 touch $migrate_dir/$lnktgt
17760                 ln -s $lnktgt $migrate_dir/${len}char_ln
17761         done
17762
17763         # PATH_MAX
17764         for len in 4094 4095; do
17765                 lnktgt=$(str_repeat 'l' $len)
17766                 ln -s $lnktgt $migrate_dir/${len}char_ln
17767         done
17768
17769         # NAME_MAX
17770         for len in 254 255; do
17771                 touch $migrate_dir/$(str_repeat 'l' $len)
17772         done
17773
17774         $LFS migrate -m $MDTIDX $migrate_dir ||
17775                 error "fails on migrating remote dir to MDT1"
17776
17777         echo "migratate to MDT1, then checking.."
17778         for ((i = 0; i < 10; i++)); do
17779                 for file in $(find $migrate_dir/dir_${i}); do
17780                         mdt_index=$($LFS getstripe -m $file)
17781                         # broken symlink getstripe will fail
17782                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17783                                 error "$file is not on MDT${MDTIDX}"
17784                 done
17785         done
17786
17787         # the multiple link file should still in MDT0
17788         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17789         [ $mdt_index == 0 ] ||
17790                 error "$file is not on MDT${MDTIDX}"
17791
17792         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17793         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17794                 error " expect $old_dir_flag get $new_dir_flag"
17795
17796         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17797         [ "$old_file_flag" = "$new_file_flag" ] ||
17798                 error " expect $old_file_flag get $new_file_flag"
17799
17800         local new_dir_mode=$(stat -c%f $migrate_dir)
17801         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17802                 error "expect mode $old_dir_mode get $new_dir_mode"
17803
17804         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17805         [ "$old_file_mode" = "$new_file_mode" ] ||
17806                 error "expect mode $old_file_mode get $new_file_mode"
17807
17808         diff /etc/passwd $migrate_dir/$tfile ||
17809                 error "$tfile different after migration"
17810
17811         diff /etc/passwd $other_dir/luna ||
17812                 error "luna different after migration"
17813
17814         diff /etc/passwd $migrate_dir/sofia ||
17815                 error "sofia different after migration"
17816
17817         diff /etc/passwd $migrate_dir/david ||
17818                 error "david different after migration"
17819
17820         diff /etc/passwd $other_dir/zachary ||
17821                 error "zachary different after migration"
17822
17823         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17824                 error "${tfile}_ln different after migration"
17825
17826         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17827                 error "${tfile}_ln_other different after migration"
17828
17829         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17830         [ $stripe_count = 2 ] ||
17831                 error "dir strpe_count $d != 2 after migration."
17832
17833         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17834         [ $stripe_count = 2 ] ||
17835                 error "file strpe_count $d != 2 after migration."
17836
17837         #migrate back to MDT0
17838         MDTIDX=0
17839
17840         $LFS migrate -m $MDTIDX $migrate_dir ||
17841                 error "fails on migrating remote dir to MDT0"
17842
17843         echo "migrate back to MDT0, checking.."
17844         for file in $(find $migrate_dir); do
17845                 mdt_index=$($LFS getstripe -m $file)
17846                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17847                         error "$file is not on MDT${MDTIDX}"
17848         done
17849
17850         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17851         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17852                 error " expect $old_dir_flag get $new_dir_flag"
17853
17854         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17855         [ "$old_file_flag" = "$new_file_flag" ] ||
17856                 error " expect $old_file_flag get $new_file_flag"
17857
17858         local new_dir_mode=$(stat -c%f $migrate_dir)
17859         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17860                 error "expect mode $old_dir_mode get $new_dir_mode"
17861
17862         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17863         [ "$old_file_mode" = "$new_file_mode" ] ||
17864                 error "expect mode $old_file_mode get $new_file_mode"
17865
17866         diff /etc/passwd ${migrate_dir}/$tfile ||
17867                 error "$tfile different after migration"
17868
17869         diff /etc/passwd ${other_dir}/luna ||
17870                 error "luna different after migration"
17871
17872         diff /etc/passwd ${migrate_dir}/sofia ||
17873                 error "sofia different after migration"
17874
17875         diff /etc/passwd ${other_dir}/zachary ||
17876                 error "zachary different after migration"
17877
17878         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17879                 error "${tfile}_ln different after migration"
17880
17881         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17882                 error "${tfile}_ln_other different after migration"
17883
17884         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17885         [ $stripe_count = 2 ] ||
17886                 error "dir strpe_count $d != 2 after migration."
17887
17888         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17889         [ $stripe_count = 2 ] ||
17890                 error "file strpe_count $d != 2 after migration."
17891
17892         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17893 }
17894 run_test 230b "migrate directory"
17895
17896 test_230c() {
17897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17899         remote_mds_nodsh && skip "remote MDS with nodsh"
17900         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17901                 skip "Need MDS version at least 2.11.52"
17902
17903         local MDTIDX=1
17904         local total=3
17905         local mdt_index
17906         local file
17907         local migrate_dir=$DIR/$tdir/migrate_dir
17908
17909         #If migrating directory fails in the middle, all entries of
17910         #the directory is still accessiable.
17911         test_mkdir $DIR/$tdir
17912         test_mkdir -i0 -c1 $migrate_dir
17913         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17914         stat $migrate_dir
17915         createmany -o $migrate_dir/f $total ||
17916                 error "create files under ${migrate_dir} failed"
17917
17918         # fail after migrating top dir, and this will fail only once, so the
17919         # first sub file migration will fail (currently f3), others succeed.
17920         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17921         do_facet mds1 lctl set_param fail_loc=0x1801
17922         local t=$(ls $migrate_dir | wc -l)
17923         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17924                 error "migrate should fail"
17925         local u=$(ls $migrate_dir | wc -l)
17926         [ "$u" == "$t" ] || error "$u != $t during migration"
17927
17928         # add new dir/file should succeed
17929         mkdir $migrate_dir/dir ||
17930                 error "mkdir failed under migrating directory"
17931         touch $migrate_dir/file ||
17932                 error "create file failed under migrating directory"
17933
17934         # add file with existing name should fail
17935         for file in $migrate_dir/f*; do
17936                 stat $file > /dev/null || error "stat $file failed"
17937                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17938                         error "open(O_CREAT|O_EXCL) $file should fail"
17939                 $MULTIOP $file m && error "create $file should fail"
17940                 touch $DIR/$tdir/remote_dir/$tfile ||
17941                         error "touch $tfile failed"
17942                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17943                         error "link $file should fail"
17944                 mdt_index=$($LFS getstripe -m $file)
17945                 if [ $mdt_index == 0 ]; then
17946                         # file failed to migrate is not allowed to rename to
17947                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17948                                 error "rename to $file should fail"
17949                 else
17950                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17951                                 error "rename to $file failed"
17952                 fi
17953                 echo hello >> $file || error "write $file failed"
17954         done
17955
17956         # resume migration with different options should fail
17957         $LFS migrate -m 0 $migrate_dir &&
17958                 error "migrate -m 0 $migrate_dir should fail"
17959
17960         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17961                 error "migrate -c 2 $migrate_dir should fail"
17962
17963         # resume migration should succeed
17964         $LFS migrate -m $MDTIDX $migrate_dir ||
17965                 error "migrate $migrate_dir failed"
17966
17967         echo "Finish migration, then checking.."
17968         for file in $(find $migrate_dir); do
17969                 mdt_index=$($LFS getstripe -m $file)
17970                 [ $mdt_index == $MDTIDX ] ||
17971                         error "$file is not on MDT${MDTIDX}"
17972         done
17973
17974         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17975 }
17976 run_test 230c "check directory accessiblity if migration failed"
17977
17978 test_230d() {
17979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17980         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17981         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17982                 skip "Need MDS version at least 2.11.52"
17983         # LU-11235
17984         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17985
17986         local migrate_dir=$DIR/$tdir/migrate_dir
17987         local old_index
17988         local new_index
17989         local old_count
17990         local new_count
17991         local new_hash
17992         local mdt_index
17993         local i
17994         local j
17995
17996         old_index=$((RANDOM % MDSCOUNT))
17997         old_count=$((MDSCOUNT - old_index))
17998         new_index=$((RANDOM % MDSCOUNT))
17999         new_count=$((MDSCOUNT - new_index))
18000         new_hash=1 # for all_char
18001
18002         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18003         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18004
18005         test_mkdir $DIR/$tdir
18006         test_mkdir -i $old_index -c $old_count $migrate_dir
18007
18008         for ((i=0; i<100; i++)); do
18009                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18010                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18011                         error "create files under remote dir failed $i"
18012         done
18013
18014         echo -n "Migrate from MDT$old_index "
18015         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18016         echo -n "to MDT$new_index"
18017         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18018         echo
18019
18020         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18021         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18022                 error "migrate remote dir error"
18023
18024         echo "Finish migration, then checking.."
18025         for file in $(find $migrate_dir); do
18026                 mdt_index=$($LFS getstripe -m $file)
18027                 if [ $mdt_index -lt $new_index ] ||
18028                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18029                         error "$file is on MDT$mdt_index"
18030                 fi
18031         done
18032
18033         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18034 }
18035 run_test 230d "check migrate big directory"
18036
18037 test_230e() {
18038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18039         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18040         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18041                 skip "Need MDS version at least 2.11.52"
18042
18043         local i
18044         local j
18045         local a_fid
18046         local b_fid
18047
18048         mkdir -p $DIR/$tdir
18049         mkdir $DIR/$tdir/migrate_dir
18050         mkdir $DIR/$tdir/other_dir
18051         touch $DIR/$tdir/migrate_dir/a
18052         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18053         ls $DIR/$tdir/other_dir
18054
18055         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18056                 error "migrate dir fails"
18057
18058         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18059         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18060
18061         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18062         [ $mdt_index == 0 ] || error "a is not on MDT0"
18063
18064         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18065                 error "migrate dir fails"
18066
18067         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18068         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18069
18070         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18071         [ $mdt_index == 1 ] || error "a is not on MDT1"
18072
18073         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18074         [ $mdt_index == 1 ] || error "b is not on MDT1"
18075
18076         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18077         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18078
18079         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18080
18081         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18082 }
18083 run_test 230e "migrate mulitple local link files"
18084
18085 test_230f() {
18086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18088         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18089                 skip "Need MDS version at least 2.11.52"
18090
18091         local a_fid
18092         local ln_fid
18093
18094         mkdir -p $DIR/$tdir
18095         mkdir $DIR/$tdir/migrate_dir
18096         $LFS mkdir -i1 $DIR/$tdir/other_dir
18097         touch $DIR/$tdir/migrate_dir/a
18098         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18099         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18100         ls $DIR/$tdir/other_dir
18101
18102         # a should be migrated to MDT1, since no other links on MDT0
18103         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18104                 error "#1 migrate dir fails"
18105         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18106         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18107         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18108         [ $mdt_index == 1 ] || error "a is not on MDT1"
18109
18110         # a should stay on MDT1, because it is a mulitple link file
18111         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18112                 error "#2 migrate dir fails"
18113         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18114         [ $mdt_index == 1 ] || error "a is not on MDT1"
18115
18116         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18117                 error "#3 migrate dir fails"
18118
18119         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18120         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18121         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18122
18123         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18124         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18125
18126         # a should be migrated to MDT0, since no other links on MDT1
18127         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18128                 error "#4 migrate dir fails"
18129         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18130         [ $mdt_index == 0 ] || error "a is not on MDT0"
18131
18132         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18133 }
18134 run_test 230f "migrate mulitple remote link files"
18135
18136 test_230g() {
18137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18139         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18140                 skip "Need MDS version at least 2.11.52"
18141
18142         mkdir -p $DIR/$tdir/migrate_dir
18143
18144         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18145                 error "migrating dir to non-exist MDT succeeds"
18146         true
18147 }
18148 run_test 230g "migrate dir to non-exist MDT"
18149
18150 test_230h() {
18151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18153         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18154                 skip "Need MDS version at least 2.11.52"
18155
18156         local mdt_index
18157
18158         mkdir -p $DIR/$tdir/migrate_dir
18159
18160         $LFS migrate -m1 $DIR &&
18161                 error "migrating mountpoint1 should fail"
18162
18163         $LFS migrate -m1 $DIR/$tdir/.. &&
18164                 error "migrating mountpoint2 should fail"
18165
18166         # same as mv
18167         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18168                 error "migrating $tdir/migrate_dir/.. should fail"
18169
18170         true
18171 }
18172 run_test 230h "migrate .. and root"
18173
18174 test_230i() {
18175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18177         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18178                 skip "Need MDS version at least 2.11.52"
18179
18180         mkdir -p $DIR/$tdir/migrate_dir
18181
18182         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18183                 error "migration fails with a tailing slash"
18184
18185         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18186                 error "migration fails with two tailing slashes"
18187 }
18188 run_test 230i "lfs migrate -m tolerates trailing slashes"
18189
18190 test_230j() {
18191         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18192         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18193                 skip "Need MDS version at least 2.11.52"
18194
18195         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18196         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18197                 error "create $tfile failed"
18198         cat /etc/passwd > $DIR/$tdir/$tfile
18199
18200         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18201
18202         cmp /etc/passwd $DIR/$tdir/$tfile ||
18203                 error "DoM file mismatch after migration"
18204 }
18205 run_test 230j "DoM file data not changed after dir migration"
18206
18207 test_230k() {
18208         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18209         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18210                 skip "Need MDS version at least 2.11.56"
18211
18212         local total=20
18213         local files_on_starting_mdt=0
18214
18215         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18216         $LFS getdirstripe $DIR/$tdir
18217         for i in $(seq $total); do
18218                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18219                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18220                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18221         done
18222
18223         echo "$files_on_starting_mdt files on MDT0"
18224
18225         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18226         $LFS getdirstripe $DIR/$tdir
18227
18228         files_on_starting_mdt=0
18229         for i in $(seq $total); do
18230                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18231                         error "file $tfile.$i mismatch after migration"
18232                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18233                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18234         done
18235
18236         echo "$files_on_starting_mdt files on MDT1 after migration"
18237         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18238
18239         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18240         $LFS getdirstripe $DIR/$tdir
18241
18242         files_on_starting_mdt=0
18243         for i in $(seq $total); do
18244                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18245                         error "file $tfile.$i mismatch after 2nd migration"
18246                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18247                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18248         done
18249
18250         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18251         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18252
18253         true
18254 }
18255 run_test 230k "file data not changed after dir migration"
18256
18257 test_230l() {
18258         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18259         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18260                 skip "Need MDS version at least 2.11.56"
18261
18262         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18263         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18264                 error "create files under remote dir failed $i"
18265         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18266 }
18267 run_test 230l "readdir between MDTs won't crash"
18268
18269 test_230m() {
18270         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18271         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18272                 skip "Need MDS version at least 2.11.56"
18273
18274         local MDTIDX=1
18275         local mig_dir=$DIR/$tdir/migrate_dir
18276         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18277         local shortstr="b"
18278         local val
18279
18280         echo "Creating files and dirs with xattrs"
18281         test_mkdir $DIR/$tdir
18282         test_mkdir -i0 -c1 $mig_dir
18283         mkdir $mig_dir/dir
18284         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18285                 error "cannot set xattr attr1 on dir"
18286         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18287                 error "cannot set xattr attr2 on dir"
18288         touch $mig_dir/dir/f0
18289         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18290                 error "cannot set xattr attr1 on file"
18291         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18292                 error "cannot set xattr attr2 on file"
18293         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18294         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18295         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18296         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18297         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18298         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18299         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18300         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18301         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18302
18303         echo "Migrating to MDT1"
18304         $LFS migrate -m $MDTIDX $mig_dir ||
18305                 error "fails on migrating dir to MDT1"
18306
18307         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18308         echo "Checking xattrs"
18309         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18310         [ "$val" = $longstr ] ||
18311                 error "expecting xattr1 $longstr on dir, found $val"
18312         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18313         [ "$val" = $shortstr ] ||
18314                 error "expecting xattr2 $shortstr on dir, found $val"
18315         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18316         [ "$val" = $longstr ] ||
18317                 error "expecting xattr1 $longstr on file, found $val"
18318         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18319         [ "$val" = $shortstr ] ||
18320                 error "expecting xattr2 $shortstr on file, found $val"
18321 }
18322 run_test 230m "xattrs not changed after dir migration"
18323
18324 test_230n() {
18325         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18326         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18327                 skip "Need MDS version at least 2.13.53"
18328
18329         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18330         cat /etc/hosts > $DIR/$tdir/$tfile
18331         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18332         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18333
18334         cmp /etc/hosts $DIR/$tdir/$tfile ||
18335                 error "File data mismatch after migration"
18336 }
18337 run_test 230n "Dir migration with mirrored file"
18338
18339 test_230o() {
18340         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18341         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18342                 skip "Need MDS version at least 2.13.52"
18343
18344         local mdts=$(comma_list $(mdts_nodes))
18345         local timeout=100
18346
18347         local restripe_status
18348         local delta
18349         local i
18350         local j
18351
18352         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18353
18354         # in case "crush" hash type is not set
18355         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18356
18357         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18358                            mdt.*MDT0000.enable_dir_restripe)
18359         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18360         stack_trap "do_nodes $mdts $LCTL set_param \
18361                     mdt.*.enable_dir_restripe=$restripe_status"
18362
18363         mkdir $DIR/$tdir
18364         createmany -m $DIR/$tdir/f 100 ||
18365                 error "create files under remote dir failed $i"
18366         createmany -d $DIR/$tdir/d 100 ||
18367                 error "create dirs under remote dir failed $i"
18368
18369         for i in $(seq 2 $MDSCOUNT); do
18370                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18371                 $LFS setdirstripe -c $i $DIR/$tdir ||
18372                         error "split -c $i $tdir failed"
18373                 wait_update $HOSTNAME \
18374                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18375                         error "dir split not finished"
18376                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18377                         awk '/migrate/ {sum += $2} END { print sum }')
18378                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18379                 # delta is around total_files/stripe_count
18380                 [ $delta -lt $((200 /(i - 1))) ] ||
18381                         error "$delta files migrated"
18382         done
18383 }
18384 run_test 230o "dir split"
18385
18386 test_230p() {
18387         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18388         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18389                 skip "Need MDS version at least 2.13.52"
18390
18391         local mdts=$(comma_list $(mdts_nodes))
18392         local timeout=100
18393
18394         local restripe_status
18395         local delta
18396         local i
18397         local j
18398
18399         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18400
18401         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18402
18403         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18404                            mdt.*MDT0000.enable_dir_restripe)
18405         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18406         stack_trap "do_nodes $mdts $LCTL set_param \
18407                     mdt.*.enable_dir_restripe=$restripe_status"
18408
18409         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18410         createmany -m $DIR/$tdir/f 100 ||
18411                 error "create files under remote dir failed $i"
18412         createmany -d $DIR/$tdir/d 100 ||
18413                 error "create dirs under remote dir failed $i"
18414
18415         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18416                 local mdt_hash="crush"
18417
18418                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18419                 $LFS setdirstripe -c $i $DIR/$tdir ||
18420                         error "split -c $i $tdir failed"
18421                 [ $i -eq 1 ] && mdt_hash="none"
18422                 wait_update $HOSTNAME \
18423                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18424                         error "dir merge not finished"
18425                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18426                         awk '/migrate/ {sum += $2} END { print sum }')
18427                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18428                 # delta is around total_files/stripe_count
18429                 [ $delta -lt $((200 / i)) ] ||
18430                         error "$delta files migrated"
18431         done
18432 }
18433 run_test 230p "dir merge"
18434
18435 test_230q() {
18436         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18437         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18438                 skip "Need MDS version at least 2.13.52"
18439
18440         local mdts=$(comma_list $(mdts_nodes))
18441         local saved_threshold=$(do_facet mds1 \
18442                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18443         local saved_delta=$(do_facet mds1 \
18444                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18445         local threshold=100
18446         local delta=2
18447         local total=0
18448         local stripe_count=0
18449         local stripe_index
18450         local nr_files
18451
18452         # test with fewer files on ZFS
18453         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18454
18455         stack_trap "do_nodes $mdts $LCTL set_param \
18456                     mdt.*.dir_split_count=$saved_threshold"
18457         stack_trap "do_nodes $mdts $LCTL set_param \
18458                     mdt.*.dir_split_delta=$saved_delta"
18459         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18460         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18461         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18462         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18463         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18464         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18465
18466         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18467         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18468
18469         while [ $stripe_count -lt $MDSCOUNT ]; do
18470                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18471                         error "create sub files failed"
18472                 stat $DIR/$tdir > /dev/null
18473                 total=$((total + threshold * 3 / 2))
18474                 stripe_count=$((stripe_count + delta))
18475                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18476
18477                 wait_update $HOSTNAME \
18478                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18479                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18480
18481                 wait_update $HOSTNAME \
18482                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18483                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18484
18485                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18486                            grep -w $stripe_index | wc -l)
18487                 echo "$nr_files files on MDT$stripe_index after split"
18488                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18489                         error "$nr_files files on MDT$stripe_index after split"
18490
18491                 nr_files=$(ls $DIR/$tdir | wc -w)
18492                 [ $nr_files -eq $total ] ||
18493                         error "total sub files $nr_files != $total"
18494         done
18495 }
18496 run_test 230q "dir auto split"
18497
18498 test_230r() {
18499         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18500         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18501         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18502                 skip "Need MDS version at least 2.13.54"
18503
18504         # maximum amount of local locks:
18505         # parent striped dir - 2 locks
18506         # new stripe in parent to migrate to - 1 lock
18507         # source and target - 2 locks
18508         # Total 5 locks for regular file
18509         mkdir -p $DIR/$tdir
18510         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18511         touch $DIR/$tdir/dir1/eee
18512
18513         # create 4 hardlink for 4 more locks
18514         # Total: 9 locks > RS_MAX_LOCKS (8)
18515         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18516         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18517         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18518         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18519         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18520         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18521         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18522         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18523
18524         cancel_lru_locks mdc
18525
18526         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18527                 error "migrate dir fails"
18528
18529         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18530 }
18531 run_test 230r "migrate with too many local locks"
18532
18533 test_231a()
18534 {
18535         # For simplicity this test assumes that max_pages_per_rpc
18536         # is the same across all OSCs
18537         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18538         local bulk_size=$((max_pages * PAGE_SIZE))
18539         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18540                                        head -n 1)
18541
18542         mkdir -p $DIR/$tdir
18543         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18544                 error "failed to set stripe with -S ${brw_size}M option"
18545
18546         # clear the OSC stats
18547         $LCTL set_param osc.*.stats=0 &>/dev/null
18548         stop_writeback
18549
18550         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18552                 oflag=direct &>/dev/null || error "dd failed"
18553
18554         sync; sleep 1; sync # just to be safe
18555         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18556         if [ x$nrpcs != "x1" ]; then
18557                 $LCTL get_param osc.*.stats
18558                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18559         fi
18560
18561         start_writeback
18562         # Drop the OSC cache, otherwise we will read from it
18563         cancel_lru_locks osc
18564
18565         # clear the OSC stats
18566         $LCTL set_param osc.*.stats=0 &>/dev/null
18567
18568         # Client reads $bulk_size.
18569         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18570                 iflag=direct &>/dev/null || error "dd failed"
18571
18572         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18573         if [ x$nrpcs != "x1" ]; then
18574                 $LCTL get_param osc.*.stats
18575                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18576         fi
18577 }
18578 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18579
18580 test_231b() {
18581         mkdir -p $DIR/$tdir
18582         local i
18583         for i in {0..1023}; do
18584                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18585                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18586                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18587         done
18588         sync
18589 }
18590 run_test 231b "must not assert on fully utilized OST request buffer"
18591
18592 test_232a() {
18593         mkdir -p $DIR/$tdir
18594         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18595
18596         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18597         do_facet ost1 $LCTL set_param fail_loc=0x31c
18598
18599         # ignore dd failure
18600         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18601
18602         do_facet ost1 $LCTL set_param fail_loc=0
18603         umount_client $MOUNT || error "umount failed"
18604         mount_client $MOUNT || error "mount failed"
18605         stop ost1 || error "cannot stop ost1"
18606         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18607 }
18608 run_test 232a "failed lock should not block umount"
18609
18610 test_232b() {
18611         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18612                 skip "Need MDS version at least 2.10.58"
18613
18614         mkdir -p $DIR/$tdir
18615         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18616         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18617         sync
18618         cancel_lru_locks osc
18619
18620         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18621         do_facet ost1 $LCTL set_param fail_loc=0x31c
18622
18623         # ignore failure
18624         $LFS data_version $DIR/$tdir/$tfile || true
18625
18626         do_facet ost1 $LCTL set_param fail_loc=0
18627         umount_client $MOUNT || error "umount failed"
18628         mount_client $MOUNT || error "mount failed"
18629         stop ost1 || error "cannot stop ost1"
18630         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18631 }
18632 run_test 232b "failed data version lock should not block umount"
18633
18634 test_233a() {
18635         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18636                 skip "Need MDS version at least 2.3.64"
18637         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18638
18639         local fid=$($LFS path2fid $MOUNT)
18640
18641         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18642                 error "cannot access $MOUNT using its FID '$fid'"
18643 }
18644 run_test 233a "checking that OBF of the FS root succeeds"
18645
18646 test_233b() {
18647         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18648                 skip "Need MDS version at least 2.5.90"
18649         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18650
18651         local fid=$($LFS path2fid $MOUNT/.lustre)
18652
18653         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18654                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18655
18656         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18657         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18658                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18659 }
18660 run_test 233b "checking that OBF of the FS .lustre succeeds"
18661
18662 test_234() {
18663         local p="$TMP/sanityN-$TESTNAME.parameters"
18664         save_lustre_params client "llite.*.xattr_cache" > $p
18665         lctl set_param llite.*.xattr_cache 1 ||
18666                 skip_env "xattr cache is not supported"
18667
18668         mkdir -p $DIR/$tdir || error "mkdir failed"
18669         touch $DIR/$tdir/$tfile || error "touch failed"
18670         # OBD_FAIL_LLITE_XATTR_ENOMEM
18671         $LCTL set_param fail_loc=0x1405
18672         getfattr -n user.attr $DIR/$tdir/$tfile &&
18673                 error "getfattr should have failed with ENOMEM"
18674         $LCTL set_param fail_loc=0x0
18675         rm -rf $DIR/$tdir
18676
18677         restore_lustre_params < $p
18678         rm -f $p
18679 }
18680 run_test 234 "xattr cache should not crash on ENOMEM"
18681
18682 test_235() {
18683         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18684                 skip "Need MDS version at least 2.4.52"
18685
18686         flock_deadlock $DIR/$tfile
18687         local RC=$?
18688         case $RC in
18689                 0)
18690                 ;;
18691                 124) error "process hangs on a deadlock"
18692                 ;;
18693                 *) error "error executing flock_deadlock $DIR/$tfile"
18694                 ;;
18695         esac
18696 }
18697 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18698
18699 #LU-2935
18700 test_236() {
18701         check_swap_layouts_support
18702
18703         local ref1=/etc/passwd
18704         local ref2=/etc/group
18705         local file1=$DIR/$tdir/f1
18706         local file2=$DIR/$tdir/f2
18707
18708         test_mkdir -c1 $DIR/$tdir
18709         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18710         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18711         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18712         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18713         local fd=$(free_fd)
18714         local cmd="exec $fd<>$file2"
18715         eval $cmd
18716         rm $file2
18717         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18718                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18719         cmd="exec $fd>&-"
18720         eval $cmd
18721         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18722
18723         #cleanup
18724         rm -rf $DIR/$tdir
18725 }
18726 run_test 236 "Layout swap on open unlinked file"
18727
18728 # LU-4659 linkea consistency
18729 test_238() {
18730         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18731                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18732                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18733                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18734
18735         touch $DIR/$tfile
18736         ln $DIR/$tfile $DIR/$tfile.lnk
18737         touch $DIR/$tfile.new
18738         mv $DIR/$tfile.new $DIR/$tfile
18739         local fid1=$($LFS path2fid $DIR/$tfile)
18740         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18741         local path1=$($LFS fid2path $FSNAME "$fid1")
18742         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18743         local path2=$($LFS fid2path $FSNAME "$fid2")
18744         [ $tfile.lnk == $path2 ] ||
18745                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18746         rm -f $DIR/$tfile*
18747 }
18748 run_test 238 "Verify linkea consistency"
18749
18750 test_239A() { # was test_239
18751         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18752                 skip "Need MDS version at least 2.5.60"
18753
18754         local list=$(comma_list $(mdts_nodes))
18755
18756         mkdir -p $DIR/$tdir
18757         createmany -o $DIR/$tdir/f- 5000
18758         unlinkmany $DIR/$tdir/f- 5000
18759         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18760                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18761         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18762                         osp.*MDT*.sync_in_flight" | calc_sum)
18763         [ "$changes" -eq 0 ] || error "$changes not synced"
18764 }
18765 run_test 239A "osp_sync test"
18766
18767 test_239a() { #LU-5297
18768         remote_mds_nodsh && skip "remote MDS with nodsh"
18769
18770         touch $DIR/$tfile
18771         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18772         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18773         chgrp $RUNAS_GID $DIR/$tfile
18774         wait_delete_completed
18775 }
18776 run_test 239a "process invalid osp sync record correctly"
18777
18778 test_239b() { #LU-5297
18779         remote_mds_nodsh && skip "remote MDS with nodsh"
18780
18781         touch $DIR/$tfile1
18782         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18783         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18784         chgrp $RUNAS_GID $DIR/$tfile1
18785         wait_delete_completed
18786         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18787         touch $DIR/$tfile2
18788         chgrp $RUNAS_GID $DIR/$tfile2
18789         wait_delete_completed
18790 }
18791 run_test 239b "process osp sync record with ENOMEM error correctly"
18792
18793 test_240() {
18794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18795         remote_mds_nodsh && skip "remote MDS with nodsh"
18796
18797         mkdir -p $DIR/$tdir
18798
18799         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18800                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18801         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18802                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18803
18804         umount_client $MOUNT || error "umount failed"
18805         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18806         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18807         mount_client $MOUNT || error "failed to mount client"
18808
18809         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18810         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18811 }
18812 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18813
18814 test_241_bio() {
18815         local count=$1
18816         local bsize=$2
18817
18818         for LOOP in $(seq $count); do
18819                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18820                 cancel_lru_locks $OSC || true
18821         done
18822 }
18823
18824 test_241_dio() {
18825         local count=$1
18826         local bsize=$2
18827
18828         for LOOP in $(seq $1); do
18829                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18830                         2>/dev/null
18831         done
18832 }
18833
18834 test_241a() { # was test_241
18835         local bsize=$PAGE_SIZE
18836
18837         (( bsize < 40960 )) && bsize=40960
18838         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18839         ls -la $DIR/$tfile
18840         cancel_lru_locks $OSC
18841         test_241_bio 1000 $bsize &
18842         PID=$!
18843         test_241_dio 1000 $bsize
18844         wait $PID
18845 }
18846 run_test 241a "bio vs dio"
18847
18848 test_241b() {
18849         local bsize=$PAGE_SIZE
18850
18851         (( bsize < 40960 )) && bsize=40960
18852         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18853         ls -la $DIR/$tfile
18854         test_241_dio 1000 $bsize &
18855         PID=$!
18856         test_241_dio 1000 $bsize
18857         wait $PID
18858 }
18859 run_test 241b "dio vs dio"
18860
18861 test_242() {
18862         remote_mds_nodsh && skip "remote MDS with nodsh"
18863
18864         mkdir -p $DIR/$tdir
18865         touch $DIR/$tdir/$tfile
18866
18867         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18868         do_facet mds1 lctl set_param fail_loc=0x105
18869         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18870
18871         do_facet mds1 lctl set_param fail_loc=0
18872         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18873 }
18874 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18875
18876 test_243()
18877 {
18878         test_mkdir $DIR/$tdir
18879         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18880 }
18881 run_test 243 "various group lock tests"
18882
18883 test_244a()
18884 {
18885         test_mkdir $DIR/$tdir
18886         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18887         sendfile_grouplock $DIR/$tdir/$tfile || \
18888                 error "sendfile+grouplock failed"
18889         rm -rf $DIR/$tdir
18890 }
18891 run_test 244a "sendfile with group lock tests"
18892
18893 test_244b()
18894 {
18895         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18896
18897         local threads=50
18898         local size=$((1024*1024))
18899
18900         test_mkdir $DIR/$tdir
18901         for i in $(seq 1 $threads); do
18902                 local file=$DIR/$tdir/file_$((i / 10))
18903                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18904                 local pids[$i]=$!
18905         done
18906         for i in $(seq 1 $threads); do
18907                 wait ${pids[$i]}
18908         done
18909 }
18910 run_test 244b "multi-threaded write with group lock"
18911
18912 test_245() {
18913         local flagname="multi_mod_rpcs"
18914         local connect_data_name="max_mod_rpcs"
18915         local out
18916
18917         # check if multiple modify RPCs flag is set
18918         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18919                 grep "connect_flags:")
18920         echo "$out"
18921
18922         echo "$out" | grep -qw $flagname
18923         if [ $? -ne 0 ]; then
18924                 echo "connect flag $flagname is not set"
18925                 return
18926         fi
18927
18928         # check if multiple modify RPCs data is set
18929         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18930         echo "$out"
18931
18932         echo "$out" | grep -qw $connect_data_name ||
18933                 error "import should have connect data $connect_data_name"
18934 }
18935 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18936
18937 cleanup_247() {
18938         local submount=$1
18939
18940         trap 0
18941         umount_client $submount
18942         rmdir $submount
18943 }
18944
18945 test_247a() {
18946         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18947                 grep -q subtree ||
18948                 skip_env "Fileset feature is not supported"
18949
18950         local submount=${MOUNT}_$tdir
18951
18952         mkdir $MOUNT/$tdir
18953         mkdir -p $submount || error "mkdir $submount failed"
18954         FILESET="$FILESET/$tdir" mount_client $submount ||
18955                 error "mount $submount failed"
18956         trap "cleanup_247 $submount" EXIT
18957         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18958         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18959                 error "read $MOUNT/$tdir/$tfile failed"
18960         cleanup_247 $submount
18961 }
18962 run_test 247a "mount subdir as fileset"
18963
18964 test_247b() {
18965         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18966                 skip_env "Fileset feature is not supported"
18967
18968         local submount=${MOUNT}_$tdir
18969
18970         rm -rf $MOUNT/$tdir
18971         mkdir -p $submount || error "mkdir $submount failed"
18972         SKIP_FILESET=1
18973         FILESET="$FILESET/$tdir" mount_client $submount &&
18974                 error "mount $submount should fail"
18975         rmdir $submount
18976 }
18977 run_test 247b "mount subdir that dose not exist"
18978
18979 test_247c() {
18980         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18981                 skip_env "Fileset feature is not supported"
18982
18983         local submount=${MOUNT}_$tdir
18984
18985         mkdir -p $MOUNT/$tdir/dir1
18986         mkdir -p $submount || error "mkdir $submount failed"
18987         trap "cleanup_247 $submount" EXIT
18988         FILESET="$FILESET/$tdir" mount_client $submount ||
18989                 error "mount $submount failed"
18990         local fid=$($LFS path2fid $MOUNT/)
18991         $LFS fid2path $submount $fid && error "fid2path should fail"
18992         cleanup_247 $submount
18993 }
18994 run_test 247c "running fid2path outside subdirectory root"
18995
18996 test_247d() {
18997         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18998                 skip "Fileset feature is not supported"
18999
19000         local submount=${MOUNT}_$tdir
19001
19002         mkdir -p $MOUNT/$tdir/dir1
19003         mkdir -p $submount || error "mkdir $submount failed"
19004         FILESET="$FILESET/$tdir" mount_client $submount ||
19005                 error "mount $submount failed"
19006         trap "cleanup_247 $submount" EXIT
19007
19008         local td=$submount/dir1
19009         local fid=$($LFS path2fid $td)
19010         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19011
19012         # check that we get the same pathname back
19013         local rootpath
19014         local found
19015         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19016                 echo "$rootpath $fid"
19017                 found=$($LFS fid2path $rootpath "$fid")
19018                 [ -n "found" ] || error "fid2path should succeed"
19019                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19020         done
19021         # check wrong root path format
19022         rootpath=$submount"_wrong"
19023         found=$($LFS fid2path $rootpath "$fid")
19024         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19025
19026         cleanup_247 $submount
19027 }
19028 run_test 247d "running fid2path inside subdirectory root"
19029
19030 # LU-8037
19031 test_247e() {
19032         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19033                 grep -q subtree ||
19034                 skip "Fileset feature is not supported"
19035
19036         local submount=${MOUNT}_$tdir
19037
19038         mkdir $MOUNT/$tdir
19039         mkdir -p $submount || error "mkdir $submount failed"
19040         FILESET="$FILESET/.." mount_client $submount &&
19041                 error "mount $submount should fail"
19042         rmdir $submount
19043 }
19044 run_test 247e "mount .. as fileset"
19045
19046 test_247f() {
19047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19048         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19049                 skip "Need at least version 2.13.52"
19050         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19051                 grep -q subtree ||
19052                 skip "Fileset feature is not supported"
19053
19054         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19055         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19056                 error "mkdir remote failed"
19057         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19058         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19059                 error "mkdir striped failed"
19060         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19061
19062         local submount=${MOUNT}_$tdir
19063
19064         mkdir -p $submount || error "mkdir $submount failed"
19065
19066         local dir
19067         local fileset=$FILESET
19068
19069         for dir in $tdir/remote $tdir/remote/subdir \
19070                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19071                 FILESET="$fileset/$dir" mount_client $submount ||
19072                         error "mount $dir failed"
19073                 umount_client $submount
19074         done
19075 }
19076 run_test 247f "mount striped or remote directory as fileset"
19077
19078 test_248a() {
19079         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19080         [ -z "$fast_read_sav" ] && skip "no fast read support"
19081
19082         # create a large file for fast read verification
19083         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19084
19085         # make sure the file is created correctly
19086         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19087                 { rm -f $DIR/$tfile; skip "file creation error"; }
19088
19089         echo "Test 1: verify that fast read is 4 times faster on cache read"
19090
19091         # small read with fast read enabled
19092         $LCTL set_param -n llite.*.fast_read=1
19093         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19094                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19095                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19096         # small read with fast read disabled
19097         $LCTL set_param -n llite.*.fast_read=0
19098         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19099                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19100                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19101
19102         # verify that fast read is 4 times faster for cache read
19103         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19104                 error_not_in_vm "fast read was not 4 times faster: " \
19105                            "$t_fast vs $t_slow"
19106
19107         echo "Test 2: verify the performance between big and small read"
19108         $LCTL set_param -n llite.*.fast_read=1
19109
19110         # 1k non-cache read
19111         cancel_lru_locks osc
19112         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19113                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19114                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19115
19116         # 1M non-cache read
19117         cancel_lru_locks osc
19118         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19119                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19120                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19121
19122         # verify that big IO is not 4 times faster than small IO
19123         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19124                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19125
19126         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19127         rm -f $DIR/$tfile
19128 }
19129 run_test 248a "fast read verification"
19130
19131 test_248b() {
19132         # Default short_io_bytes=16384, try both smaller and larger sizes.
19133         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19134         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19135         echo "bs=53248 count=113 normal buffered write"
19136         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19137                 error "dd of initial data file failed"
19138         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19139
19140         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19141         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19142                 error "dd with sync normal writes failed"
19143         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19144
19145         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19146         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19147                 error "dd with sync small writes failed"
19148         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19149
19150         cancel_lru_locks osc
19151
19152         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19153         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19154         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19155         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19156                 iflag=direct || error "dd with O_DIRECT small read failed"
19157         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19158         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19159                 error "compare $TMP/$tfile.1 failed"
19160
19161         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19162         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19163
19164         # just to see what the maximum tunable value is, and test parsing
19165         echo "test invalid parameter 2MB"
19166         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19167                 error "too-large short_io_bytes allowed"
19168         echo "test maximum parameter 512KB"
19169         # if we can set a larger short_io_bytes, run test regardless of version
19170         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19171                 # older clients may not allow setting it this large, that's OK
19172                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19173                         skip "Need at least client version 2.13.50"
19174                 error "medium short_io_bytes failed"
19175         fi
19176         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19177         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19178
19179         echo "test large parameter 64KB"
19180         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19181         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19182
19183         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19184         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19185                 error "dd with sync large writes failed"
19186         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19187
19188         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19189         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19190         num=$((113 * 4096 / PAGE_SIZE))
19191         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19192         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19193                 error "dd with O_DIRECT large writes failed"
19194         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19195                 error "compare $DIR/$tfile.3 failed"
19196
19197         cancel_lru_locks osc
19198
19199         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19200         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19201                 error "dd with O_DIRECT large read failed"
19202         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19203                 error "compare $TMP/$tfile.2 failed"
19204
19205         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19206         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19207                 error "dd with O_DIRECT large read failed"
19208         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19209                 error "compare $TMP/$tfile.3 failed"
19210 }
19211 run_test 248b "test short_io read and write for both small and large sizes"
19212
19213 test_249() { # LU-7890
19214         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19215                 skip "Need at least version 2.8.54"
19216
19217         rm -f $DIR/$tfile
19218         $LFS setstripe -c 1 $DIR/$tfile
19219         # Offset 2T == 4k * 512M
19220         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19221                 error "dd to 2T offset failed"
19222 }
19223 run_test 249 "Write above 2T file size"
19224
19225 test_250() {
19226         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19227          && skip "no 16TB file size limit on ZFS"
19228
19229         $LFS setstripe -c 1 $DIR/$tfile
19230         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19231         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19232         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19233         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19234                 conv=notrunc,fsync && error "append succeeded"
19235         return 0
19236 }
19237 run_test 250 "Write above 16T limit"
19238
19239 test_251() {
19240         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19241
19242         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19243         #Skip once - writing the first stripe will succeed
19244         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19245         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19246                 error "short write happened"
19247
19248         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19249         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19250                 error "short read happened"
19251
19252         rm -f $DIR/$tfile
19253 }
19254 run_test 251 "Handling short read and write correctly"
19255
19256 test_252() {
19257         remote_mds_nodsh && skip "remote MDS with nodsh"
19258         remote_ost_nodsh && skip "remote OST with nodsh"
19259         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19260                 skip_env "ldiskfs only test"
19261         fi
19262
19263         local tgt
19264         local dev
19265         local out
19266         local uuid
19267         local num
19268         local gen
19269
19270         # check lr_reader on OST0000
19271         tgt=ost1
19272         dev=$(facet_device $tgt)
19273         out=$(do_facet $tgt $LR_READER $dev)
19274         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19275         echo "$out"
19276         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19277         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19278                 error "Invalid uuid returned by $LR_READER on target $tgt"
19279         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19280
19281         # check lr_reader -c on MDT0000
19282         tgt=mds1
19283         dev=$(facet_device $tgt)
19284         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19285                 skip "$LR_READER does not support additional options"
19286         fi
19287         out=$(do_facet $tgt $LR_READER -c $dev)
19288         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19289         echo "$out"
19290         num=$(echo "$out" | grep -c "mdtlov")
19291         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19292                 error "Invalid number of mdtlov clients returned by $LR_READER"
19293         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19294
19295         # check lr_reader -cr on MDT0000
19296         out=$(do_facet $tgt $LR_READER -cr $dev)
19297         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19298         echo "$out"
19299         echo "$out" | grep -q "^reply_data:$" ||
19300                 error "$LR_READER should have returned 'reply_data' section"
19301         num=$(echo "$out" | grep -c "client_generation")
19302         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19303 }
19304 run_test 252 "check lr_reader tool"
19305
19306 test_253() {
19307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19308         remote_mds_nodsh && skip "remote MDS with nodsh"
19309         remote_mgs_nodsh && skip "remote MGS with nodsh"
19310
19311         local ostidx=0
19312         local rc=0
19313         local ost_name=$(ostname_from_index $ostidx)
19314
19315         # on the mdt's osc
19316         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19317         do_facet $SINGLEMDS $LCTL get_param -n \
19318                 osp.$mdtosc_proc1.reserved_mb_high ||
19319                 skip  "remote MDS does not support reserved_mb_high"
19320
19321         rm -rf $DIR/$tdir
19322         wait_mds_ost_sync
19323         wait_delete_completed
19324         mkdir $DIR/$tdir
19325
19326         pool_add $TESTNAME || error "Pool creation failed"
19327         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19328
19329         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19330                 error "Setstripe failed"
19331
19332         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19333
19334         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19335                     grep "watermarks")
19336         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19337
19338         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19339                         osp.$mdtosc_proc1.prealloc_status)
19340         echo "prealloc_status $oa_status"
19341
19342         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19343                 error "File creation should fail"
19344
19345         #object allocation was stopped, but we still able to append files
19346         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19347                 oflag=append || error "Append failed"
19348
19349         rm -f $DIR/$tdir/$tfile.0
19350
19351         # For this test, we want to delete the files we created to go out of
19352         # space but leave the watermark, so we remain nearly out of space
19353         ost_watermarks_enospc_delete_files $tfile $ostidx
19354
19355         wait_delete_completed
19356
19357         sleep_maxage
19358
19359         for i in $(seq 10 12); do
19360                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19361                         2>/dev/null || error "File creation failed after rm"
19362         done
19363
19364         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19365                         osp.$mdtosc_proc1.prealloc_status)
19366         echo "prealloc_status $oa_status"
19367
19368         if (( oa_status != 0 )); then
19369                 error "Object allocation still disable after rm"
19370         fi
19371 }
19372 run_test 253 "Check object allocation limit"
19373
19374 test_254() {
19375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19376         remote_mds_nodsh && skip "remote MDS with nodsh"
19377         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19378                 skip "MDS does not support changelog_size"
19379
19380         local cl_user
19381         local MDT0=$(facet_svc $SINGLEMDS)
19382
19383         changelog_register || error "changelog_register failed"
19384
19385         changelog_clear 0 || error "changelog_clear failed"
19386
19387         local size1=$(do_facet $SINGLEMDS \
19388                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19389         echo "Changelog size $size1"
19390
19391         rm -rf $DIR/$tdir
19392         $LFS mkdir -i 0 $DIR/$tdir
19393         # change something
19394         mkdir -p $DIR/$tdir/pics/2008/zachy
19395         touch $DIR/$tdir/pics/2008/zachy/timestamp
19396         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19397         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19398         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19399         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19400         rm $DIR/$tdir/pics/desktop.jpg
19401
19402         local size2=$(do_facet $SINGLEMDS \
19403                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19404         echo "Changelog size after work $size2"
19405
19406         (( $size2 > $size1 )) ||
19407                 error "new Changelog size=$size2 less than old size=$size1"
19408 }
19409 run_test 254 "Check changelog size"
19410
19411 ladvise_no_type()
19412 {
19413         local type=$1
19414         local file=$2
19415
19416         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19417                 awk -F: '{print $2}' | grep $type > /dev/null
19418         if [ $? -ne 0 ]; then
19419                 return 0
19420         fi
19421         return 1
19422 }
19423
19424 ladvise_no_ioctl()
19425 {
19426         local file=$1
19427
19428         lfs ladvise -a willread $file > /dev/null 2>&1
19429         if [ $? -eq 0 ]; then
19430                 return 1
19431         fi
19432
19433         lfs ladvise -a willread $file 2>&1 |
19434                 grep "Inappropriate ioctl for device" > /dev/null
19435         if [ $? -eq 0 ]; then
19436                 return 0
19437         fi
19438         return 1
19439 }
19440
19441 percent() {
19442         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19443 }
19444
19445 # run a random read IO workload
19446 # usage: random_read_iops <filename> <filesize> <iosize>
19447 random_read_iops() {
19448         local file=$1
19449         local fsize=$2
19450         local iosize=${3:-4096}
19451
19452         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19453                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19454 }
19455
19456 drop_file_oss_cache() {
19457         local file="$1"
19458         local nodes="$2"
19459
19460         $LFS ladvise -a dontneed $file 2>/dev/null ||
19461                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19462 }
19463
19464 ladvise_willread_performance()
19465 {
19466         local repeat=10
19467         local average_origin=0
19468         local average_cache=0
19469         local average_ladvise=0
19470
19471         for ((i = 1; i <= $repeat; i++)); do
19472                 echo "Iter $i/$repeat: reading without willread hint"
19473                 cancel_lru_locks osc
19474                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19475                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19476                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19477                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19478
19479                 cancel_lru_locks osc
19480                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19481                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19482                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19483
19484                 cancel_lru_locks osc
19485                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19486                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19487                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19488                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19489                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19490         done
19491         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19492         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19493         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19494
19495         speedup_cache=$(percent $average_cache $average_origin)
19496         speedup_ladvise=$(percent $average_ladvise $average_origin)
19497
19498         echo "Average uncached read: $average_origin"
19499         echo "Average speedup with OSS cached read: " \
19500                 "$average_cache = +$speedup_cache%"
19501         echo "Average speedup with ladvise willread: " \
19502                 "$average_ladvise = +$speedup_ladvise%"
19503
19504         local lowest_speedup=20
19505         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19506                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19507                         "got $average_cache%. Skipping ladvise willread check."
19508                 return 0
19509         fi
19510
19511         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19512         # it is still good to run until then to exercise 'ladvise willread'
19513         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19514                 [ "$ost1_FSTYPE" = "zfs" ] &&
19515                 echo "osd-zfs does not support dontneed or drop_caches" &&
19516                 return 0
19517
19518         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19519         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19520                 error_not_in_vm "Speedup with willread is less than " \
19521                         "$lowest_speedup%, got $average_ladvise%"
19522 }
19523
19524 test_255a() {
19525         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19526                 skip "lustre < 2.8.54 does not support ladvise "
19527         remote_ost_nodsh && skip "remote OST with nodsh"
19528
19529         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19530
19531         ladvise_no_type willread $DIR/$tfile &&
19532                 skip "willread ladvise is not supported"
19533
19534         ladvise_no_ioctl $DIR/$tfile &&
19535                 skip "ladvise ioctl is not supported"
19536
19537         local size_mb=100
19538         local size=$((size_mb * 1048576))
19539         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19540                 error "dd to $DIR/$tfile failed"
19541
19542         lfs ladvise -a willread $DIR/$tfile ||
19543                 error "Ladvise failed with no range argument"
19544
19545         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19546                 error "Ladvise failed with no -l or -e argument"
19547
19548         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19549                 error "Ladvise failed with only -e argument"
19550
19551         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19552                 error "Ladvise failed with only -l argument"
19553
19554         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19555                 error "End offset should not be smaller than start offset"
19556
19557         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19558                 error "End offset should not be equal to start offset"
19559
19560         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19561                 error "Ladvise failed with overflowing -s argument"
19562
19563         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19564                 error "Ladvise failed with overflowing -e argument"
19565
19566         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19567                 error "Ladvise failed with overflowing -l argument"
19568
19569         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19570                 error "Ladvise succeeded with conflicting -l and -e arguments"
19571
19572         echo "Synchronous ladvise should wait"
19573         local delay=4
19574 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19575         do_nodes $(comma_list $(osts_nodes)) \
19576                 $LCTL set_param fail_val=$delay fail_loc=0x237
19577
19578         local start_ts=$SECONDS
19579         lfs ladvise -a willread $DIR/$tfile ||
19580                 error "Ladvise failed with no range argument"
19581         local end_ts=$SECONDS
19582         local inteval_ts=$((end_ts - start_ts))
19583
19584         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19585                 error "Synchronous advice didn't wait reply"
19586         fi
19587
19588         echo "Asynchronous ladvise shouldn't wait"
19589         local start_ts=$SECONDS
19590         lfs ladvise -a willread -b $DIR/$tfile ||
19591                 error "Ladvise failed with no range argument"
19592         local end_ts=$SECONDS
19593         local inteval_ts=$((end_ts - start_ts))
19594
19595         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19596                 error "Asynchronous advice blocked"
19597         fi
19598
19599         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19600         ladvise_willread_performance
19601 }
19602 run_test 255a "check 'lfs ladvise -a willread'"
19603
19604 facet_meminfo() {
19605         local facet=$1
19606         local info=$2
19607
19608         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19609 }
19610
19611 test_255b() {
19612         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19613                 skip "lustre < 2.8.54 does not support ladvise "
19614         remote_ost_nodsh && skip "remote OST with nodsh"
19615
19616         lfs setstripe -c 1 -i 0 $DIR/$tfile
19617
19618         ladvise_no_type dontneed $DIR/$tfile &&
19619                 skip "dontneed ladvise is not supported"
19620
19621         ladvise_no_ioctl $DIR/$tfile &&
19622                 skip "ladvise ioctl is not supported"
19623
19624         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19625                 [ "$ost1_FSTYPE" = "zfs" ] &&
19626                 skip "zfs-osd does not support 'ladvise dontneed'"
19627
19628         local size_mb=100
19629         local size=$((size_mb * 1048576))
19630         # In order to prevent disturbance of other processes, only check 3/4
19631         # of the memory usage
19632         local kibibytes=$((size_mb * 1024 * 3 / 4))
19633
19634         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19635                 error "dd to $DIR/$tfile failed"
19636
19637         #force write to complete before dropping OST cache & checking memory
19638         sync
19639
19640         local total=$(facet_meminfo ost1 MemTotal)
19641         echo "Total memory: $total KiB"
19642
19643         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19644         local before_read=$(facet_meminfo ost1 Cached)
19645         echo "Cache used before read: $before_read KiB"
19646
19647         lfs ladvise -a willread $DIR/$tfile ||
19648                 error "Ladvise willread failed"
19649         local after_read=$(facet_meminfo ost1 Cached)
19650         echo "Cache used after read: $after_read KiB"
19651
19652         lfs ladvise -a dontneed $DIR/$tfile ||
19653                 error "Ladvise dontneed again failed"
19654         local no_read=$(facet_meminfo ost1 Cached)
19655         echo "Cache used after dontneed ladvise: $no_read KiB"
19656
19657         if [ $total -lt $((before_read + kibibytes)) ]; then
19658                 echo "Memory is too small, abort checking"
19659                 return 0
19660         fi
19661
19662         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19663                 error "Ladvise willread should use more memory" \
19664                         "than $kibibytes KiB"
19665         fi
19666
19667         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19668                 error "Ladvise dontneed should release more memory" \
19669                         "than $kibibytes KiB"
19670         fi
19671 }
19672 run_test 255b "check 'lfs ladvise -a dontneed'"
19673
19674 test_255c() {
19675         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19676                 skip "lustre < 2.10.50 does not support lockahead"
19677
19678         local count
19679         local new_count
19680         local difference
19681         local i
19682         local rc
19683
19684         test_mkdir -p $DIR/$tdir
19685         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19686
19687         #test 10 returns only success/failure
19688         i=10
19689         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19690         rc=$?
19691         if [ $rc -eq 255 ]; then
19692                 error "Ladvise test${i} failed, ${rc}"
19693         fi
19694
19695         #test 11 counts lock enqueue requests, all others count new locks
19696         i=11
19697         count=$(do_facet ost1 \
19698                 $LCTL get_param -n ost.OSS.ost.stats)
19699         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19700
19701         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19702         rc=$?
19703         if [ $rc -eq 255 ]; then
19704                 error "Ladvise test${i} failed, ${rc}"
19705         fi
19706
19707         new_count=$(do_facet ost1 \
19708                 $LCTL get_param -n ost.OSS.ost.stats)
19709         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19710                    awk '{ print $2 }')
19711
19712         difference="$((new_count - count))"
19713         if [ $difference -ne $rc ]; then
19714                 error "Ladvise test${i}, bad enqueue count, returned " \
19715                       "${rc}, actual ${difference}"
19716         fi
19717
19718         for i in $(seq 12 21); do
19719                 # If we do not do this, we run the risk of having too many
19720                 # locks and starting lock cancellation while we are checking
19721                 # lock counts.
19722                 cancel_lru_locks osc
19723
19724                 count=$($LCTL get_param -n \
19725                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19726
19727                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19728                 rc=$?
19729                 if [ $rc -eq 255 ]; then
19730                         error "Ladvise test ${i} failed, ${rc}"
19731                 fi
19732
19733                 new_count=$($LCTL get_param -n \
19734                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19735                 difference="$((new_count - count))"
19736
19737                 # Test 15 output is divided by 100 to map down to valid return
19738                 if [ $i -eq 15 ]; then
19739                         rc="$((rc * 100))"
19740                 fi
19741
19742                 if [ $difference -ne $rc ]; then
19743                         error "Ladvise test ${i}, bad lock count, returned " \
19744                               "${rc}, actual ${difference}"
19745                 fi
19746         done
19747
19748         #test 22 returns only success/failure
19749         i=22
19750         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19751         rc=$?
19752         if [ $rc -eq 255 ]; then
19753                 error "Ladvise test${i} failed, ${rc}"
19754         fi
19755 }
19756 run_test 255c "suite of ladvise lockahead tests"
19757
19758 test_256() {
19759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19760         remote_mds_nodsh && skip "remote MDS with nodsh"
19761         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19762         changelog_users $SINGLEMDS | grep "^cl" &&
19763                 skip "active changelog user"
19764
19765         local cl_user
19766         local cat_sl
19767         local mdt_dev
19768
19769         mdt_dev=$(mdsdevname 1)
19770         echo $mdt_dev
19771
19772         changelog_register || error "changelog_register failed"
19773
19774         rm -rf $DIR/$tdir
19775         mkdir -p $DIR/$tdir
19776
19777         changelog_clear 0 || error "changelog_clear failed"
19778
19779         # change something
19780         touch $DIR/$tdir/{1..10}
19781
19782         # stop the MDT
19783         stop $SINGLEMDS || error "Fail to stop MDT"
19784
19785         # remount the MDT
19786
19787         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19788
19789         #after mount new plainllog is used
19790         touch $DIR/$tdir/{11..19}
19791         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19792         stack_trap "rm -f $tmpfile"
19793         cat_sl=$(do_facet $SINGLEMDS "sync; \
19794                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19795                  llog_reader $tmpfile | grep -c type=1064553b")
19796         do_facet $SINGLEMDS llog_reader $tmpfile
19797
19798         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19799
19800         changelog_clear 0 || error "changelog_clear failed"
19801
19802         cat_sl=$(do_facet $SINGLEMDS "sync; \
19803                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19804                  llog_reader $tmpfile | grep -c type=1064553b")
19805
19806         if (( cat_sl == 2 )); then
19807                 error "Empty plain llog was not deleted from changelog catalog"
19808         elif (( cat_sl != 1 )); then
19809                 error "Active plain llog shouldn't be deleted from catalog"
19810         fi
19811 }
19812 run_test 256 "Check llog delete for empty and not full state"
19813
19814 test_257() {
19815         remote_mds_nodsh && skip "remote MDS with nodsh"
19816         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19817                 skip "Need MDS version at least 2.8.55"
19818
19819         test_mkdir $DIR/$tdir
19820
19821         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19822                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19823         stat $DIR/$tdir
19824
19825 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19826         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19827         local facet=mds$((mdtidx + 1))
19828         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19829         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19830
19831         stop $facet || error "stop MDS failed"
19832         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19833                 error "start MDS fail"
19834         wait_recovery_complete $facet
19835 }
19836 run_test 257 "xattr locks are not lost"
19837
19838 # Verify we take the i_mutex when security requires it
19839 test_258a() {
19840 #define OBD_FAIL_IMUTEX_SEC 0x141c
19841         $LCTL set_param fail_loc=0x141c
19842         touch $DIR/$tfile
19843         chmod u+s $DIR/$tfile
19844         chmod a+rwx $DIR/$tfile
19845         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19846         RC=$?
19847         if [ $RC -ne 0 ]; then
19848                 error "error, failed to take i_mutex, rc=$?"
19849         fi
19850         rm -f $DIR/$tfile
19851 }
19852 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19853
19854 # Verify we do NOT take the i_mutex in the normal case
19855 test_258b() {
19856 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19857         $LCTL set_param fail_loc=0x141d
19858         touch $DIR/$tfile
19859         chmod a+rwx $DIR
19860         chmod a+rw $DIR/$tfile
19861         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19862         RC=$?
19863         if [ $RC -ne 0 ]; then
19864                 error "error, took i_mutex unnecessarily, rc=$?"
19865         fi
19866         rm -f $DIR/$tfile
19867
19868 }
19869 run_test 258b "verify i_mutex security behavior"
19870
19871 test_259() {
19872         local file=$DIR/$tfile
19873         local before
19874         local after
19875
19876         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19877
19878         stack_trap "rm -f $file" EXIT
19879
19880         wait_delete_completed
19881         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19882         echo "before: $before"
19883
19884         $LFS setstripe -i 0 -c 1 $file
19885         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19886         sync_all_data
19887         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19888         echo "after write: $after"
19889
19890 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19891         do_facet ost1 $LCTL set_param fail_loc=0x2301
19892         $TRUNCATE $file 0
19893         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19894         echo "after truncate: $after"
19895
19896         stop ost1
19897         do_facet ost1 $LCTL set_param fail_loc=0
19898         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19899         sleep 2
19900         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19901         echo "after restart: $after"
19902         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19903                 error "missing truncate?"
19904
19905         return 0
19906 }
19907 run_test 259 "crash at delayed truncate"
19908
19909 test_260() {
19910 #define OBD_FAIL_MDC_CLOSE               0x806
19911         $LCTL set_param fail_loc=0x80000806
19912         touch $DIR/$tfile
19913
19914 }
19915 run_test 260 "Check mdc_close fail"
19916
19917 ### Data-on-MDT sanity tests ###
19918 test_270a() {
19919         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19920                 skip "Need MDS version at least 2.10.55 for DoM"
19921
19922         # create DoM file
19923         local dom=$DIR/$tdir/dom_file
19924         local tmp=$DIR/$tdir/tmp_file
19925
19926         mkdir -p $DIR/$tdir
19927
19928         # basic checks for DoM component creation
19929         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19930                 error "Can set MDT layout to non-first entry"
19931
19932         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19933                 error "Can define multiple entries as MDT layout"
19934
19935         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19936
19937         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19938         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19939         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19940
19941         local mdtidx=$($LFS getstripe -m $dom)
19942         local mdtname=MDT$(printf %04x $mdtidx)
19943         local facet=mds$((mdtidx + 1))
19944         local space_check=1
19945
19946         # Skip free space checks with ZFS
19947         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19948
19949         # write
19950         sync
19951         local size_tmp=$((65536 * 3))
19952         local mdtfree1=$(do_facet $facet \
19953                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19954
19955         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19956         # check also direct IO along write
19957         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19958         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19959         sync
19960         cmp $tmp $dom || error "file data is different"
19961         [ $(stat -c%s $dom) == $size_tmp ] ||
19962                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19963         if [ $space_check == 1 ]; then
19964                 local mdtfree2=$(do_facet $facet \
19965                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19966
19967                 # increase in usage from by $size_tmp
19968                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19969                         error "MDT free space wrong after write: " \
19970                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19971         fi
19972
19973         # truncate
19974         local size_dom=10000
19975
19976         $TRUNCATE $dom $size_dom
19977         [ $(stat -c%s $dom) == $size_dom ] ||
19978                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19979         if [ $space_check == 1 ]; then
19980                 mdtfree1=$(do_facet $facet \
19981                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19982                 # decrease in usage from $size_tmp to new $size_dom
19983                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19984                   $(((size_tmp - size_dom) / 1024)) ] ||
19985                         error "MDT free space is wrong after truncate: " \
19986                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19987         fi
19988
19989         # append
19990         cat $tmp >> $dom
19991         sync
19992         size_dom=$((size_dom + size_tmp))
19993         [ $(stat -c%s $dom) == $size_dom ] ||
19994                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19995         if [ $space_check == 1 ]; then
19996                 mdtfree2=$(do_facet $facet \
19997                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19998                 # increase in usage by $size_tmp from previous
19999                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20000                         error "MDT free space is wrong after append: " \
20001                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20002         fi
20003
20004         # delete
20005         rm $dom
20006         if [ $space_check == 1 ]; then
20007                 mdtfree1=$(do_facet $facet \
20008                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20009                 # decrease in usage by $size_dom from previous
20010                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20011                         error "MDT free space is wrong after removal: " \
20012                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20013         fi
20014
20015         # combined striping
20016         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20017                 error "Can't create DoM + OST striping"
20018
20019         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20020         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20021         # check also direct IO along write
20022         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20023         sync
20024         cmp $tmp $dom || error "file data is different"
20025         [ $(stat -c%s $dom) == $size_tmp ] ||
20026                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20027         rm $dom $tmp
20028
20029         return 0
20030 }
20031 run_test 270a "DoM: basic functionality tests"
20032
20033 test_270b() {
20034         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20035                 skip "Need MDS version at least 2.10.55"
20036
20037         local dom=$DIR/$tdir/dom_file
20038         local max_size=1048576
20039
20040         mkdir -p $DIR/$tdir
20041         $LFS setstripe -E $max_size -L mdt $dom
20042
20043         # truncate over the limit
20044         $TRUNCATE $dom $(($max_size + 1)) &&
20045                 error "successful truncate over the maximum size"
20046         # write over the limit
20047         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20048                 error "successful write over the maximum size"
20049         # append over the limit
20050         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20051         echo "12345" >> $dom && error "successful append over the maximum size"
20052         rm $dom
20053
20054         return 0
20055 }
20056 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20057
20058 test_270c() {
20059         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20060                 skip "Need MDS version at least 2.10.55"
20061
20062         mkdir -p $DIR/$tdir
20063         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20064
20065         # check files inherit DoM EA
20066         touch $DIR/$tdir/first
20067         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20068                 error "bad pattern"
20069         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20070                 error "bad stripe count"
20071         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20072                 error "bad stripe size"
20073
20074         # check directory inherits DoM EA and uses it as default
20075         mkdir $DIR/$tdir/subdir
20076         touch $DIR/$tdir/subdir/second
20077         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20078                 error "bad pattern in sub-directory"
20079         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20080                 error "bad stripe count in sub-directory"
20081         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20082                 error "bad stripe size in sub-directory"
20083         return 0
20084 }
20085 run_test 270c "DoM: DoM EA inheritance tests"
20086
20087 test_270d() {
20088         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20089                 skip "Need MDS version at least 2.10.55"
20090
20091         mkdir -p $DIR/$tdir
20092         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20093
20094         # inherit default DoM striping
20095         mkdir $DIR/$tdir/subdir
20096         touch $DIR/$tdir/subdir/f1
20097
20098         # change default directory striping
20099         $LFS setstripe -c 1 $DIR/$tdir/subdir
20100         touch $DIR/$tdir/subdir/f2
20101         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20102                 error "wrong default striping in file 2"
20103         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20104                 error "bad pattern in file 2"
20105         return 0
20106 }
20107 run_test 270d "DoM: change striping from DoM to RAID0"
20108
20109 test_270e() {
20110         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20111                 skip "Need MDS version at least 2.10.55"
20112
20113         mkdir -p $DIR/$tdir/dom
20114         mkdir -p $DIR/$tdir/norm
20115         DOMFILES=20
20116         NORMFILES=10
20117         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20118         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20119
20120         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20121         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20122
20123         # find DoM files by layout
20124         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20125         [ $NUM -eq  $DOMFILES ] ||
20126                 error "lfs find -L: found $NUM, expected $DOMFILES"
20127         echo "Test 1: lfs find 20 DOM files by layout: OK"
20128
20129         # there should be 1 dir with default DOM striping
20130         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20131         [ $NUM -eq  1 ] ||
20132                 error "lfs find -L: found $NUM, expected 1 dir"
20133         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20134
20135         # find DoM files by stripe size
20136         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20137         [ $NUM -eq  $DOMFILES ] ||
20138                 error "lfs find -S: found $NUM, expected $DOMFILES"
20139         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20140
20141         # find files by stripe offset except DoM files
20142         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20143         [ $NUM -eq  $NORMFILES ] ||
20144                 error "lfs find -i: found $NUM, expected $NORMFILES"
20145         echo "Test 5: lfs find no DOM files by stripe index: OK"
20146         return 0
20147 }
20148 run_test 270e "DoM: lfs find with DoM files test"
20149
20150 test_270f() {
20151         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20152                 skip "Need MDS version at least 2.10.55"
20153
20154         local mdtname=${FSNAME}-MDT0000-mdtlov
20155         local dom=$DIR/$tdir/dom_file
20156         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20157                                                 lod.$mdtname.dom_stripesize)
20158         local dom_limit=131072
20159
20160         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20161         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20162                                                 lod.$mdtname.dom_stripesize)
20163         [ ${dom_limit} -eq ${dom_current} ] ||
20164                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20165
20166         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20167         $LFS setstripe -d $DIR/$tdir
20168         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20169                 error "Can't set directory default striping"
20170
20171         # exceed maximum stripe size
20172         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20173                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20174         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20175                 error "Able to create DoM component size more than LOD limit"
20176
20177         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20178         dom_current=$(do_facet mds1 $LCTL get_param -n \
20179                                                 lod.$mdtname.dom_stripesize)
20180         [ 0 -eq ${dom_current} ] ||
20181                 error "Can't set zero DoM stripe limit"
20182         rm $dom
20183
20184         # attempt to create DoM file on server with disabled DoM should
20185         # remove DoM entry from layout and be succeed
20186         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20187                 error "Can't create DoM file (DoM is disabled)"
20188         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20189                 error "File has DoM component while DoM is disabled"
20190         rm $dom
20191
20192         # attempt to create DoM file with only DoM stripe should return error
20193         $LFS setstripe -E $dom_limit -L mdt $dom &&
20194                 error "Able to create DoM-only file while DoM is disabled"
20195
20196         # too low values to be aligned with smallest stripe size 64K
20197         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20198         dom_current=$(do_facet mds1 $LCTL get_param -n \
20199                                                 lod.$mdtname.dom_stripesize)
20200         [ 30000 -eq ${dom_current} ] &&
20201                 error "Can set too small DoM stripe limit"
20202
20203         # 64K is a minimal stripe size in Lustre, expect limit of that size
20204         [ 65536 -eq ${dom_current} ] ||
20205                 error "Limit is not set to 64K but ${dom_current}"
20206
20207         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20208         dom_current=$(do_facet mds1 $LCTL get_param -n \
20209                                                 lod.$mdtname.dom_stripesize)
20210         echo $dom_current
20211         [ 2147483648 -eq ${dom_current} ] &&
20212                 error "Can set too large DoM stripe limit"
20213
20214         do_facet mds1 $LCTL set_param -n \
20215                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20216         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20217                 error "Can't create DoM component size after limit change"
20218         do_facet mds1 $LCTL set_param -n \
20219                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20220         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20221                 error "Can't create DoM file after limit decrease"
20222         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20223                 error "Can create big DoM component after limit decrease"
20224         touch ${dom}_def ||
20225                 error "Can't create file with old default layout"
20226
20227         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20228         return 0
20229 }
20230 run_test 270f "DoM: maximum DoM stripe size checks"
20231
20232 test_270g() {
20233         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20234                 skip "Need MDS version at least 2.13.52"
20235         local dom=$DIR/$tdir/$tfile
20236
20237         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20238         local lodname=${FSNAME}-MDT0000-mdtlov
20239
20240         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20241         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20242         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20243         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20244
20245         local dom_limit=1024
20246         local dom_threshold="50%"
20247
20248         $LFS setstripe -d $DIR/$tdir
20249         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20250                 error "Can't set directory default striping"
20251
20252         do_facet mds1 $LCTL set_param -n \
20253                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20254         # set 0 threshold and create DOM file to change tunable stripesize
20255         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20256         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20257                 error "Failed to create $dom file"
20258         # now tunable dom_cur_stripesize should reach maximum
20259         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20260                                         lod.${lodname}.dom_stripesize_cur_kb)
20261         [[ $dom_current == $dom_limit ]] ||
20262                 error "Current DOM stripesize is not maximum"
20263         rm $dom
20264
20265         # set threshold for further tests
20266         do_facet mds1 $LCTL set_param -n \
20267                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20268         echo "DOM threshold is $dom_threshold free space"
20269         local dom_def
20270         local dom_set
20271         # Spoof bfree to exceed threshold
20272         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20273         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20274         for spfree in 40 20 0 15 30 55; do
20275                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20276                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20277                         error "Failed to create $dom file"
20278                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20279                                         lod.${lodname}.dom_stripesize_cur_kb)
20280                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20281                 [[ $dom_def != $dom_current ]] ||
20282                         error "Default stripe size was not changed"
20283                 if [[ $spfree > 0 ]] ; then
20284                         dom_set=$($LFS getstripe -S $dom)
20285                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20286                                 error "DOM component size is still old"
20287                 else
20288                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20289                                 error "DoM component is set with no free space"
20290                 fi
20291                 rm $dom
20292                 dom_current=$dom_def
20293         done
20294 }
20295 run_test 270g "DoM: default DoM stripe size depends on free space"
20296
20297 test_270h() {
20298         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20299                 skip "Need MDS version at least 2.13.53"
20300
20301         local mdtname=${FSNAME}-MDT0000-mdtlov
20302         local dom=$DIR/$tdir/$tfile
20303         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20304
20305         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20306         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20307
20308         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20309         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20310                 error "can't create OST file"
20311         # mirrored file with DOM entry in the second mirror
20312         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20313                 error "can't create mirror with DoM component"
20314
20315         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20316
20317         # DOM component in the middle and has other enries in the same mirror,
20318         # should succeed but lost DoM component
20319         $LFS setstripe --copy=${dom}_1 $dom ||
20320                 error "Can't create file from OST|DOM mirror layout"
20321         # check new file has no DoM layout after all
20322         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20323                 error "File has DoM component while DoM is disabled"
20324 }
20325 run_test 270h "DoM: DoM stripe removal when disabled on server"
20326
20327 test_271a() {
20328         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20329                 skip "Need MDS version at least 2.10.55"
20330
20331         local dom=$DIR/$tdir/dom
20332
20333         mkdir -p $DIR/$tdir
20334
20335         $LFS setstripe -E 1024K -L mdt $dom
20336
20337         lctl set_param -n mdc.*.stats=clear
20338         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20339         cat $dom > /dev/null
20340         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20341         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20342         ls $dom
20343         rm -f $dom
20344 }
20345 run_test 271a "DoM: data is cached for read after write"
20346
20347 test_271b() {
20348         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20349                 skip "Need MDS version at least 2.10.55"
20350
20351         local dom=$DIR/$tdir/dom
20352
20353         mkdir -p $DIR/$tdir
20354
20355         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20356
20357         lctl set_param -n mdc.*.stats=clear
20358         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20359         cancel_lru_locks mdc
20360         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20361         # second stat to check size is cached on client
20362         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20363         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20364         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20365         rm -f $dom
20366 }
20367 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20368
20369 test_271ba() {
20370         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20371                 skip "Need MDS version at least 2.10.55"
20372
20373         local dom=$DIR/$tdir/dom
20374
20375         mkdir -p $DIR/$tdir
20376
20377         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20378
20379         lctl set_param -n mdc.*.stats=clear
20380         lctl set_param -n osc.*.stats=clear
20381         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20382         cancel_lru_locks mdc
20383         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20384         # second stat to check size is cached on client
20385         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20386         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20387         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20388         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20389         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20390         rm -f $dom
20391 }
20392 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20393
20394
20395 get_mdc_stats() {
20396         local mdtidx=$1
20397         local param=$2
20398         local mdt=MDT$(printf %04x $mdtidx)
20399
20400         if [ -z $param ]; then
20401                 lctl get_param -n mdc.*$mdt*.stats
20402         else
20403                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20404         fi
20405 }
20406
20407 test_271c() {
20408         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20409                 skip "Need MDS version at least 2.10.55"
20410
20411         local dom=$DIR/$tdir/dom
20412
20413         mkdir -p $DIR/$tdir
20414
20415         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20416
20417         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20418         local facet=mds$((mdtidx + 1))
20419
20420         cancel_lru_locks mdc
20421         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20422         createmany -o $dom 1000
20423         lctl set_param -n mdc.*.stats=clear
20424         smalliomany -w $dom 1000 200
20425         get_mdc_stats $mdtidx
20426         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20427         # Each file has 1 open, 1 IO enqueues, total 2000
20428         # but now we have also +1 getxattr for security.capability, total 3000
20429         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20430         unlinkmany $dom 1000
20431
20432         cancel_lru_locks mdc
20433         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20434         createmany -o $dom 1000
20435         lctl set_param -n mdc.*.stats=clear
20436         smalliomany -w $dom 1000 200
20437         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20438         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20439         # for OPEN and IO lock.
20440         [ $((enq - enq_2)) -ge 1000 ] ||
20441                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20442         unlinkmany $dom 1000
20443         return 0
20444 }
20445 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20446
20447 cleanup_271def_tests() {
20448         trap 0
20449         rm -f $1
20450 }
20451
20452 test_271d() {
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=1000 count=1
20468         dd if=$tmp of=$dom bs=1000 count=1
20469         cancel_lru_locks mdc
20470
20471         cat /etc/hosts >> $tmp
20472         lctl set_param -n mdc.*.stats=clear
20473
20474         # append data to the same file it should update local page
20475         echo "Append to the same page"
20476         cat /etc/hosts >> $dom
20477         local num=$(get_mdc_stats $mdtidx ost_read)
20478         local ra=$(get_mdc_stats $mdtidx req_active)
20479         local rw=$(get_mdc_stats $mdtidx req_waittime)
20480
20481         [ -z $num ] || error "$num READ RPC occured"
20482         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20483         echo "... DONE"
20484
20485         # compare content
20486         cmp $tmp $dom || error "file miscompare"
20487
20488         cancel_lru_locks mdc
20489         lctl set_param -n mdc.*.stats=clear
20490
20491         echo "Open and read file"
20492         cat $dom > /dev/null
20493         local num=$(get_mdc_stats $mdtidx ost_read)
20494         local ra=$(get_mdc_stats $mdtidx req_active)
20495         local rw=$(get_mdc_stats $mdtidx req_waittime)
20496
20497         [ -z $num ] || error "$num READ RPC occured"
20498         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20499         echo "... DONE"
20500
20501         # compare content
20502         cmp $tmp $dom || error "file miscompare"
20503
20504         return 0
20505 }
20506 run_test 271d "DoM: read on open (1K file in reply buffer)"
20507
20508 test_271f() {
20509         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20510                 skip "Need MDS version at least 2.10.57"
20511
20512         local dom=$DIR/$tdir/dom
20513         local tmp=$TMP/$tfile
20514         trap "cleanup_271def_tests $tmp" EXIT
20515
20516         mkdir -p $DIR/$tdir
20517
20518         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20519
20520         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20521
20522         cancel_lru_locks mdc
20523         dd if=/dev/urandom of=$tmp bs=265000 count=1
20524         dd if=$tmp of=$dom bs=265000 count=1
20525         cancel_lru_locks mdc
20526         cat /etc/hosts >> $tmp
20527         lctl set_param -n mdc.*.stats=clear
20528
20529         echo "Append to the same page"
20530         cat /etc/hosts >> $dom
20531         local num=$(get_mdc_stats $mdtidx ost_read)
20532         local ra=$(get_mdc_stats $mdtidx req_active)
20533         local rw=$(get_mdc_stats $mdtidx req_waittime)
20534
20535         [ -z $num ] || error "$num READ RPC occured"
20536         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20537         echo "... DONE"
20538
20539         # compare content
20540         cmp $tmp $dom || error "file miscompare"
20541
20542         cancel_lru_locks mdc
20543         lctl set_param -n mdc.*.stats=clear
20544
20545         echo "Open and read file"
20546         cat $dom > /dev/null
20547         local num=$(get_mdc_stats $mdtidx ost_read)
20548         local ra=$(get_mdc_stats $mdtidx req_active)
20549         local rw=$(get_mdc_stats $mdtidx req_waittime)
20550
20551         [ -z $num ] && num=0
20552         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20553         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20554         echo "... DONE"
20555
20556         # compare content
20557         cmp $tmp $dom || error "file miscompare"
20558
20559         return 0
20560 }
20561 run_test 271f "DoM: read on open (200K file and read tail)"
20562
20563 test_271g() {
20564         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20565                 skip "Skipping due to old client or server version"
20566
20567         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20568         # to get layout
20569         $CHECKSTAT -t file $DIR1/$tfile
20570
20571         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20572         MULTIOP_PID=$!
20573         sleep 1
20574         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20575         $LCTL set_param fail_loc=0x80000314
20576         rm $DIR1/$tfile || error "Unlink fails"
20577         RC=$?
20578         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20579         [ $RC -eq 0 ] || error "Failed write to stale object"
20580 }
20581 run_test 271g "Discard DoM data vs client flush race"
20582
20583 test_272a() {
20584         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20585                 skip "Need MDS version at least 2.11.50"
20586
20587         local dom=$DIR/$tdir/dom
20588         mkdir -p $DIR/$tdir
20589
20590         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20591         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20592                 error "failed to write data into $dom"
20593         local old_md5=$(md5sum $dom)
20594
20595         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20596                 error "failed to migrate to the same DoM component"
20597
20598         local new_md5=$(md5sum $dom)
20599
20600         [ "$old_md5" == "$new_md5" ] ||
20601                 error "md5sum differ: $old_md5, $new_md5"
20602
20603         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20604                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20605 }
20606 run_test 272a "DoM migration: new layout with the same DOM component"
20607
20608 test_272b() {
20609         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20610                 skip "Need MDS version at least 2.11.50"
20611
20612         local dom=$DIR/$tdir/dom
20613         mkdir -p $DIR/$tdir
20614         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20615
20616         local mdtidx=$($LFS getstripe -m $dom)
20617         local mdtname=MDT$(printf %04x $mdtidx)
20618         local facet=mds$((mdtidx + 1))
20619
20620         local mdtfree1=$(do_facet $facet \
20621                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20622         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20623                 error "failed to write data into $dom"
20624         local old_md5=$(md5sum $dom)
20625         cancel_lru_locks mdc
20626         local mdtfree1=$(do_facet $facet \
20627                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20628
20629         $LFS migrate -c2 $dom ||
20630                 error "failed to migrate to the new composite layout"
20631         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20632                 error "MDT stripe was not removed"
20633
20634         cancel_lru_locks mdc
20635         local new_md5=$(md5sum $dom)
20636         [ "$old_md5" == "$new_md5" ] ||
20637                 error "$old_md5 != $new_md5"
20638
20639         # Skip free space checks with ZFS
20640         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20641                 local mdtfree2=$(do_facet $facet \
20642                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20643                 [ $mdtfree2 -gt $mdtfree1 ] ||
20644                         error "MDT space is not freed after migration"
20645         fi
20646         return 0
20647 }
20648 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20649
20650 test_272c() {
20651         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20652                 skip "Need MDS version at least 2.11.50"
20653
20654         local dom=$DIR/$tdir/$tfile
20655         mkdir -p $DIR/$tdir
20656         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20657
20658         local mdtidx=$($LFS getstripe -m $dom)
20659         local mdtname=MDT$(printf %04x $mdtidx)
20660         local facet=mds$((mdtidx + 1))
20661
20662         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20663                 error "failed to write data into $dom"
20664         local old_md5=$(md5sum $dom)
20665         cancel_lru_locks mdc
20666         local mdtfree1=$(do_facet $facet \
20667                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20668
20669         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20670                 error "failed to migrate to the new composite layout"
20671         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20672                 error "MDT stripe was not removed"
20673
20674         cancel_lru_locks mdc
20675         local new_md5=$(md5sum $dom)
20676         [ "$old_md5" == "$new_md5" ] ||
20677                 error "$old_md5 != $new_md5"
20678
20679         # Skip free space checks with ZFS
20680         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20681                 local mdtfree2=$(do_facet $facet \
20682                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20683                 [ $mdtfree2 -gt $mdtfree1 ] ||
20684                         error "MDS space is not freed after migration"
20685         fi
20686         return 0
20687 }
20688 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20689
20690 test_272d() {
20691         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20692                 skip "Need MDS version at least 2.12.55"
20693
20694         local dom=$DIR/$tdir/$tfile
20695         mkdir -p $DIR/$tdir
20696         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20697
20698         local mdtidx=$($LFS getstripe -m $dom)
20699         local mdtname=MDT$(printf %04x $mdtidx)
20700         local facet=mds$((mdtidx + 1))
20701
20702         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20703                 error "failed to write data into $dom"
20704         local old_md5=$(md5sum $dom)
20705         cancel_lru_locks mdc
20706         local mdtfree1=$(do_facet $facet \
20707                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20708
20709         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20710                 error "failed mirroring to the new composite layout"
20711         $LFS mirror resync $dom ||
20712                 error "failed mirror resync"
20713         $LFS mirror split --mirror-id 1 -d $dom ||
20714                 error "failed mirror split"
20715
20716         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20717                 error "MDT stripe was not removed"
20718
20719         cancel_lru_locks mdc
20720         local new_md5=$(md5sum $dom)
20721         [ "$old_md5" == "$new_md5" ] ||
20722                 error "$old_md5 != $new_md5"
20723
20724         # Skip free space checks with ZFS
20725         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20726                 local mdtfree2=$(do_facet $facet \
20727                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20728                 [ $mdtfree2 -gt $mdtfree1 ] ||
20729                         error "MDS space is not freed after DOM mirror deletion"
20730         fi
20731         return 0
20732 }
20733 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20734
20735 test_272e() {
20736         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20737                 skip "Need MDS version at least 2.12.55"
20738
20739         local dom=$DIR/$tdir/$tfile
20740         mkdir -p $DIR/$tdir
20741         $LFS setstripe -c 2 $dom
20742
20743         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20744                 error "failed to write data into $dom"
20745         local old_md5=$(md5sum $dom)
20746         cancel_lru_locks mdc
20747
20748         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20749                 error "failed mirroring to the DOM layout"
20750         $LFS mirror resync $dom ||
20751                 error "failed mirror resync"
20752         $LFS mirror split --mirror-id 1 -d $dom ||
20753                 error "failed mirror split"
20754
20755         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20756                 error "MDT stripe was not removed"
20757
20758         cancel_lru_locks mdc
20759         local new_md5=$(md5sum $dom)
20760         [ "$old_md5" == "$new_md5" ] ||
20761                 error "$old_md5 != $new_md5"
20762
20763         return 0
20764 }
20765 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20766
20767 test_272f() {
20768         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20769                 skip "Need MDS version at least 2.12.55"
20770
20771         local dom=$DIR/$tdir/$tfile
20772         mkdir -p $DIR/$tdir
20773         $LFS setstripe -c 2 $dom
20774
20775         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20776                 error "failed to write data into $dom"
20777         local old_md5=$(md5sum $dom)
20778         cancel_lru_locks mdc
20779
20780         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20781                 error "failed migrating to the DOM file"
20782
20783         cancel_lru_locks mdc
20784         local new_md5=$(md5sum $dom)
20785         [ "$old_md5" != "$new_md5" ] &&
20786                 error "$old_md5 != $new_md5"
20787
20788         return 0
20789 }
20790 run_test 272f "DoM migration: OST-striped file to DOM file"
20791
20792 test_273a() {
20793         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20794                 skip "Need MDS version at least 2.11.50"
20795
20796         # Layout swap cannot be done if either file has DOM component,
20797         # this will never be supported, migration should be used instead
20798
20799         local dom=$DIR/$tdir/$tfile
20800         mkdir -p $DIR/$tdir
20801
20802         $LFS setstripe -c2 ${dom}_plain
20803         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20804         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20805                 error "can swap layout with DoM component"
20806         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20807                 error "can swap layout with DoM component"
20808
20809         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20810         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20811                 error "can swap layout with DoM component"
20812         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20813                 error "can swap layout with DoM component"
20814         return 0
20815 }
20816 run_test 273a "DoM: layout swapping should fail with DOM"
20817
20818 test_275() {
20819         remote_ost_nodsh && skip "remote OST with nodsh"
20820         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20821                 skip "Need OST version >= 2.10.57"
20822
20823         local file=$DIR/$tfile
20824         local oss
20825
20826         oss=$(comma_list $(osts_nodes))
20827
20828         dd if=/dev/urandom of=$file bs=1M count=2 ||
20829                 error "failed to create a file"
20830         cancel_lru_locks osc
20831
20832         #lock 1
20833         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20834                 error "failed to read a file"
20835
20836 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20837         $LCTL set_param fail_loc=0x8000031f
20838
20839         cancel_lru_locks osc &
20840         sleep 1
20841
20842 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20843         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20844         #IO takes another lock, but matches the PENDING one
20845         #and places it to the IO RPC
20846         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20847                 error "failed to read a file with PENDING lock"
20848 }
20849 run_test 275 "Read on a canceled duplicate lock"
20850
20851 test_276() {
20852         remote_ost_nodsh && skip "remote OST with nodsh"
20853         local pid
20854
20855         do_facet ost1 "(while true; do \
20856                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20857                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20858         pid=$!
20859
20860         for LOOP in $(seq 20); do
20861                 stop ost1
20862                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20863         done
20864         kill -9 $pid
20865         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20866                 rm $TMP/sanity_276_pid"
20867 }
20868 run_test 276 "Race between mount and obd_statfs"
20869
20870 test_277() {
20871         $LCTL set_param ldlm.namespaces.*.lru_size=0
20872         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20873         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20874                         grep ^used_mb | awk '{print $2}')
20875         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20876         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20877                 oflag=direct conv=notrunc
20878         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20879                         grep ^used_mb | awk '{print $2}')
20880         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20881 }
20882 run_test 277 "Direct IO shall drop page cache"
20883
20884 test_278() {
20885         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20886         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20887         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20888                 skip "needs the same host for mdt1 mdt2" && return
20889
20890         local pid1
20891         local pid2
20892
20893 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20894         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20895         stop mds2 &
20896         pid2=$!
20897
20898         stop mds1
20899
20900         echo "Starting MDTs"
20901         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20902         wait $pid2
20903 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20904 #will return NULL
20905         do_facet mds2 $LCTL set_param fail_loc=0
20906
20907         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20908         wait_recovery_complete mds2
20909 }
20910 run_test 278 "Race starting MDS between MDTs stop/start"
20911
20912 test_280() {
20913         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20914                 skip "Need MGS version at least 2.13.52"
20915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20916         combined_mgs_mds || skip "needs combined MGS/MDT"
20917
20918         umount_client $MOUNT
20919 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20920         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20921
20922         mount_client $MOUNT &
20923         sleep 1
20924         stop mgs || error "stop mgs failed"
20925         #for a race mgs would crash
20926         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20927         mount_client $MOUNT || error "mount client failed"
20928 }
20929 run_test 280 "Race between MGS umount and client llog processing"
20930
20931 cleanup_test_300() {
20932         trap 0
20933         umask $SAVE_UMASK
20934 }
20935 test_striped_dir() {
20936         local mdt_index=$1
20937         local stripe_count
20938         local stripe_index
20939
20940         mkdir -p $DIR/$tdir
20941
20942         SAVE_UMASK=$(umask)
20943         trap cleanup_test_300 RETURN EXIT
20944
20945         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20946                                                 $DIR/$tdir/striped_dir ||
20947                 error "set striped dir error"
20948
20949         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20950         [ "$mode" = "755" ] || error "expect 755 got $mode"
20951
20952         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20953                 error "getdirstripe failed"
20954         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20955         if [ "$stripe_count" != "2" ]; then
20956                 error "1:stripe_count is $stripe_count, expect 2"
20957         fi
20958         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20959         if [ "$stripe_count" != "2" ]; then
20960                 error "2:stripe_count is $stripe_count, expect 2"
20961         fi
20962
20963         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20964         if [ "$stripe_index" != "$mdt_index" ]; then
20965                 error "stripe_index is $stripe_index, expect $mdt_index"
20966         fi
20967
20968         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20969                 error "nlink error after create striped dir"
20970
20971         mkdir $DIR/$tdir/striped_dir/a
20972         mkdir $DIR/$tdir/striped_dir/b
20973
20974         stat $DIR/$tdir/striped_dir/a ||
20975                 error "create dir under striped dir failed"
20976         stat $DIR/$tdir/striped_dir/b ||
20977                 error "create dir under striped dir failed"
20978
20979         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20980                 error "nlink error after mkdir"
20981
20982         rmdir $DIR/$tdir/striped_dir/a
20983         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20984                 error "nlink error after rmdir"
20985
20986         rmdir $DIR/$tdir/striped_dir/b
20987         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20988                 error "nlink error after rmdir"
20989
20990         chattr +i $DIR/$tdir/striped_dir
20991         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20992                 error "immutable flags not working under striped dir!"
20993         chattr -i $DIR/$tdir/striped_dir
20994
20995         rmdir $DIR/$tdir/striped_dir ||
20996                 error "rmdir striped dir error"
20997
20998         cleanup_test_300
20999
21000         true
21001 }
21002
21003 test_300a() {
21004         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21005                 skip "skipped for lustre < 2.7.0"
21006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21008
21009         test_striped_dir 0 || error "failed on striped dir on MDT0"
21010         test_striped_dir 1 || error "failed on striped dir on MDT0"
21011 }
21012 run_test 300a "basic striped dir sanity test"
21013
21014 test_300b() {
21015         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21016                 skip "skipped for lustre < 2.7.0"
21017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21018         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21019
21020         local i
21021         local mtime1
21022         local mtime2
21023         local mtime3
21024
21025         test_mkdir $DIR/$tdir || error "mkdir fail"
21026         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21027                 error "set striped dir error"
21028         for i in {0..9}; do
21029                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21030                 sleep 1
21031                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21032                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21033                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21034                 sleep 1
21035                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21036                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21037                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21038         done
21039         true
21040 }
21041 run_test 300b "check ctime/mtime for striped dir"
21042
21043 test_300c() {
21044         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21045                 skip "skipped for lustre < 2.7.0"
21046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21048
21049         local file_count
21050
21051         mkdir -p $DIR/$tdir
21052         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21053                 error "set striped dir error"
21054
21055         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21056                 error "chown striped dir failed"
21057
21058         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21059                 error "create 5k files failed"
21060
21061         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21062
21063         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21064
21065         rm -rf $DIR/$tdir
21066 }
21067 run_test 300c "chown && check ls under striped directory"
21068
21069 test_300d() {
21070         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21071                 skip "skipped for lustre < 2.7.0"
21072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21073         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21074
21075         local stripe_count
21076         local file
21077
21078         mkdir -p $DIR/$tdir
21079         $LFS setstripe -c 2 $DIR/$tdir
21080
21081         #local striped directory
21082         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21083                 error "set striped dir error"
21084         #look at the directories for debug purposes
21085         ls -l $DIR/$tdir
21086         $LFS getdirstripe $DIR/$tdir
21087         ls -l $DIR/$tdir/striped_dir
21088         $LFS getdirstripe $DIR/$tdir/striped_dir
21089         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21090                 error "create 10 files failed"
21091
21092         #remote striped directory
21093         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21094                 error "set striped dir error"
21095         #look at the directories for debug purposes
21096         ls -l $DIR/$tdir
21097         $LFS getdirstripe $DIR/$tdir
21098         ls -l $DIR/$tdir/remote_striped_dir
21099         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21100         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21101                 error "create 10 files failed"
21102
21103         for file in $(find $DIR/$tdir); do
21104                 stripe_count=$($LFS getstripe -c $file)
21105                 [ $stripe_count -eq 2 ] ||
21106                         error "wrong stripe $stripe_count for $file"
21107         done
21108
21109         rm -rf $DIR/$tdir
21110 }
21111 run_test 300d "check default stripe under striped directory"
21112
21113 test_300e() {
21114         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21115                 skip "Need MDS version at least 2.7.55"
21116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21118
21119         local stripe_count
21120         local file
21121
21122         mkdir -p $DIR/$tdir
21123
21124         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21125                 error "set striped dir error"
21126
21127         touch $DIR/$tdir/striped_dir/a
21128         touch $DIR/$tdir/striped_dir/b
21129         touch $DIR/$tdir/striped_dir/c
21130
21131         mkdir $DIR/$tdir/striped_dir/dir_a
21132         mkdir $DIR/$tdir/striped_dir/dir_b
21133         mkdir $DIR/$tdir/striped_dir/dir_c
21134
21135         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21136                 error "set striped adir under striped dir error"
21137
21138         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21139                 error "set striped bdir under striped dir error"
21140
21141         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21142                 error "set striped cdir under striped dir error"
21143
21144         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21145                 error "rename dir under striped dir fails"
21146
21147         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21148                 error "rename dir under different stripes fails"
21149
21150         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21151                 error "rename file under striped dir should succeed"
21152
21153         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21154                 error "rename dir under striped dir should succeed"
21155
21156         rm -rf $DIR/$tdir
21157 }
21158 run_test 300e "check rename under striped directory"
21159
21160 test_300f() {
21161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21162         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21163         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21164                 skip "Need MDS version at least 2.7.55"
21165
21166         local stripe_count
21167         local file
21168
21169         rm -rf $DIR/$tdir
21170         mkdir -p $DIR/$tdir
21171
21172         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21173                 error "set striped dir error"
21174
21175         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21176                 error "set striped dir error"
21177
21178         touch $DIR/$tdir/striped_dir/a
21179         mkdir $DIR/$tdir/striped_dir/dir_a
21180         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21181                 error "create striped dir under striped dir fails"
21182
21183         touch $DIR/$tdir/striped_dir1/b
21184         mkdir $DIR/$tdir/striped_dir1/dir_b
21185         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21186                 error "create striped dir under striped dir fails"
21187
21188         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21189                 error "rename dir under different striped dir should fail"
21190
21191         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21192                 error "rename striped dir under diff striped dir should fail"
21193
21194         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21195                 error "rename file under diff striped dirs fails"
21196
21197         rm -rf $DIR/$tdir
21198 }
21199 run_test 300f "check rename cross striped directory"
21200
21201 test_300_check_default_striped_dir()
21202 {
21203         local dirname=$1
21204         local default_count=$2
21205         local default_index=$3
21206         local stripe_count
21207         local stripe_index
21208         local dir_stripe_index
21209         local dir
21210
21211         echo "checking $dirname $default_count $default_index"
21212         $LFS setdirstripe -D -c $default_count -i $default_index \
21213                                 -t all_char $DIR/$tdir/$dirname ||
21214                 error "set default stripe on striped dir error"
21215         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21216         [ $stripe_count -eq $default_count ] ||
21217                 error "expect $default_count get $stripe_count for $dirname"
21218
21219         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21220         [ $stripe_index -eq $default_index ] ||
21221                 error "expect $default_index get $stripe_index for $dirname"
21222
21223         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21224                                                 error "create dirs failed"
21225
21226         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21227         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21228         for dir in $(find $DIR/$tdir/$dirname/*); do
21229                 stripe_count=$($LFS getdirstripe -c $dir)
21230                 [ $stripe_count -eq $default_count ] ||
21231                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21232                 error "stripe count $default_count != $stripe_count for $dir"
21233
21234                 stripe_index=$($LFS getdirstripe -i $dir)
21235                 [ $default_index -eq -1 ] ||
21236                         [ $stripe_index -eq $default_index ] ||
21237                         error "$stripe_index != $default_index for $dir"
21238
21239                 #check default stripe
21240                 stripe_count=$($LFS getdirstripe -D -c $dir)
21241                 [ $stripe_count -eq $default_count ] ||
21242                 error "default count $default_count != $stripe_count for $dir"
21243
21244                 stripe_index=$($LFS getdirstripe -D -i $dir)
21245                 [ $stripe_index -eq $default_index ] ||
21246                 error "default index $default_index != $stripe_index for $dir"
21247         done
21248         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21249 }
21250
21251 test_300g() {
21252         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21253         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21254                 skip "Need MDS version at least 2.7.55"
21255
21256         local dir
21257         local stripe_count
21258         local stripe_index
21259
21260         mkdir $DIR/$tdir
21261         mkdir $DIR/$tdir/normal_dir
21262
21263         #Checking when client cache stripe index
21264         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21265         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21266                 error "create striped_dir failed"
21267
21268         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21269                 error "create dir0 fails"
21270         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21271         [ $stripe_index -eq 0 ] ||
21272                 error "dir0 expect index 0 got $stripe_index"
21273
21274         mkdir $DIR/$tdir/striped_dir/dir1 ||
21275                 error "create dir1 fails"
21276         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21277         [ $stripe_index -eq 1 ] ||
21278                 error "dir1 expect index 1 got $stripe_index"
21279
21280         #check default stripe count/stripe index
21281         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21282         test_300_check_default_striped_dir normal_dir 1 0
21283         test_300_check_default_striped_dir normal_dir 2 1
21284         test_300_check_default_striped_dir normal_dir 2 -1
21285
21286         #delete default stripe information
21287         echo "delete default stripeEA"
21288         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21289                 error "set default stripe on striped dir error"
21290
21291         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21292         for dir in $(find $DIR/$tdir/normal_dir/*); do
21293                 stripe_count=$($LFS getdirstripe -c $dir)
21294                 [ $stripe_count -eq 0 ] ||
21295                         error "expect 1 get $stripe_count for $dir"
21296                 stripe_index=$($LFS getdirstripe -i $dir)
21297                 [ $stripe_index -eq 0 ] ||
21298                         error "expect 0 get $stripe_index for $dir"
21299         done
21300 }
21301 run_test 300g "check default striped directory for normal directory"
21302
21303 test_300h() {
21304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21305         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21306                 skip "Need MDS version at least 2.7.55"
21307
21308         local dir
21309         local stripe_count
21310
21311         mkdir $DIR/$tdir
21312         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21313                 error "set striped dir error"
21314
21315         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21316         test_300_check_default_striped_dir striped_dir 1 0
21317         test_300_check_default_striped_dir striped_dir 2 1
21318         test_300_check_default_striped_dir striped_dir 2 -1
21319
21320         #delete default stripe information
21321         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21322                 error "set default stripe on striped dir error"
21323
21324         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21325         for dir in $(find $DIR/$tdir/striped_dir/*); do
21326                 stripe_count=$($LFS getdirstripe -c $dir)
21327                 [ $stripe_count -eq 0 ] ||
21328                         error "expect 1 get $stripe_count for $dir"
21329         done
21330 }
21331 run_test 300h "check default striped directory for striped directory"
21332
21333 test_300i() {
21334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21336         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21337                 skip "Need MDS version at least 2.7.55"
21338
21339         local stripe_count
21340         local file
21341
21342         mkdir $DIR/$tdir
21343
21344         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21345                 error "set striped dir error"
21346
21347         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21348                 error "create files under striped dir failed"
21349
21350         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21351                 error "set striped hashdir error"
21352
21353         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21354                 error "create dir0 under hash dir failed"
21355         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21356                 error "create dir1 under hash dir failed"
21357
21358         # unfortunately, we need to umount to clear dir layout cache for now
21359         # once we fully implement dir layout, we can drop this
21360         umount_client $MOUNT || error "umount failed"
21361         mount_client $MOUNT || error "mount failed"
21362
21363         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21364         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21365         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21366
21367         #set the stripe to be unknown hash type
21368         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21369         $LCTL set_param fail_loc=0x1901
21370         for ((i = 0; i < 10; i++)); do
21371                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21372                         error "stat f-$i failed"
21373                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21374         done
21375
21376         touch $DIR/$tdir/striped_dir/f0 &&
21377                 error "create under striped dir with unknown hash should fail"
21378
21379         $LCTL set_param fail_loc=0
21380
21381         umount_client $MOUNT || error "umount failed"
21382         mount_client $MOUNT || error "mount failed"
21383
21384         return 0
21385 }
21386 run_test 300i "client handle unknown hash type striped directory"
21387
21388 test_300j() {
21389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21391         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21392                 skip "Need MDS version at least 2.7.55"
21393
21394         local stripe_count
21395         local file
21396
21397         mkdir $DIR/$tdir
21398
21399         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21400         $LCTL set_param fail_loc=0x1702
21401         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21402                 error "set striped dir error"
21403
21404         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21405                 error "create files under striped dir failed"
21406
21407         $LCTL set_param fail_loc=0
21408
21409         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21410
21411         return 0
21412 }
21413 run_test 300j "test large update record"
21414
21415 test_300k() {
21416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21418         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21419                 skip "Need MDS version at least 2.7.55"
21420
21421         # this test needs a huge transaction
21422         local kb
21423         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21424              osd*.$FSNAME-MDT0000.kbytestotal")
21425         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21426
21427         local stripe_count
21428         local file
21429
21430         mkdir $DIR/$tdir
21431
21432         #define OBD_FAIL_LARGE_STRIPE   0x1703
21433         $LCTL set_param fail_loc=0x1703
21434         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21435                 error "set striped dir error"
21436         $LCTL set_param fail_loc=0
21437
21438         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21439                 error "getstripeddir fails"
21440         rm -rf $DIR/$tdir/striped_dir ||
21441                 error "unlink striped dir fails"
21442
21443         return 0
21444 }
21445 run_test 300k "test large striped directory"
21446
21447 test_300l() {
21448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21450         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21451                 skip "Need MDS version at least 2.7.55"
21452
21453         local stripe_index
21454
21455         test_mkdir -p $DIR/$tdir/striped_dir
21456         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21457                         error "chown $RUNAS_ID failed"
21458         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21459                 error "set default striped dir failed"
21460
21461         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21462         $LCTL set_param fail_loc=0x80000158
21463         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21464
21465         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21466         [ $stripe_index -eq 1 ] ||
21467                 error "expect 1 get $stripe_index for $dir"
21468 }
21469 run_test 300l "non-root user to create dir under striped dir with stale layout"
21470
21471 test_300m() {
21472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21473         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21474         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21475                 skip "Need MDS version at least 2.7.55"
21476
21477         mkdir -p $DIR/$tdir/striped_dir
21478         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21479                 error "set default stripes dir error"
21480
21481         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21482
21483         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21484         [ $stripe_count -eq 0 ] ||
21485                         error "expect 0 get $stripe_count for a"
21486
21487         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21488                 error "set default stripes dir error"
21489
21490         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21491
21492         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21493         [ $stripe_count -eq 0 ] ||
21494                         error "expect 0 get $stripe_count for b"
21495
21496         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21497                 error "set default stripes dir error"
21498
21499         mkdir $DIR/$tdir/striped_dir/c &&
21500                 error "default stripe_index is invalid, mkdir c should fails"
21501
21502         rm -rf $DIR/$tdir || error "rmdir fails"
21503 }
21504 run_test 300m "setstriped directory on single MDT FS"
21505
21506 cleanup_300n() {
21507         local list=$(comma_list $(mdts_nodes))
21508
21509         trap 0
21510         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21511 }
21512
21513 test_300n() {
21514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21515         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21516         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21517                 skip "Need MDS version at least 2.7.55"
21518         remote_mds_nodsh && skip "remote MDS with nodsh"
21519
21520         local stripe_index
21521         local list=$(comma_list $(mdts_nodes))
21522
21523         trap cleanup_300n RETURN EXIT
21524         mkdir -p $DIR/$tdir
21525         chmod 777 $DIR/$tdir
21526         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21527                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21528                 error "create striped dir succeeds with gid=0"
21529
21530         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21531         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21532                 error "create striped dir fails with gid=-1"
21533
21534         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21535         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21536                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21537                 error "set default striped dir succeeds with gid=0"
21538
21539
21540         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21541         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21542                 error "set default striped dir fails with gid=-1"
21543
21544
21545         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21546         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21547                                         error "create test_dir fails"
21548         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21549                                         error "create test_dir1 fails"
21550         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21551                                         error "create test_dir2 fails"
21552         cleanup_300n
21553 }
21554 run_test 300n "non-root user to create dir under striped dir with default EA"
21555
21556 test_300o() {
21557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21559         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21560                 skip "Need MDS version at least 2.7.55"
21561
21562         local numfree1
21563         local numfree2
21564
21565         mkdir -p $DIR/$tdir
21566
21567         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21568         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21569         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21570                 skip "not enough free inodes $numfree1 $numfree2"
21571         fi
21572
21573         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21574         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21575         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21576                 skip "not enough free space $numfree1 $numfree2"
21577         fi
21578
21579         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21580                 error "setdirstripe fails"
21581
21582         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21583                 error "create dirs fails"
21584
21585         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21586         ls $DIR/$tdir/striped_dir > /dev/null ||
21587                 error "ls striped dir fails"
21588         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21589                 error "unlink big striped dir fails"
21590 }
21591 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21592
21593 test_300p() {
21594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21596         remote_mds_nodsh && skip "remote MDS with nodsh"
21597
21598         mkdir -p $DIR/$tdir
21599
21600         #define OBD_FAIL_OUT_ENOSPC     0x1704
21601         do_facet mds2 lctl set_param fail_loc=0x80001704
21602         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21603                  && error "create striped directory should fail"
21604
21605         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21606
21607         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21608         true
21609 }
21610 run_test 300p "create striped directory without space"
21611
21612 test_300q() {
21613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21614         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21615
21616         local fd=$(free_fd)
21617         local cmd="exec $fd<$tdir"
21618         cd $DIR
21619         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21620         eval $cmd
21621         cmd="exec $fd<&-"
21622         trap "eval $cmd" EXIT
21623         cd $tdir || error "cd $tdir fails"
21624         rmdir  ../$tdir || error "rmdir $tdir fails"
21625         mkdir local_dir && error "create dir succeeds"
21626         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21627         eval $cmd
21628         return 0
21629 }
21630 run_test 300q "create remote directory under orphan directory"
21631
21632 test_300r() {
21633         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21634                 skip "Need MDS version at least 2.7.55" && return
21635         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21636
21637         mkdir $DIR/$tdir
21638
21639         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21640                 error "set striped dir error"
21641
21642         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21643                 error "getstripeddir fails"
21644
21645         local stripe_count
21646         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21647                       awk '/lmv_stripe_count:/ { print $2 }')
21648
21649         [ $MDSCOUNT -ne $stripe_count ] &&
21650                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21651
21652         rm -rf $DIR/$tdir/striped_dir ||
21653                 error "unlink striped dir fails"
21654 }
21655 run_test 300r "test -1 striped directory"
21656
21657 prepare_remote_file() {
21658         mkdir $DIR/$tdir/src_dir ||
21659                 error "create remote source failed"
21660
21661         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21662                  error "cp to remote source failed"
21663         touch $DIR/$tdir/src_dir/a
21664
21665         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21666                 error "create remote target dir failed"
21667
21668         touch $DIR/$tdir/tgt_dir/b
21669
21670         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21671                 error "rename dir cross MDT failed!"
21672
21673         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21674                 error "src_child still exists after rename"
21675
21676         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21677                 error "missing file(a) after rename"
21678
21679         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21680                 error "diff after rename"
21681 }
21682
21683 test_310a() {
21684         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21686
21687         local remote_file=$DIR/$tdir/tgt_dir/b
21688
21689         mkdir -p $DIR/$tdir
21690
21691         prepare_remote_file || error "prepare remote file failed"
21692
21693         #open-unlink file
21694         $OPENUNLINK $remote_file $remote_file ||
21695                 error "openunlink $remote_file failed"
21696         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21697 }
21698 run_test 310a "open unlink remote file"
21699
21700 test_310b() {
21701         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21703
21704         local remote_file=$DIR/$tdir/tgt_dir/b
21705
21706         mkdir -p $DIR/$tdir
21707
21708         prepare_remote_file || error "prepare remote file failed"
21709
21710         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21711         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21712         $CHECKSTAT -t file $remote_file || error "check file failed"
21713 }
21714 run_test 310b "unlink remote file with multiple links while open"
21715
21716 test_310c() {
21717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21718         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21719
21720         local remote_file=$DIR/$tdir/tgt_dir/b
21721
21722         mkdir -p $DIR/$tdir
21723
21724         prepare_remote_file || error "prepare remote file failed"
21725
21726         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21727         multiop_bg_pause $remote_file O_uc ||
21728                         error "mulitop failed for remote file"
21729         MULTIPID=$!
21730         $MULTIOP $DIR/$tfile Ouc
21731         kill -USR1 $MULTIPID
21732         wait $MULTIPID
21733 }
21734 run_test 310c "open-unlink remote file with multiple links"
21735
21736 #LU-4825
21737 test_311() {
21738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21739         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21740         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21741                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21742         remote_mds_nodsh && skip "remote MDS with nodsh"
21743
21744         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21745         local mdts=$(comma_list $(mdts_nodes))
21746
21747         mkdir -p $DIR/$tdir
21748         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21749         createmany -o $DIR/$tdir/$tfile. 1000
21750
21751         # statfs data is not real time, let's just calculate it
21752         old_iused=$((old_iused + 1000))
21753
21754         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21755                         osp.*OST0000*MDT0000.create_count")
21756         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21757                                 osp.*OST0000*MDT0000.max_create_count")
21758         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21759
21760         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21761         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21762         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21763
21764         unlinkmany $DIR/$tdir/$tfile. 1000
21765
21766         do_nodes $mdts "$LCTL set_param -n \
21767                         osp.*OST0000*.max_create_count=$max_count"
21768         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21769                 do_nodes $mdts "$LCTL set_param -n \
21770                                 osp.*OST0000*.create_count=$count"
21771         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21772                         grep "=0" && error "create_count is zero"
21773
21774         local new_iused
21775         for i in $(seq 120); do
21776                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21777                 # system may be too busy to destroy all objs in time, use
21778                 # a somewhat small value to not fail autotest
21779                 [ $((old_iused - new_iused)) -gt 400 ] && break
21780                 sleep 1
21781         done
21782
21783         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21784         [ $((old_iused - new_iused)) -gt 400 ] ||
21785                 error "objs not destroyed after unlink"
21786 }
21787 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21788
21789 zfs_oid_to_objid()
21790 {
21791         local ost=$1
21792         local objid=$2
21793
21794         local vdevdir=$(dirname $(facet_vdevice $ost))
21795         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21796         local zfs_zapid=$(do_facet $ost $cmd |
21797                           grep -w "/O/0/d$((objid%32))" -C 5 |
21798                           awk '/Object/{getline; print $1}')
21799         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21800                           awk "/$objid = /"'{printf $3}')
21801
21802         echo $zfs_objid
21803 }
21804
21805 zfs_object_blksz() {
21806         local ost=$1
21807         local objid=$2
21808
21809         local vdevdir=$(dirname $(facet_vdevice $ost))
21810         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21811         local blksz=$(do_facet $ost $cmd $objid |
21812                       awk '/dblk/{getline; printf $4}')
21813
21814         case "${blksz: -1}" in
21815                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21816                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21817                 *) ;;
21818         esac
21819
21820         echo $blksz
21821 }
21822
21823 test_312() { # LU-4856
21824         remote_ost_nodsh && skip "remote OST with nodsh"
21825         [ "$ost1_FSTYPE" = "zfs" ] ||
21826                 skip_env "the test only applies to zfs"
21827
21828         local max_blksz=$(do_facet ost1 \
21829                           $ZFS get -p recordsize $(facet_device ost1) |
21830                           awk '!/VALUE/{print $3}')
21831
21832         # to make life a little bit easier
21833         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21834         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21835
21836         local tf=$DIR/$tdir/$tfile
21837         touch $tf
21838         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21839
21840         # Get ZFS object id
21841         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21842         # block size change by sequential overwrite
21843         local bs
21844
21845         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21846                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21847
21848                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21849                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21850         done
21851         rm -f $tf
21852
21853         # block size change by sequential append write
21854         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21855         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21856         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21857         local count
21858
21859         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21860                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21861                         oflag=sync conv=notrunc
21862
21863                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21864                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21865                         error "blksz error, actual $blksz, " \
21866                                 "expected: 2 * $count * $PAGE_SIZE"
21867         done
21868         rm -f $tf
21869
21870         # random write
21871         touch $tf
21872         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21873         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21874
21875         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21876         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21877         [ $blksz -eq $PAGE_SIZE ] ||
21878                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21879
21880         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21881         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21882         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21883
21884         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21885         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21886         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21887 }
21888 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21889
21890 test_313() {
21891         remote_ost_nodsh && skip "remote OST with nodsh"
21892
21893         local file=$DIR/$tfile
21894
21895         rm -f $file
21896         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21897
21898         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21899         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21900         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21901                 error "write should failed"
21902         do_facet ost1 "$LCTL set_param fail_loc=0"
21903         rm -f $file
21904 }
21905 run_test 313 "io should fail after last_rcvd update fail"
21906
21907 test_314() {
21908         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21909
21910         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21911         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21912         rm -f $DIR/$tfile
21913         wait_delete_completed
21914         do_facet ost1 "$LCTL set_param fail_loc=0"
21915 }
21916 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21917
21918 test_315() { # LU-618
21919         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21920
21921         local file=$DIR/$tfile
21922         rm -f $file
21923
21924         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21925                 error "multiop file write failed"
21926         $MULTIOP $file oO_RDONLY:r4063232_c &
21927         PID=$!
21928
21929         sleep 2
21930
21931         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21932         kill -USR1 $PID
21933
21934         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21935         rm -f $file
21936 }
21937 run_test 315 "read should be accounted"
21938
21939 test_316() {
21940         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21941         large_xattr_enabled || skip_env "ea_inode feature disabled"
21942
21943         rm -rf $DIR/$tdir/d
21944         mkdir -p $DIR/$tdir/d
21945         chown nobody $DIR/$tdir/d
21946         touch $DIR/$tdir/d/file
21947
21948         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21949 }
21950 run_test 316 "lfs mv"
21951
21952 test_317() {
21953         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21954                 skip "Need MDS version at least 2.11.53"
21955         if [ "$ost1_FSTYPE" == "zfs" ]; then
21956                 skip "LU-10370: no implementation for ZFS"
21957         fi
21958
21959         local trunc_sz
21960         local grant_blk_size
21961
21962         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21963                         awk '/grant_block_size:/ { print $2; exit; }')
21964         #
21965         # Create File of size 5M. Truncate it to below size's and verify
21966         # blocks count.
21967         #
21968         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21969                 error "Create file $DIR/$tfile failed"
21970         stack_trap "rm -f $DIR/$tfile" EXIT
21971
21972         for trunc_sz in 2097152 4097 4000 509 0; do
21973                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21974                         error "truncate $tfile to $trunc_sz failed"
21975                 local sz=$(stat --format=%s $DIR/$tfile)
21976                 local blk=$(stat --format=%b $DIR/$tfile)
21977                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21978                                      grant_blk_size) * 8))
21979
21980                 if [[ $blk -ne $trunc_blk ]]; then
21981                         $(which stat) $DIR/$tfile
21982                         error "Expected Block $trunc_blk got $blk for $tfile"
21983                 fi
21984
21985                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21986                         error "Expected Size $trunc_sz got $sz for $tfile"
21987         done
21988
21989         #
21990         # sparse file test
21991         # Create file with a hole and write actual two blocks. Block count
21992         # must be 16.
21993         #
21994         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21995                 conv=fsync || error "Create file : $DIR/$tfile"
21996
21997         # Calculate the final truncate size.
21998         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21999
22000         #
22001         # truncate to size $trunc_sz bytes. Strip the last block
22002         # The block count must drop to 8
22003         #
22004         $TRUNCATE $DIR/$tfile $trunc_sz ||
22005                 error "truncate $tfile to $trunc_sz failed"
22006
22007         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22008         sz=$(stat --format=%s $DIR/$tfile)
22009         blk=$(stat --format=%b $DIR/$tfile)
22010
22011         if [[ $blk -ne $trunc_bsz ]]; then
22012                 $(which stat) $DIR/$tfile
22013                 error "Expected Block $trunc_bsz got $blk for $tfile"
22014         fi
22015
22016         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22017                 error "Expected Size $trunc_sz got $sz for $tfile"
22018 }
22019 run_test 317 "Verify blocks get correctly update after truncate"
22020
22021 test_318() {
22022         local old_max_active=$($LCTL get_param -n \
22023                             llite.*.max_read_ahead_async_active 2>/dev/null)
22024
22025         $LCTL set_param llite.*.max_read_ahead_async_active=256
22026         local max_active=$($LCTL get_param -n \
22027                            llite.*.max_read_ahead_async_active 2>/dev/null)
22028         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22029
22030         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22031                 error "set max_read_ahead_async_active should succeed"
22032
22033         $LCTL set_param llite.*.max_read_ahead_async_active=512
22034         max_active=$($LCTL get_param -n \
22035                      llite.*.max_read_ahead_async_active 2>/dev/null)
22036         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22037
22038         # restore @max_active
22039         [ $old_max_active -ne 0 ] && $LCTL set_param \
22040                 llite.*.max_read_ahead_async_active=$old_max_active
22041
22042         local old_threshold=$($LCTL get_param -n \
22043                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22044         local max_per_file_mb=$($LCTL get_param -n \
22045                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22046
22047         local invalid=$(($max_per_file_mb + 1))
22048         $LCTL set_param \
22049                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22050                         && error "set $invalid should fail"
22051
22052         local valid=$(($invalid - 1))
22053         $LCTL set_param \
22054                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22055                         error "set $valid should succeed"
22056         local threshold=$($LCTL get_param -n \
22057                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22058         [ $threshold -eq $valid ] || error \
22059                 "expect threshold $valid got $threshold"
22060         $LCTL set_param \
22061                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22062 }
22063 run_test 318 "Verify async readahead tunables"
22064
22065 test_319() {
22066         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22067
22068         local before=$(date +%s)
22069         local evict
22070         local mdir=$DIR/$tdir
22071         local file=$mdir/xxx
22072
22073         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22074         touch $file
22075
22076 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22077         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22078         $LFS mv -m1 $file &
22079
22080         sleep 1
22081         dd if=$file of=/dev/null
22082         wait
22083         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22084           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22085
22086         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22087 }
22088 run_test 319 "lost lease lock on migrate error"
22089
22090 test_398a() { # LU-4198
22091         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22092         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22093
22094         # request a new lock on client
22095         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22096
22097         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22098         local lock_count=$($LCTL get_param -n \
22099                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22100         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22101
22102         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22103
22104         # no lock cached, should use lockless IO and not enqueue new lock
22105         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22106         lock_count=$($LCTL get_param -n \
22107                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22108         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22109 }
22110 run_test 398a "direct IO should cancel lock otherwise lockless"
22111
22112 test_398b() { # LU-4198
22113         which fio || skip_env "no fio installed"
22114         $LFS setstripe -c -1 $DIR/$tfile
22115
22116         local size=12
22117         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22118
22119         local njobs=4
22120         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22121         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22122                 --numjobs=$njobs --fallocate=none \
22123                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22124                 --filename=$DIR/$tfile &
22125         bg_pid=$!
22126
22127         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22128         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22129                 --numjobs=$njobs --fallocate=none \
22130                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22131                 --filename=$DIR/$tfile || true
22132         wait $bg_pid
22133
22134         rm -rf $DIR/$tfile
22135 }
22136 run_test 398b "DIO and buffer IO race"
22137
22138 test_398c() { # LU-4198
22139         which fio || skip_env "no fio installed"
22140
22141         saved_debug=$($LCTL get_param -n debug)
22142         $LCTL set_param debug=0
22143
22144         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22145         ((size /= 1024)) # by megabytes
22146         ((size /= 2)) # write half of the OST at most
22147         [ $size -gt 40 ] && size=40 #reduce test time anyway
22148
22149         $LFS setstripe -c 1 $DIR/$tfile
22150
22151         # it seems like ldiskfs reserves more space than necessary if the
22152         # writing blocks are not mapped, so it extends the file firstly
22153         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22154         cancel_lru_locks osc
22155
22156         # clear and verify rpc_stats later
22157         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22158
22159         local njobs=4
22160         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22161         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22162                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22163                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22164                 --filename=$DIR/$tfile
22165         [ $? -eq 0 ] || error "fio write error"
22166
22167         [ $($LCTL get_param -n \
22168          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22169                 error "Locks were requested while doing AIO"
22170
22171         # get the percentage of 1-page I/O
22172         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22173                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22174                 awk '{print $7}')
22175         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22176
22177         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22178         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22179                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22180                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22181                 --filename=$DIR/$tfile
22182         [ $? -eq 0 ] || error "fio mixed read write error"
22183
22184         echo "AIO with large block size ${size}M"
22185         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22186                 --numjobs=1 --fallocate=none --ioengine=libaio \
22187                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22188                 --filename=$DIR/$tfile
22189         [ $? -eq 0 ] || error "fio large block size failed"
22190
22191         rm -rf $DIR/$tfile
22192         $LCTL set_param debug="$saved_debug"
22193 }
22194 run_test 398c "run fio to test AIO"
22195
22196 test_398d() { #  LU-13846
22197         test -f aiocp || skip_env "no aiocp installed"
22198         local aio_file=$DIR/aio_file
22199
22200         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22201
22202         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22203         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22204
22205         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22206
22207         # make sure we don't crash and fail properly
22208         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22209                 error "aio not aligned with PAGE SIZE should fail"
22210
22211         rm -rf $DIR/$tfile $aio_file
22212 }
22213 run_test 398d "run aiocp to verify block size > stripe size"
22214
22215 test_fake_rw() {
22216         local read_write=$1
22217         if [ "$read_write" = "write" ]; then
22218                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22219         elif [ "$read_write" = "read" ]; then
22220                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22221         else
22222                 error "argument error"
22223         fi
22224
22225         # turn off debug for performance testing
22226         local saved_debug=$($LCTL get_param -n debug)
22227         $LCTL set_param debug=0
22228
22229         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22230
22231         # get ost1 size - $FSNAME-OST0000
22232         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22233         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22234         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22235
22236         if [ "$read_write" = "read" ]; then
22237                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22238         fi
22239
22240         local start_time=$(date +%s.%N)
22241         $dd_cmd bs=1M count=$blocks oflag=sync ||
22242                 error "real dd $read_write error"
22243         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22244
22245         if [ "$read_write" = "write" ]; then
22246                 rm -f $DIR/$tfile
22247         fi
22248
22249         # define OBD_FAIL_OST_FAKE_RW           0x238
22250         do_facet ost1 $LCTL set_param fail_loc=0x238
22251
22252         local start_time=$(date +%s.%N)
22253         $dd_cmd bs=1M count=$blocks oflag=sync ||
22254                 error "fake dd $read_write error"
22255         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22256
22257         if [ "$read_write" = "write" ]; then
22258                 # verify file size
22259                 cancel_lru_locks osc
22260                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22261                         error "$tfile size not $blocks MB"
22262         fi
22263         do_facet ost1 $LCTL set_param fail_loc=0
22264
22265         echo "fake $read_write $duration_fake vs. normal $read_write" \
22266                 "$duration in seconds"
22267         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22268                 error_not_in_vm "fake write is slower"
22269
22270         $LCTL set_param -n debug="$saved_debug"
22271         rm -f $DIR/$tfile
22272 }
22273 test_399a() { # LU-7655 for OST fake write
22274         remote_ost_nodsh && skip "remote OST with nodsh"
22275
22276         test_fake_rw write
22277 }
22278 run_test 399a "fake write should not be slower than normal write"
22279
22280 test_399b() { # LU-8726 for OST fake read
22281         remote_ost_nodsh && skip "remote OST with nodsh"
22282         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22283                 skip_env "ldiskfs only test"
22284         fi
22285
22286         test_fake_rw read
22287 }
22288 run_test 399b "fake read should not be slower than normal read"
22289
22290 test_400a() { # LU-1606, was conf-sanity test_74
22291         if ! which $CC > /dev/null 2>&1; then
22292                 skip_env "$CC is not installed"
22293         fi
22294
22295         local extra_flags=''
22296         local out=$TMP/$tfile
22297         local prefix=/usr/include/lustre
22298         local prog
22299
22300         # Oleg removes c files in his test rig so test if any c files exist
22301         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22302                 skip_env "Needed c test files are missing"
22303
22304         if ! [[ -d $prefix ]]; then
22305                 # Assume we're running in tree and fixup the include path.
22306                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22307                 extra_flags+=" -L$LUSTRE/utils/.lib"
22308         fi
22309
22310         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22311                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22312                         error "client api broken"
22313         done
22314         rm -f $out
22315 }
22316 run_test 400a "Lustre client api program can compile and link"
22317
22318 test_400b() { # LU-1606, LU-5011
22319         local header
22320         local out=$TMP/$tfile
22321         local prefix=/usr/include/linux/lustre
22322
22323         # We use a hard coded prefix so that this test will not fail
22324         # when run in tree. There are headers in lustre/include/lustre/
22325         # that are not packaged (like lustre_idl.h) and have more
22326         # complicated include dependencies (like config.h and lnet/types.h).
22327         # Since this test about correct packaging we just skip them when
22328         # they don't exist (see below) rather than try to fixup cppflags.
22329
22330         if ! which $CC > /dev/null 2>&1; then
22331                 skip_env "$CC is not installed"
22332         fi
22333
22334         for header in $prefix/*.h; do
22335                 if ! [[ -f "$header" ]]; then
22336                         continue
22337                 fi
22338
22339                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22340                         continue # lustre_ioctl.h is internal header
22341                 fi
22342
22343                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22344                         error "cannot compile '$header'"
22345         done
22346         rm -f $out
22347 }
22348 run_test 400b "packaged headers can be compiled"
22349
22350 test_401a() { #LU-7437
22351         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22352         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22353
22354         #count the number of parameters by "list_param -R"
22355         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22356         #count the number of parameters by listing proc files
22357         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22358         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22359         echo "proc_dirs='$proc_dirs'"
22360         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22361         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22362                       sort -u | wc -l)
22363
22364         [ $params -eq $procs ] ||
22365                 error "found $params parameters vs. $procs proc files"
22366
22367         # test the list_param -D option only returns directories
22368         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22369         #count the number of parameters by listing proc directories
22370         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22371                 sort -u | wc -l)
22372
22373         [ $params -eq $procs ] ||
22374                 error "found $params parameters vs. $procs proc files"
22375 }
22376 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22377
22378 test_401b() {
22379         # jobid_var may not allow arbitrary values, so use jobid_name
22380         # if available
22381         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22382                 local testname=jobid_name tmp='testing%p'
22383         else
22384                 local testname=jobid_var tmp=testing
22385         fi
22386
22387         local save=$($LCTL get_param -n $testname)
22388
22389         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22390                 error "no error returned when setting bad parameters"
22391
22392         local jobid_new=$($LCTL get_param -n foe $testname baz)
22393         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22394
22395         $LCTL set_param -n fog=bam $testname=$save bat=fog
22396         local jobid_old=$($LCTL get_param -n foe $testname bag)
22397         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22398 }
22399 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22400
22401 test_401c() {
22402         # jobid_var may not allow arbitrary values, so use jobid_name
22403         # if available
22404         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22405                 local testname=jobid_name
22406         else
22407                 local testname=jobid_var
22408         fi
22409
22410         local jobid_var_old=$($LCTL get_param -n $testname)
22411         local jobid_var_new
22412
22413         $LCTL set_param $testname= &&
22414                 error "no error returned for 'set_param a='"
22415
22416         jobid_var_new=$($LCTL get_param -n $testname)
22417         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22418                 error "$testname was changed by setting without value"
22419
22420         $LCTL set_param $testname &&
22421                 error "no error returned for 'set_param a'"
22422
22423         jobid_var_new=$($LCTL get_param -n $testname)
22424         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22425                 error "$testname was changed by setting without value"
22426 }
22427 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22428
22429 test_401d() {
22430         # jobid_var may not allow arbitrary values, so use jobid_name
22431         # if available
22432         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22433                 local testname=jobid_name new_value='foo=bar%p'
22434         else
22435                 local testname=jobid_var new_valuie=foo=bar
22436         fi
22437
22438         local jobid_var_old=$($LCTL get_param -n $testname)
22439         local jobid_var_new
22440
22441         $LCTL set_param $testname=$new_value ||
22442                 error "'set_param a=b' did not accept a value containing '='"
22443
22444         jobid_var_new=$($LCTL get_param -n $testname)
22445         [[ "$jobid_var_new" == "$new_value" ]] ||
22446                 error "'set_param a=b' failed on a value containing '='"
22447
22448         # Reset the $testname to test the other format
22449         $LCTL set_param $testname=$jobid_var_old
22450         jobid_var_new=$($LCTL get_param -n $testname)
22451         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22452                 error "failed to reset $testname"
22453
22454         $LCTL set_param $testname $new_value ||
22455                 error "'set_param a b' did not accept a value containing '='"
22456
22457         jobid_var_new=$($LCTL get_param -n $testname)
22458         [[ "$jobid_var_new" == "$new_value" ]] ||
22459                 error "'set_param a b' failed on a value containing '='"
22460
22461         $LCTL set_param $testname $jobid_var_old
22462         jobid_var_new=$($LCTL get_param -n $testname)
22463         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22464                 error "failed to reset $testname"
22465 }
22466 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22467
22468 test_402() {
22469         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22470         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22471                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22472         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22473                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22474                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22475         remote_mds_nodsh && skip "remote MDS with nodsh"
22476
22477         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22478 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22479         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22480         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22481                 echo "Touch failed - OK"
22482 }
22483 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22484
22485 test_403() {
22486         local file1=$DIR/$tfile.1
22487         local file2=$DIR/$tfile.2
22488         local tfile=$TMP/$tfile
22489
22490         rm -f $file1 $file2 $tfile
22491
22492         touch $file1
22493         ln $file1 $file2
22494
22495         # 30 sec OBD_TIMEOUT in ll_getattr()
22496         # right before populating st_nlink
22497         $LCTL set_param fail_loc=0x80001409
22498         stat -c %h $file1 > $tfile &
22499
22500         # create an alias, drop all locks and reclaim the dentry
22501         < $file2
22502         cancel_lru_locks mdc
22503         cancel_lru_locks osc
22504         sysctl -w vm.drop_caches=2
22505
22506         wait
22507
22508         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22509
22510         rm -f $tfile $file1 $file2
22511 }
22512 run_test 403 "i_nlink should not drop to zero due to aliasing"
22513
22514 test_404() { # LU-6601
22515         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22516                 skip "Need server version newer than 2.8.52"
22517         remote_mds_nodsh && skip "remote MDS with nodsh"
22518
22519         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22520                 awk '/osp .*-osc-MDT/ { print $4}')
22521
22522         local osp
22523         for osp in $mosps; do
22524                 echo "Deactivate: " $osp
22525                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22526                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22527                         awk -vp=$osp '$4 == p { print $2 }')
22528                 [ $stat = IN ] || {
22529                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22530                         error "deactivate error"
22531                 }
22532                 echo "Activate: " $osp
22533                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22534                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22535                         awk -vp=$osp '$4 == p { print $2 }')
22536                 [ $stat = UP ] || {
22537                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22538                         error "activate error"
22539                 }
22540         done
22541 }
22542 run_test 404 "validate manual {de}activated works properly for OSPs"
22543
22544 test_405() {
22545         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22546         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22547                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22548                         skip "Layout swap lock is not supported"
22549
22550         check_swap_layouts_support
22551         check_swap_layout_no_dom $DIR
22552
22553         test_mkdir $DIR/$tdir
22554         swap_lock_test -d $DIR/$tdir ||
22555                 error "One layout swap locked test failed"
22556 }
22557 run_test 405 "Various layout swap lock tests"
22558
22559 test_406() {
22560         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22561         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22562         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22564         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22565                 skip "Need MDS version at least 2.8.50"
22566
22567         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22568         local test_pool=$TESTNAME
22569
22570         pool_add $test_pool || error "pool_add failed"
22571         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22572                 error "pool_add_targets failed"
22573
22574         save_layout_restore_at_exit $MOUNT
22575
22576         # parent set default stripe count only, child will stripe from both
22577         # parent and fs default
22578         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22579                 error "setstripe $MOUNT failed"
22580         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22581         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22582         for i in $(seq 10); do
22583                 local f=$DIR/$tdir/$tfile.$i
22584                 touch $f || error "touch failed"
22585                 local count=$($LFS getstripe -c $f)
22586                 [ $count -eq $OSTCOUNT ] ||
22587                         error "$f stripe count $count != $OSTCOUNT"
22588                 local offset=$($LFS getstripe -i $f)
22589                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22590                 local size=$($LFS getstripe -S $f)
22591                 [ $size -eq $((def_stripe_size * 2)) ] ||
22592                         error "$f stripe size $size != $((def_stripe_size * 2))"
22593                 local pool=$($LFS getstripe -p $f)
22594                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22595         done
22596
22597         # change fs default striping, delete parent default striping, now child
22598         # will stripe from new fs default striping only
22599         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22600                 error "change $MOUNT default stripe failed"
22601         $LFS setstripe -c 0 $DIR/$tdir ||
22602                 error "delete $tdir default stripe failed"
22603         for i in $(seq 11 20); do
22604                 local f=$DIR/$tdir/$tfile.$i
22605                 touch $f || error "touch $f failed"
22606                 local count=$($LFS getstripe -c $f)
22607                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22608                 local offset=$($LFS getstripe -i $f)
22609                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22610                 local size=$($LFS getstripe -S $f)
22611                 [ $size -eq $def_stripe_size ] ||
22612                         error "$f stripe size $size != $def_stripe_size"
22613                 local pool=$($LFS getstripe -p $f)
22614                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22615         done
22616
22617         unlinkmany $DIR/$tdir/$tfile. 1 20
22618
22619         local f=$DIR/$tdir/$tfile
22620         pool_remove_all_targets $test_pool $f
22621         pool_remove $test_pool $f
22622 }
22623 run_test 406 "DNE support fs default striping"
22624
22625 test_407() {
22626         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22627         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22628                 skip "Need MDS version at least 2.8.55"
22629         remote_mds_nodsh && skip "remote MDS with nodsh"
22630
22631         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22632                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22633         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22634                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22635         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22636
22637         #define OBD_FAIL_DT_TXN_STOP    0x2019
22638         for idx in $(seq $MDSCOUNT); do
22639                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22640         done
22641         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22642         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22643                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22644         true
22645 }
22646 run_test 407 "transaction fail should cause operation fail"
22647
22648 test_408() {
22649         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22650
22651         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22652         lctl set_param fail_loc=0x8000040a
22653         # let ll_prepare_partial_page() fail
22654         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22655
22656         rm -f $DIR/$tfile
22657
22658         # create at least 100 unused inodes so that
22659         # shrink_icache_memory(0) should not return 0
22660         touch $DIR/$tfile-{0..100}
22661         rm -f $DIR/$tfile-{0..100}
22662         sync
22663
22664         echo 2 > /proc/sys/vm/drop_caches
22665 }
22666 run_test 408 "drop_caches should not hang due to page leaks"
22667
22668 test_409()
22669 {
22670         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22671
22672         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22673         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22674         touch $DIR/$tdir/guard || error "(2) Fail to create"
22675
22676         local PREFIX=$(str_repeat 'A' 128)
22677         echo "Create 1K hard links start at $(date)"
22678         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22679                 error "(3) Fail to hard link"
22680
22681         echo "Links count should be right although linkEA overflow"
22682         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22683         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22684         [ $linkcount -eq 1001 ] ||
22685                 error "(5) Unexpected hard links count: $linkcount"
22686
22687         echo "List all links start at $(date)"
22688         ls -l $DIR/$tdir/foo > /dev/null ||
22689                 error "(6) Fail to list $DIR/$tdir/foo"
22690
22691         echo "Unlink hard links start at $(date)"
22692         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22693                 error "(7) Fail to unlink"
22694         echo "Unlink hard links finished at $(date)"
22695 }
22696 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22697
22698 test_410()
22699 {
22700         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22701                 skip "Need client version at least 2.9.59"
22702         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22703                 skip "Need MODULES build"
22704
22705         # Create a file, and stat it from the kernel
22706         local testfile=$DIR/$tfile
22707         touch $testfile
22708
22709         local run_id=$RANDOM
22710         local my_ino=$(stat --format "%i" $testfile)
22711
22712         # Try to insert the module. This will always fail as the
22713         # module is designed to not be inserted.
22714         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22715             &> /dev/null
22716
22717         # Anything but success is a test failure
22718         dmesg | grep -q \
22719             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22720             error "no inode match"
22721 }
22722 run_test 410 "Test inode number returned from kernel thread"
22723
22724 cleanup_test411_cgroup() {
22725         trap 0
22726         rmdir "$1"
22727 }
22728
22729 test_411() {
22730         local cg_basedir=/sys/fs/cgroup/memory
22731         # LU-9966
22732         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22733                 skip "no setup for cgroup"
22734
22735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22736                 error "test file creation failed"
22737         cancel_lru_locks osc
22738
22739         # Create a very small memory cgroup to force a slab allocation error
22740         local cgdir=$cg_basedir/osc_slab_alloc
22741         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22742         trap "cleanup_test411_cgroup $cgdir" EXIT
22743         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22744         echo 1M > $cgdir/memory.limit_in_bytes
22745
22746         # Should not LBUG, just be killed by oom-killer
22747         # dd will return 0 even allocation failure in some environment.
22748         # So don't check return value
22749         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22750         cleanup_test411_cgroup $cgdir
22751
22752         return 0
22753 }
22754 run_test 411 "Slab allocation error with cgroup does not LBUG"
22755
22756 test_412() {
22757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22758         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22759                 skip "Need server version at least 2.10.55"
22760         fi
22761
22762         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22763                 error "mkdir failed"
22764         $LFS getdirstripe $DIR/$tdir
22765         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22766         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22767                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22768         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22769         [ $stripe_count -eq 2 ] ||
22770                 error "expect 2 get $stripe_count"
22771 }
22772 run_test 412 "mkdir on specific MDTs"
22773
22774 test_qos_mkdir() {
22775         local mkdir_cmd=$1
22776         local stripe_count=$2
22777         local mdts=$(comma_list $(mdts_nodes))
22778
22779         local testdir
22780         local lmv_qos_prio_free
22781         local lmv_qos_threshold_rr
22782         local lmv_qos_maxage
22783         local lod_qos_prio_free
22784         local lod_qos_threshold_rr
22785         local lod_qos_maxage
22786         local count
22787         local i
22788
22789         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22790         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22791         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22792                 head -n1)
22793         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22794         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22795         stack_trap "$LCTL set_param \
22796                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22797         stack_trap "$LCTL set_param \
22798                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22799         stack_trap "$LCTL set_param \
22800                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22801
22802         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22803                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22804         lod_qos_prio_free=${lod_qos_prio_free%%%}
22805         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22806                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22807         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22808         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22809                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22810         stack_trap "do_nodes $mdts $LCTL set_param \
22811                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22812         stack_trap "do_nodes $mdts $LCTL set_param \
22813                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22814                 EXIT
22815         stack_trap "do_nodes $mdts $LCTL set_param \
22816                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22817
22818         echo
22819         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22820
22821         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22822         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22823
22824         testdir=$DIR/$tdir-s$stripe_count/rr
22825
22826         for i in $(seq $((100 * MDSCOUNT))); do
22827                 eval $mkdir_cmd $testdir/subdir$i ||
22828                         error "$mkdir_cmd subdir$i failed"
22829         done
22830
22831         for i in $(seq $MDSCOUNT); do
22832                 count=$($LFS getdirstripe -i $testdir/* |
22833                                 grep ^$((i - 1))$ | wc -l)
22834                 echo "$count directories created on MDT$((i - 1))"
22835                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22836
22837                 if [ $stripe_count -gt 1 ]; then
22838                         count=$($LFS getdirstripe $testdir/* |
22839                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22840                         echo "$count stripes created on MDT$((i - 1))"
22841                         # deviation should < 5% of average
22842                         [ $count -lt $((95 * stripe_count)) ] ||
22843                         [ $count -gt $((105 * stripe_count)) ] &&
22844                                 error "stripes are not evenly distributed"
22845                 fi
22846         done
22847
22848         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22849         do_nodes $mdts $LCTL set_param \
22850                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22851
22852         echo
22853         echo "Check for uneven MDTs: "
22854
22855         local ffree
22856         local bavail
22857         local max
22858         local min
22859         local max_index
22860         local min_index
22861         local tmp
22862
22863         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22864         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22865         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22866
22867         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22868         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22869         max_index=0
22870         min_index=0
22871         for ((i = 1; i < ${#ffree[@]}; i++)); do
22872                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22873                 if [ $tmp -gt $max ]; then
22874                         max=$tmp
22875                         max_index=$i
22876                 fi
22877                 if [ $tmp -lt $min ]; then
22878                         min=$tmp
22879                         min_index=$i
22880                 fi
22881         done
22882
22883         [ ${ffree[min_index]} -eq 0 ] &&
22884                 skip "no free files in MDT$min_index"
22885         [ ${ffree[min_index]} -gt 100000000 ] &&
22886                 skip "too much free files in MDT$min_index"
22887
22888         # Check if we need to generate uneven MDTs
22889         local threshold=50
22890         local diff=$(((max - min) * 100 / min))
22891         local value="$(generate_string 1024)"
22892
22893         while [ $diff -lt $threshold ]; do
22894                 # generate uneven MDTs, create till $threshold% diff
22895                 echo -n "weight diff=$diff% must be > $threshold% ..."
22896                 count=$((${ffree[min_index]} / 10))
22897                 # 50 sec per 10000 files in vm
22898                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22899                         skip "$count files to create"
22900                 echo "Fill MDT$min_index with $count files"
22901                 [ -d $DIR/$tdir-MDT$min_index ] ||
22902                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22903                         error "mkdir $tdir-MDT$min_index failed"
22904                 for i in $(seq $count); do
22905                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22906                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22907                                 error "create f$j_$i failed"
22908                         setfattr -n user.413b -v $value \
22909                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22910                                 error "setfattr f$j_$i failed"
22911                 done
22912
22913                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22914                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22915                 max=$(((${ffree[max_index]} >> 8) * \
22916                         (${bavail[max_index]} * bsize >> 16)))
22917                 min=$(((${ffree[min_index]} >> 8) * \
22918                         (${bavail[min_index]} * bsize >> 16)))
22919                 diff=$(((max - min) * 100 / min))
22920         done
22921
22922         echo "MDT filesfree available: ${ffree[@]}"
22923         echo "MDT blocks available: ${bavail[@]}"
22924         echo "weight diff=$diff%"
22925
22926         echo
22927         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22928
22929         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22930         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22931         # decrease statfs age, so that it can be updated in time
22932         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22933         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22934
22935         sleep 1
22936
22937         testdir=$DIR/$tdir-s$stripe_count/qos
22938
22939         for i in $(seq $((100 * MDSCOUNT))); do
22940                 eval $mkdir_cmd $testdir/subdir$i ||
22941                         error "$mkdir_cmd subdir$i failed"
22942         done
22943
22944         for i in $(seq $MDSCOUNT); do
22945                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22946                         wc -l)
22947                 echo "$count directories created on MDT$((i - 1))"
22948
22949                 if [ $stripe_count -gt 1 ]; then
22950                         count=$($LFS getdirstripe $testdir/* |
22951                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22952                         echo "$count stripes created on MDT$((i - 1))"
22953                 fi
22954         done
22955
22956         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22957         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22958
22959         # D-value should > 10% of averge
22960         [ $((max - min)) -lt 10 ] &&
22961                 error "subdirs shouldn't be evenly distributed"
22962
22963         # ditto
22964         if [ $stripe_count -gt 1 ]; then
22965                 max=$($LFS getdirstripe $testdir/* |
22966                         grep -P "^\s+$max_index\t" | wc -l)
22967                 min=$($LFS getdirstripe $testdir/* |
22968                         grep -P "^\s+$min_index\t" | wc -l)
22969                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22970                         error "stripes shouldn't be evenly distributed"|| true
22971         fi
22972 }
22973
22974 test_413a() {
22975         [ $MDSCOUNT -lt 2 ] &&
22976                 skip "We need at least 2 MDTs for this test"
22977
22978         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22979                 skip "Need server version at least 2.12.52"
22980
22981         local stripe_count
22982
22983         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22984                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22985                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22986                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22987                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22988         done
22989 }
22990 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22991
22992 test_413b() {
22993         [ $MDSCOUNT -lt 2 ] &&
22994                 skip "We need at least 2 MDTs for this test"
22995
22996         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22997                 skip "Need server version at least 2.12.52"
22998
22999         local stripe_count
23000
23001         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23002                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23003                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23004                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23005                 $LFS setdirstripe -D -c $stripe_count \
23006                         $DIR/$tdir-s$stripe_count/rr ||
23007                         error "setdirstripe failed"
23008                 $LFS setdirstripe -D -c $stripe_count \
23009                         $DIR/$tdir-s$stripe_count/qos ||
23010                         error "setdirstripe failed"
23011                 test_qos_mkdir "mkdir" $stripe_count
23012         done
23013 }
23014 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23015
23016 test_414() {
23017 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23018         $LCTL set_param fail_loc=0x80000521
23019         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23020         rm -f $DIR/$tfile
23021 }
23022 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23023
23024 test_415() {
23025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23026         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23027                 skip "Need server version at least 2.11.52"
23028
23029         # LU-11102
23030         local total
23031         local setattr_pid
23032         local start_time
23033         local end_time
23034         local duration
23035
23036         total=500
23037         # this test may be slow on ZFS
23038         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23039
23040         # though this test is designed for striped directory, let's test normal
23041         # directory too since lock is always saved as CoS lock.
23042         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23043         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23044
23045         (
23046                 while true; do
23047                         touch $DIR/$tdir
23048                 done
23049         ) &
23050         setattr_pid=$!
23051
23052         start_time=$(date +%s)
23053         for i in $(seq $total); do
23054                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23055                         > /dev/null
23056         done
23057         end_time=$(date +%s)
23058         duration=$((end_time - start_time))
23059
23060         kill -9 $setattr_pid
23061
23062         echo "rename $total files took $duration sec"
23063         [ $duration -lt 100 ] || error "rename took $duration sec"
23064 }
23065 run_test 415 "lock revoke is not missing"
23066
23067 test_416() {
23068         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23069                 skip "Need server version at least 2.11.55"
23070
23071         # define OBD_FAIL_OSD_TXN_START    0x19a
23072         do_facet mds1 lctl set_param fail_loc=0x19a
23073
23074         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23075
23076         true
23077 }
23078 run_test 416 "transaction start failure won't cause system hung"
23079
23080 cleanup_417() {
23081         trap 0
23082         do_nodes $(comma_list $(mdts_nodes)) \
23083                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23084         do_nodes $(comma_list $(mdts_nodes)) \
23085                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23086         do_nodes $(comma_list $(mdts_nodes)) \
23087                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23088 }
23089
23090 test_417() {
23091         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23092         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23093                 skip "Need MDS version at least 2.11.56"
23094
23095         trap cleanup_417 RETURN EXIT
23096
23097         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23098         do_nodes $(comma_list $(mdts_nodes)) \
23099                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23100         $LFS migrate -m 0 $DIR/$tdir.1 &&
23101                 error "migrate dir $tdir.1 should fail"
23102
23103         do_nodes $(comma_list $(mdts_nodes)) \
23104                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23105         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23106                 error "create remote dir $tdir.2 should fail"
23107
23108         do_nodes $(comma_list $(mdts_nodes)) \
23109                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23110         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23111                 error "create striped dir $tdir.3 should fail"
23112         true
23113 }
23114 run_test 417 "disable remote dir, striped dir and dir migration"
23115
23116 # Checks that the outputs of df [-i] and lfs df [-i] match
23117 #
23118 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23119 check_lfs_df() {
23120         local dir=$2
23121         local inodes
23122         local df_out
23123         local lfs_df_out
23124         local count
23125         local passed=false
23126
23127         # blocks or inodes
23128         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23129
23130         for count in {1..100}; do
23131                 cancel_lru_locks
23132                 sync; sleep 0.2
23133
23134                 # read the lines of interest
23135                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23136                         error "df $inodes $dir | tail -n +2 failed"
23137                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23138                         error "lfs df $inodes $dir | grep summary: failed"
23139
23140                 # skip first substrings of each output as they are different
23141                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23142                 # compare the two outputs
23143                 passed=true
23144                 for i in {1..5}; do
23145                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23146                 done
23147                 $passed && break
23148         done
23149
23150         if ! $passed; then
23151                 df -P $inodes $dir
23152                 echo
23153                 lfs df $inodes $dir
23154                 error "df and lfs df $1 output mismatch: "      \
23155                       "df ${inodes}: ${df_out[*]}, "            \
23156                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23157         fi
23158 }
23159
23160 test_418() {
23161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23162
23163         local dir=$DIR/$tdir
23164         local numfiles=$((RANDOM % 4096 + 2))
23165         local numblocks=$((RANDOM % 256 + 1))
23166
23167         wait_delete_completed
23168         test_mkdir $dir
23169
23170         # check block output
23171         check_lfs_df blocks $dir
23172         # check inode output
23173         check_lfs_df inodes $dir
23174
23175         # create a single file and retest
23176         echo "Creating a single file and testing"
23177         createmany -o $dir/$tfile- 1 &>/dev/null ||
23178                 error "creating 1 file in $dir failed"
23179         check_lfs_df blocks $dir
23180         check_lfs_df inodes $dir
23181
23182         # create a random number of files
23183         echo "Creating $((numfiles - 1)) files and testing"
23184         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23185                 error "creating $((numfiles - 1)) files in $dir failed"
23186
23187         # write a random number of blocks to the first test file
23188         echo "Writing $numblocks 4K blocks and testing"
23189         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23190                 count=$numblocks &>/dev/null ||
23191                 error "dd to $dir/${tfile}-0 failed"
23192
23193         # retest
23194         check_lfs_df blocks $dir
23195         check_lfs_df inodes $dir
23196
23197         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23198                 error "unlinking $numfiles files in $dir failed"
23199 }
23200 run_test 418 "df and lfs df outputs match"
23201
23202 test_419()
23203 {
23204         local dir=$DIR/$tdir
23205
23206         mkdir -p $dir
23207         touch $dir/file
23208
23209         cancel_lru_locks mdc
23210
23211         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23212         $LCTL set_param fail_loc=0x1410
23213         cat $dir/file
23214         $LCTL set_param fail_loc=0
23215         rm -rf $dir
23216 }
23217 run_test 419 "Verify open file by name doesn't crash kernel"
23218
23219 test_420()
23220 {
23221         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23222                 skip "Need MDS version at least 2.12.53"
23223
23224         local SAVE_UMASK=$(umask)
23225         local dir=$DIR/$tdir
23226         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23227
23228         mkdir -p $dir
23229         umask 0000
23230         mkdir -m03777 $dir/testdir
23231         ls -dn $dir/testdir
23232         # Need to remove trailing '.' when SELinux is enabled
23233         local dirperms=$(ls -dn $dir/testdir |
23234                          awk '{ sub(/\.$/, "", $1); print $1}')
23235         [ $dirperms == "drwxrwsrwt" ] ||
23236                 error "incorrect perms on $dir/testdir"
23237
23238         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23239                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23240         ls -n $dir/testdir/testfile
23241         local fileperms=$(ls -n $dir/testdir/testfile |
23242                           awk '{ sub(/\.$/, "", $1); print $1}')
23243         [ $fileperms == "-rwxr-xr-x" ] ||
23244                 error "incorrect perms on $dir/testdir/testfile"
23245
23246         umask $SAVE_UMASK
23247 }
23248 run_test 420 "clear SGID bit on non-directories for non-members"
23249
23250 test_421a() {
23251         local cnt
23252         local fid1
23253         local fid2
23254
23255         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23256                 skip "Need MDS version at least 2.12.54"
23257
23258         test_mkdir $DIR/$tdir
23259         createmany -o $DIR/$tdir/f 3
23260         cnt=$(ls -1 $DIR/$tdir | wc -l)
23261         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23262
23263         fid1=$(lfs path2fid $DIR/$tdir/f1)
23264         fid2=$(lfs path2fid $DIR/$tdir/f2)
23265         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23266
23267         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23268         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23269
23270         cnt=$(ls -1 $DIR/$tdir | wc -l)
23271         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23272
23273         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23274         createmany -o $DIR/$tdir/f 3
23275         cnt=$(ls -1 $DIR/$tdir | wc -l)
23276         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23277
23278         fid1=$(lfs path2fid $DIR/$tdir/f1)
23279         fid2=$(lfs path2fid $DIR/$tdir/f2)
23280         echo "remove using fsname $FSNAME"
23281         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23282
23283         cnt=$(ls -1 $DIR/$tdir | wc -l)
23284         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23285 }
23286 run_test 421a "simple rm by fid"
23287
23288 test_421b() {
23289         local cnt
23290         local FID1
23291         local FID2
23292
23293         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23294                 skip "Need MDS version at least 2.12.54"
23295
23296         test_mkdir $DIR/$tdir
23297         createmany -o $DIR/$tdir/f 3
23298         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23299         MULTIPID=$!
23300
23301         FID1=$(lfs path2fid $DIR/$tdir/f1)
23302         FID2=$(lfs path2fid $DIR/$tdir/f2)
23303         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23304
23305         kill -USR1 $MULTIPID
23306         wait
23307
23308         cnt=$(ls $DIR/$tdir | wc -l)
23309         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23310 }
23311 run_test 421b "rm by fid on open file"
23312
23313 test_421c() {
23314         local cnt
23315         local FIDS
23316
23317         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23318                 skip "Need MDS version at least 2.12.54"
23319
23320         test_mkdir $DIR/$tdir
23321         createmany -o $DIR/$tdir/f 3
23322         touch $DIR/$tdir/$tfile
23323         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23324         cnt=$(ls -1 $DIR/$tdir | wc -l)
23325         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23326
23327         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23328         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23329
23330         cnt=$(ls $DIR/$tdir | wc -l)
23331         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23332 }
23333 run_test 421c "rm by fid against hardlinked files"
23334
23335 test_421d() {
23336         local cnt
23337         local FIDS
23338
23339         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23340                 skip "Need MDS version at least 2.12.54"
23341
23342         test_mkdir $DIR/$tdir
23343         createmany -o $DIR/$tdir/f 4097
23344         cnt=$(ls -1 $DIR/$tdir | wc -l)
23345         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23346
23347         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23348         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23349
23350         cnt=$(ls $DIR/$tdir | wc -l)
23351         rm -rf $DIR/$tdir
23352         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23353 }
23354 run_test 421d "rmfid en masse"
23355
23356 test_421e() {
23357         local cnt
23358         local FID
23359
23360         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23361         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23362                 skip "Need MDS version at least 2.12.54"
23363
23364         mkdir -p $DIR/$tdir
23365         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23366         createmany -o $DIR/$tdir/striped_dir/f 512
23367         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23368         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23369
23370         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23371                 sed "s/[/][^:]*://g")
23372         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23373
23374         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23375         rm -rf $DIR/$tdir
23376         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23377 }
23378 run_test 421e "rmfid in DNE"
23379
23380 test_421f() {
23381         local cnt
23382         local FID
23383
23384         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23385                 skip "Need MDS version at least 2.12.54"
23386
23387         test_mkdir $DIR/$tdir
23388         touch $DIR/$tdir/f
23389         cnt=$(ls -1 $DIR/$tdir | wc -l)
23390         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23391
23392         FID=$(lfs path2fid $DIR/$tdir/f)
23393         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23394         # rmfid should fail
23395         cnt=$(ls -1 $DIR/$tdir | wc -l)
23396         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23397
23398         chmod a+rw $DIR/$tdir
23399         ls -la $DIR/$tdir
23400         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23401         # rmfid should fail
23402         cnt=$(ls -1 $DIR/$tdir | wc -l)
23403         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23404
23405         rm -f $DIR/$tdir/f
23406         $RUNAS touch $DIR/$tdir/f
23407         FID=$(lfs path2fid $DIR/$tdir/f)
23408         echo "rmfid as root"
23409         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23410         cnt=$(ls -1 $DIR/$tdir | wc -l)
23411         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23412
23413         rm -f $DIR/$tdir/f
23414         $RUNAS touch $DIR/$tdir/f
23415         cnt=$(ls -1 $DIR/$tdir | wc -l)
23416         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23417         FID=$(lfs path2fid $DIR/$tdir/f)
23418         # rmfid w/o user_fid2path mount option should fail
23419         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23420         cnt=$(ls -1 $DIR/$tdir | wc -l)
23421         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23422
23423         umount_client $MOUNT || error "failed to umount client"
23424         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23425                 error "failed to mount client'"
23426
23427         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23428         # rmfid should succeed
23429         cnt=$(ls -1 $DIR/$tdir | wc -l)
23430         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23431
23432         # rmfid shouldn't allow to remove files due to dir's permission
23433         chmod a+rwx $DIR/$tdir
23434         touch $DIR/$tdir/f
23435         ls -la $DIR/$tdir
23436         FID=$(lfs path2fid $DIR/$tdir/f)
23437         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23438
23439         umount_client $MOUNT || error "failed to umount client"
23440         mount_client $MOUNT "$MOUNT_OPTS" ||
23441                 error "failed to mount client'"
23442
23443 }
23444 run_test 421f "rmfid checks permissions"
23445
23446 test_421g() {
23447         local cnt
23448         local FIDS
23449
23450         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23451         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23452                 skip "Need MDS version at least 2.12.54"
23453
23454         mkdir -p $DIR/$tdir
23455         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23456         createmany -o $DIR/$tdir/striped_dir/f 512
23457         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23458         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23459
23460         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23461                 sed "s/[/][^:]*://g")
23462
23463         rm -f $DIR/$tdir/striped_dir/f1*
23464         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23465         removed=$((512 - cnt))
23466
23467         # few files have been just removed, so we expect
23468         # rmfid to fail on their fids
23469         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23470         [ $removed != $errors ] && error "$errors != $removed"
23471
23472         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23473         rm -rf $DIR/$tdir
23474         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23475 }
23476 run_test 421g "rmfid to return errors properly"
23477
23478 test_422() {
23479         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23480         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23481         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23482         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23483         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23484
23485         local amc=$(at_max_get client)
23486         local amo=$(at_max_get mds1)
23487         local timeout=`lctl get_param -n timeout`
23488
23489         at_max_set 0 client
23490         at_max_set 0 mds1
23491
23492 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23493         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23494                         fail_val=$(((2*timeout + 10)*1000))
23495         touch $DIR/$tdir/d3/file &
23496         sleep 2
23497 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23498         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23499                         fail_val=$((2*timeout + 5))
23500         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23501         local pid=$!
23502         sleep 1
23503         kill -9 $pid
23504         sleep $((2 * timeout))
23505         echo kill $pid
23506         kill -9 $pid
23507         lctl mark touch
23508         touch $DIR/$tdir/d2/file3
23509         touch $DIR/$tdir/d2/file4
23510         touch $DIR/$tdir/d2/file5
23511
23512         wait
23513         at_max_set $amc client
23514         at_max_set $amo mds1
23515
23516         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23517         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23518                 error "Watchdog is always throttled"
23519 }
23520 run_test 422 "kill a process with RPC in progress"
23521
23522 stat_test() {
23523     df -h $MOUNT &
23524     df -h $MOUNT &
23525     df -h $MOUNT &
23526     df -h $MOUNT &
23527     df -h $MOUNT &
23528     df -h $MOUNT &
23529 }
23530
23531 test_423() {
23532     local _stats
23533     # ensure statfs cache is expired
23534     sleep 2;
23535
23536     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23537     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23538
23539     return 0
23540 }
23541 run_test 423 "statfs should return a right data"
23542
23543 test_424() {
23544 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23545         $LCTL set_param fail_loc=0x80000522
23546         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23547         rm -f $DIR/$tfile
23548 }
23549 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23550
23551 test_425() {
23552         test_mkdir -c -1 $DIR/$tdir
23553         $LFS setstripe -c -1 $DIR/$tdir
23554
23555         lru_resize_disable "" 100
23556         stack_trap "lru_resize_enable" EXIT
23557
23558         sleep 5
23559
23560         for i in $(seq $((MDSCOUNT * 125))); do
23561                 local t=$DIR/$tdir/$tfile_$i
23562
23563                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23564                         error_noexit "Create file $t"
23565         done
23566         stack_trap "rm -rf $DIR/$tdir" EXIT
23567
23568         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23569                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23570                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23571
23572                 [ $lock_count -le $lru_size ] ||
23573                         error "osc lock count $lock_count > lru size $lru_size"
23574         done
23575
23576         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23577                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23578                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23579
23580                 [ $lock_count -le $lru_size ] ||
23581                         error "mdc lock count $lock_count > lru size $lru_size"
23582         done
23583 }
23584 run_test 425 "lock count should not exceed lru size"
23585
23586 test_426() {
23587         splice-test -r $DIR/$tfile
23588         splice-test -rd $DIR/$tfile
23589         splice-test $DIR/$tfile
23590         splice-test -d $DIR/$tfile
23591 }
23592 run_test 426 "splice test on Lustre"
23593
23594 prep_801() {
23595         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23596         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23597                 skip "Need server version at least 2.9.55"
23598
23599         start_full_debug_logging
23600 }
23601
23602 post_801() {
23603         stop_full_debug_logging
23604 }
23605
23606 barrier_stat() {
23607         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23608                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23609                            awk '/The barrier for/ { print $7 }')
23610                 echo $st
23611         else
23612                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23613                 echo \'$st\'
23614         fi
23615 }
23616
23617 barrier_expired() {
23618         local expired
23619
23620         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23621                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23622                           awk '/will be expired/ { print $7 }')
23623         else
23624                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23625         fi
23626
23627         echo $expired
23628 }
23629
23630 test_801a() {
23631         prep_801
23632
23633         echo "Start barrier_freeze at: $(date)"
23634         #define OBD_FAIL_BARRIER_DELAY          0x2202
23635         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23636         # Do not reduce barrier time - See LU-11873
23637         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23638
23639         sleep 2
23640         local b_status=$(barrier_stat)
23641         echo "Got barrier status at: $(date)"
23642         [ "$b_status" = "'freezing_p1'" ] ||
23643                 error "(1) unexpected barrier status $b_status"
23644
23645         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23646         wait
23647         b_status=$(barrier_stat)
23648         [ "$b_status" = "'frozen'" ] ||
23649                 error "(2) unexpected barrier status $b_status"
23650
23651         local expired=$(barrier_expired)
23652         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23653         sleep $((expired + 3))
23654
23655         b_status=$(barrier_stat)
23656         [ "$b_status" = "'expired'" ] ||
23657                 error "(3) unexpected barrier status $b_status"
23658
23659         # Do not reduce barrier time - See LU-11873
23660         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23661                 error "(4) fail to freeze barrier"
23662
23663         b_status=$(barrier_stat)
23664         [ "$b_status" = "'frozen'" ] ||
23665                 error "(5) unexpected barrier status $b_status"
23666
23667         echo "Start barrier_thaw at: $(date)"
23668         #define OBD_FAIL_BARRIER_DELAY          0x2202
23669         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23670         do_facet mgs $LCTL barrier_thaw $FSNAME &
23671
23672         sleep 2
23673         b_status=$(barrier_stat)
23674         echo "Got barrier status at: $(date)"
23675         [ "$b_status" = "'thawing'" ] ||
23676                 error "(6) unexpected barrier status $b_status"
23677
23678         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23679         wait
23680         b_status=$(barrier_stat)
23681         [ "$b_status" = "'thawed'" ] ||
23682                 error "(7) unexpected barrier status $b_status"
23683
23684         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23685         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23686         do_facet mgs $LCTL barrier_freeze $FSNAME
23687
23688         b_status=$(barrier_stat)
23689         [ "$b_status" = "'failed'" ] ||
23690                 error "(8) unexpected barrier status $b_status"
23691
23692         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23693         do_facet mgs $LCTL barrier_thaw $FSNAME
23694
23695         post_801
23696 }
23697 run_test 801a "write barrier user interfaces and stat machine"
23698
23699 test_801b() {
23700         prep_801
23701
23702         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23703         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23704         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23705         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23706         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23707
23708         cancel_lru_locks mdc
23709
23710         # 180 seconds should be long enough
23711         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23712
23713         local b_status=$(barrier_stat)
23714         [ "$b_status" = "'frozen'" ] ||
23715                 error "(6) unexpected barrier status $b_status"
23716
23717         mkdir $DIR/$tdir/d0/d10 &
23718         mkdir_pid=$!
23719
23720         touch $DIR/$tdir/d1/f13 &
23721         touch_pid=$!
23722
23723         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23724         ln_pid=$!
23725
23726         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23727         mv_pid=$!
23728
23729         rm -f $DIR/$tdir/d4/f12 &
23730         rm_pid=$!
23731
23732         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23733
23734         # To guarantee taht the 'stat' is not blocked
23735         b_status=$(barrier_stat)
23736         [ "$b_status" = "'frozen'" ] ||
23737                 error "(8) unexpected barrier status $b_status"
23738
23739         # let above commands to run at background
23740         sleep 5
23741
23742         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23743         ps -p $touch_pid || error "(10) touch should be blocked"
23744         ps -p $ln_pid || error "(11) link should be blocked"
23745         ps -p $mv_pid || error "(12) rename should be blocked"
23746         ps -p $rm_pid || error "(13) unlink should be blocked"
23747
23748         b_status=$(barrier_stat)
23749         [ "$b_status" = "'frozen'" ] ||
23750                 error "(14) unexpected barrier status $b_status"
23751
23752         do_facet mgs $LCTL barrier_thaw $FSNAME
23753         b_status=$(barrier_stat)
23754         [ "$b_status" = "'thawed'" ] ||
23755                 error "(15) unexpected barrier status $b_status"
23756
23757         wait $mkdir_pid || error "(16) mkdir should succeed"
23758         wait $touch_pid || error "(17) touch should succeed"
23759         wait $ln_pid || error "(18) link should succeed"
23760         wait $mv_pid || error "(19) rename should succeed"
23761         wait $rm_pid || error "(20) unlink should succeed"
23762
23763         post_801
23764 }
23765 run_test 801b "modification will be blocked by write barrier"
23766
23767 test_801c() {
23768         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23769
23770         prep_801
23771
23772         stop mds2 || error "(1) Fail to stop mds2"
23773
23774         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23775
23776         local b_status=$(barrier_stat)
23777         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23778                 do_facet mgs $LCTL barrier_thaw $FSNAME
23779                 error "(2) unexpected barrier status $b_status"
23780         }
23781
23782         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23783                 error "(3) Fail to rescan barrier bitmap"
23784
23785         # Do not reduce barrier time - See LU-11873
23786         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23787
23788         b_status=$(barrier_stat)
23789         [ "$b_status" = "'frozen'" ] ||
23790                 error "(4) unexpected barrier status $b_status"
23791
23792         do_facet mgs $LCTL barrier_thaw $FSNAME
23793         b_status=$(barrier_stat)
23794         [ "$b_status" = "'thawed'" ] ||
23795                 error "(5) unexpected barrier status $b_status"
23796
23797         local devname=$(mdsdevname 2)
23798
23799         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23800
23801         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23802                 error "(7) Fail to rescan barrier bitmap"
23803
23804         post_801
23805 }
23806 run_test 801c "rescan barrier bitmap"
23807
23808 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23809 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23810 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23811 saved_MOUNT_OPTS=$MOUNT_OPTS
23812
23813 cleanup_802a() {
23814         trap 0
23815
23816         stopall
23817         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23818         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23819         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23820         MOUNT_OPTS=$saved_MOUNT_OPTS
23821         setupall
23822 }
23823
23824 test_802a() {
23825         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23826         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23827         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23828                 skip "Need server version at least 2.9.55"
23829
23830         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23831
23832         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23833
23834         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23835                 error "(2) Fail to copy"
23836
23837         trap cleanup_802a EXIT
23838
23839         # sync by force before remount as readonly
23840         sync; sync_all_data; sleep 3; sync_all_data
23841
23842         stopall
23843
23844         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23845         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23846         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23847
23848         echo "Mount the server as read only"
23849         setupall server_only || error "(3) Fail to start servers"
23850
23851         echo "Mount client without ro should fail"
23852         mount_client $MOUNT &&
23853                 error "(4) Mount client without 'ro' should fail"
23854
23855         echo "Mount client with ro should succeed"
23856         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23857         mount_client $MOUNT ||
23858                 error "(5) Mount client with 'ro' should succeed"
23859
23860         echo "Modify should be refused"
23861         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23862
23863         echo "Read should be allowed"
23864         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23865                 error "(7) Read should succeed under ro mode"
23866
23867         cleanup_802a
23868 }
23869 run_test 802a "simulate readonly device"
23870
23871 test_802b() {
23872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23873         remote_mds_nodsh && skip "remote MDS with nodsh"
23874
23875         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23876                 skip "readonly option not available"
23877
23878         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23879
23880         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23881                 error "(2) Fail to copy"
23882
23883         # write back all cached data before setting MDT to readonly
23884         cancel_lru_locks
23885         sync_all_data
23886
23887         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23888         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23889
23890         echo "Modify should be refused"
23891         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23892
23893         echo "Read should be allowed"
23894         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23895                 error "(7) Read should succeed under ro mode"
23896
23897         # disable readonly
23898         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23899 }
23900 run_test 802b "be able to set MDTs to readonly"
23901
23902 test_803a() {
23903         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23904         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23905                 skip "MDS needs to be newer than 2.10.54"
23906
23907         mkdir -p $DIR/$tdir
23908         # Create some objects on all MDTs to trigger related logs objects
23909         for idx in $(seq $MDSCOUNT); do
23910                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23911                         $DIR/$tdir/dir${idx} ||
23912                         error "Fail to create $DIR/$tdir/dir${idx}"
23913         done
23914
23915         sync; sleep 3
23916         wait_delete_completed # ensure old test cleanups are finished
23917         echo "before create:"
23918         $LFS df -i $MOUNT
23919         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23920
23921         for i in {1..10}; do
23922                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23923                         error "Fail to create $DIR/$tdir/foo$i"
23924         done
23925
23926         sync; sleep 3
23927         echo "after create:"
23928         $LFS df -i $MOUNT
23929         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23930
23931         # allow for an llog to be cleaned up during the test
23932         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23933                 error "before ($before_used) + 10 > after ($after_used)"
23934
23935         for i in {1..10}; do
23936                 rm -rf $DIR/$tdir/foo$i ||
23937                         error "Fail to remove $DIR/$tdir/foo$i"
23938         done
23939
23940         sleep 3 # avoid MDT return cached statfs
23941         wait_delete_completed
23942         echo "after unlink:"
23943         $LFS df -i $MOUNT
23944         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23945
23946         # allow for an llog to be created during the test
23947         [ $after_used -le $((before_used + 1)) ] ||
23948                 error "after ($after_used) > before ($before_used) + 1"
23949 }
23950 run_test 803a "verify agent object for remote object"
23951
23952 test_803b() {
23953         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23954         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
23955                 skip "MDS needs to be newer than 2.13.56"
23956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23957
23958         for i in $(seq 0 $((MDSCOUNT - 1))); do
23959                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
23960         done
23961
23962         local before=0
23963         local after=0
23964
23965         local tmp
23966
23967         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
23968         for i in $(seq 0 $((MDSCOUNT - 1))); do
23969                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
23970                         awk '/getattr/ { print $2 }')
23971                 before=$((before + tmp))
23972         done
23973         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
23974         for i in $(seq 0 $((MDSCOUNT - 1))); do
23975                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
23976                         awk '/getattr/ { print $2 }')
23977                 after=$((after + tmp))
23978         done
23979
23980         [ $before -eq $after ] || error "getattr count $before != $after"
23981 }
23982 run_test 803b "remote object can getattr from cache"
23983
23984 test_804() {
23985         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23986         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23987                 skip "MDS needs to be newer than 2.10.54"
23988         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23989
23990         mkdir -p $DIR/$tdir
23991         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23992                 error "Fail to create $DIR/$tdir/dir0"
23993
23994         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23995         local dev=$(mdsdevname 2)
23996
23997         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23998                 grep ${fid} || error "NOT found agent entry for dir0"
23999
24000         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24001                 error "Fail to create $DIR/$tdir/dir1"
24002
24003         touch $DIR/$tdir/dir1/foo0 ||
24004                 error "Fail to create $DIR/$tdir/dir1/foo0"
24005         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24006         local rc=0
24007
24008         for idx in $(seq $MDSCOUNT); do
24009                 dev=$(mdsdevname $idx)
24010                 do_facet mds${idx} \
24011                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24012                         grep ${fid} && rc=$idx
24013         done
24014
24015         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24016                 error "Fail to rename foo0 to foo1"
24017         if [ $rc -eq 0 ]; then
24018                 for idx in $(seq $MDSCOUNT); do
24019                         dev=$(mdsdevname $idx)
24020                         do_facet mds${idx} \
24021                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24022                         grep ${fid} && rc=$idx
24023                 done
24024         fi
24025
24026         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24027                 error "Fail to rename foo1 to foo2"
24028         if [ $rc -eq 0 ]; then
24029                 for idx in $(seq $MDSCOUNT); do
24030                         dev=$(mdsdevname $idx)
24031                         do_facet mds${idx} \
24032                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24033                         grep ${fid} && rc=$idx
24034                 done
24035         fi
24036
24037         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24038
24039         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24040                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24041         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24042                 error "Fail to rename foo2 to foo0"
24043         unlink $DIR/$tdir/dir1/foo0 ||
24044                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24045         rm -rf $DIR/$tdir/dir0 ||
24046                 error "Fail to rm $DIR/$tdir/dir0"
24047
24048         for idx in $(seq $MDSCOUNT); do
24049                 dev=$(mdsdevname $idx)
24050                 rc=0
24051
24052                 stop mds${idx}
24053                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24054                         rc=$?
24055                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24056                         error "mount mds$idx failed"
24057                 df $MOUNT > /dev/null 2>&1
24058
24059                 # e2fsck should not return error
24060                 [ $rc -eq 0 ] ||
24061                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24062         done
24063 }
24064 run_test 804 "verify agent entry for remote entry"
24065
24066 cleanup_805() {
24067         do_facet $SINGLEMDS zfs set quota=$old $fsset
24068         unlinkmany $DIR/$tdir/f- 1000000
24069         trap 0
24070 }
24071
24072 test_805() {
24073         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24074         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24075         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24076                 skip "netfree not implemented before 0.7"
24077         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24078                 skip "Need MDS version at least 2.10.57"
24079
24080         local fsset
24081         local freekb
24082         local usedkb
24083         local old
24084         local quota
24085         local pref="osd-zfs.$FSNAME-MDT0000."
24086
24087         # limit available space on MDS dataset to meet nospace issue
24088         # quickly. then ZFS 0.7.2 can use reserved space if asked
24089         # properly (using netfree flag in osd_declare_destroy()
24090         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24091         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24092                 gawk '{print $3}')
24093         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24094         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24095         let "usedkb=usedkb-freekb"
24096         let "freekb=freekb/2"
24097         if let "freekb > 5000"; then
24098                 let "freekb=5000"
24099         fi
24100         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24101         trap cleanup_805 EXIT
24102         mkdir $DIR/$tdir
24103         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24104                 error "Can't set PFL layout"
24105         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24106         rm -rf $DIR/$tdir || error "not able to remove"
24107         do_facet $SINGLEMDS zfs set quota=$old $fsset
24108         trap 0
24109 }
24110 run_test 805 "ZFS can remove from full fs"
24111
24112 # Size-on-MDS test
24113 check_lsom_data()
24114 {
24115         local file=$1
24116         local size=$($LFS getsom -s $file)
24117         local expect=$(stat -c %s $file)
24118
24119         [[ $size == $expect ]] ||
24120                 error "$file expected size: $expect, got: $size"
24121
24122         local blocks=$($LFS getsom -b $file)
24123         expect=$(stat -c %b $file)
24124         [[ $blocks == $expect ]] ||
24125                 error "$file expected blocks: $expect, got: $blocks"
24126 }
24127
24128 check_lsom_size()
24129 {
24130         local size=$($LFS getsom -s $1)
24131         local expect=$2
24132
24133         [[ $size == $expect ]] ||
24134                 error "$file expected size: $expect, got: $size"
24135 }
24136
24137 test_806() {
24138         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24139                 skip "Need MDS version at least 2.11.52"
24140
24141         local bs=1048576
24142
24143         touch $DIR/$tfile || error "touch $tfile failed"
24144
24145         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24146         save_lustre_params client "llite.*.xattr_cache" > $save
24147         lctl set_param llite.*.xattr_cache=0
24148         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24149
24150         # single-threaded write
24151         echo "Test SOM for single-threaded write"
24152         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24153                 error "write $tfile failed"
24154         check_lsom_size $DIR/$tfile $bs
24155
24156         local num=32
24157         local size=$(($num * $bs))
24158         local offset=0
24159         local i
24160
24161         echo "Test SOM for single client multi-threaded($num) write"
24162         $TRUNCATE $DIR/$tfile 0
24163         for ((i = 0; i < $num; i++)); do
24164                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24165                 local pids[$i]=$!
24166                 offset=$((offset + $bs))
24167         done
24168         for (( i=0; i < $num; i++ )); do
24169                 wait ${pids[$i]}
24170         done
24171         check_lsom_size $DIR/$tfile $size
24172
24173         $TRUNCATE $DIR/$tfile 0
24174         for ((i = 0; i < $num; i++)); do
24175                 offset=$((offset - $bs))
24176                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24177                 local pids[$i]=$!
24178         done
24179         for (( i=0; i < $num; i++ )); do
24180                 wait ${pids[$i]}
24181         done
24182         check_lsom_size $DIR/$tfile $size
24183
24184         # multi-client writes
24185         num=$(get_node_count ${CLIENTS//,/ })
24186         size=$(($num * $bs))
24187         offset=0
24188         i=0
24189
24190         echo "Test SOM for multi-client ($num) writes"
24191         $TRUNCATE $DIR/$tfile 0
24192         for client in ${CLIENTS//,/ }; do
24193                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24194                 local pids[$i]=$!
24195                 i=$((i + 1))
24196                 offset=$((offset + $bs))
24197         done
24198         for (( i=0; i < $num; i++ )); do
24199                 wait ${pids[$i]}
24200         done
24201         check_lsom_size $DIR/$tfile $offset
24202
24203         i=0
24204         $TRUNCATE $DIR/$tfile 0
24205         for client in ${CLIENTS//,/ }; do
24206                 offset=$((offset - $bs))
24207                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24208                 local pids[$i]=$!
24209                 i=$((i + 1))
24210         done
24211         for (( i=0; i < $num; i++ )); do
24212                 wait ${pids[$i]}
24213         done
24214         check_lsom_size $DIR/$tfile $size
24215
24216         # verify truncate
24217         echo "Test SOM for truncate"
24218         $TRUNCATE $DIR/$tfile 1048576
24219         check_lsom_size $DIR/$tfile 1048576
24220         $TRUNCATE $DIR/$tfile 1234
24221         check_lsom_size $DIR/$tfile 1234
24222
24223         # verify SOM blocks count
24224         echo "Verify SOM block count"
24225         $TRUNCATE $DIR/$tfile 0
24226         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24227                 error "failed to write file $tfile"
24228         check_lsom_data $DIR/$tfile
24229 }
24230 run_test 806 "Verify Lazy Size on MDS"
24231
24232 test_807() {
24233         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24234         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24235                 skip "Need MDS version at least 2.11.52"
24236
24237         # Registration step
24238         changelog_register || error "changelog_register failed"
24239         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24240         changelog_users $SINGLEMDS | grep -q $cl_user ||
24241                 error "User $cl_user not found in changelog_users"
24242
24243         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24244         save_lustre_params client "llite.*.xattr_cache" > $save
24245         lctl set_param llite.*.xattr_cache=0
24246         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24247
24248         rm -rf $DIR/$tdir || error "rm $tdir failed"
24249         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24250         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24251         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24252         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24253                 error "truncate $tdir/trunc failed"
24254
24255         local bs=1048576
24256         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24257                 error "write $tfile failed"
24258
24259         # multi-client wirtes
24260         local num=$(get_node_count ${CLIENTS//,/ })
24261         local offset=0
24262         local i=0
24263
24264         echo "Test SOM for multi-client ($num) writes"
24265         touch $DIR/$tfile || error "touch $tfile failed"
24266         $TRUNCATE $DIR/$tfile 0
24267         for client in ${CLIENTS//,/ }; do
24268                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24269                 local pids[$i]=$!
24270                 i=$((i + 1))
24271                 offset=$((offset + $bs))
24272         done
24273         for (( i=0; i < $num; i++ )); do
24274                 wait ${pids[$i]}
24275         done
24276
24277         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24278         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24279         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24280         check_lsom_data $DIR/$tdir/trunc
24281         check_lsom_data $DIR/$tdir/single_dd
24282         check_lsom_data $DIR/$tfile
24283
24284         rm -rf $DIR/$tdir
24285         # Deregistration step
24286         changelog_deregister || error "changelog_deregister failed"
24287 }
24288 run_test 807 "verify LSOM syncing tool"
24289
24290 check_som_nologged()
24291 {
24292         local lines=$($LFS changelog $FSNAME-MDT0000 |
24293                 grep 'x=trusted.som' | wc -l)
24294         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24295 }
24296
24297 test_808() {
24298         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24299                 skip "Need MDS version at least 2.11.55"
24300
24301         # Registration step
24302         changelog_register || error "changelog_register failed"
24303
24304         touch $DIR/$tfile || error "touch $tfile failed"
24305         check_som_nologged
24306
24307         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24308                 error "write $tfile failed"
24309         check_som_nologged
24310
24311         $TRUNCATE $DIR/$tfile 1234
24312         check_som_nologged
24313
24314         $TRUNCATE $DIR/$tfile 1048576
24315         check_som_nologged
24316
24317         # Deregistration step
24318         changelog_deregister || error "changelog_deregister failed"
24319 }
24320 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24321
24322 check_som_nodata()
24323 {
24324         $LFS getsom $1
24325         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24326 }
24327
24328 test_809() {
24329         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24330                 skip "Need MDS version at least 2.11.56"
24331
24332         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24333                 error "failed to create DoM-only file $DIR/$tfile"
24334         touch $DIR/$tfile || error "touch $tfile failed"
24335         check_som_nodata $DIR/$tfile
24336
24337         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24338                 error "write $tfile failed"
24339         check_som_nodata $DIR/$tfile
24340
24341         $TRUNCATE $DIR/$tfile 1234
24342         check_som_nodata $DIR/$tfile
24343
24344         $TRUNCATE $DIR/$tfile 4097
24345         check_som_nodata $DIR/$file
24346 }
24347 run_test 809 "Verify no SOM xattr store for DoM-only files"
24348
24349 test_810() {
24350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24351         $GSS && skip_env "could not run with gss"
24352         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24353                 skip "OST < 2.12.58 doesn't align checksum"
24354
24355         set_checksums 1
24356         stack_trap "set_checksums $ORIG_CSUM" EXIT
24357         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24358
24359         local csum
24360         local before
24361         local after
24362         for csum in $CKSUM_TYPES; do
24363                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24364                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24365                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24366                         eval set -- $i
24367                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24368                         before=$(md5sum $DIR/$tfile)
24369                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24370                         after=$(md5sum $DIR/$tfile)
24371                         [ "$before" == "$after" ] ||
24372                                 error "$csum: $before != $after bs=$1 seek=$2"
24373                 done
24374         done
24375 }
24376 run_test 810 "partial page writes on ZFS (LU-11663)"
24377
24378 test_812a() {
24379         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24380                 skip "OST < 2.12.51 doesn't support this fail_loc"
24381
24382         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24383         # ensure ost1 is connected
24384         stat $DIR/$tfile >/dev/null || error "can't stat"
24385         wait_osc_import_state client ost1 FULL
24386         # no locks, no reqs to let the connection idle
24387         cancel_lru_locks osc
24388
24389         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24390 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24391         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24392         wait_osc_import_state client ost1 CONNECTING
24393         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24394
24395         stat $DIR/$tfile >/dev/null || error "can't stat file"
24396 }
24397 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24398
24399 test_812b() { # LU-12378
24400         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24401                 skip "OST < 2.12.51 doesn't support this fail_loc"
24402
24403         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24404         # ensure ost1 is connected
24405         stat $DIR/$tfile >/dev/null || error "can't stat"
24406         wait_osc_import_state client ost1 FULL
24407         # no locks, no reqs to let the connection idle
24408         cancel_lru_locks osc
24409
24410         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24411 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24412         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24413         wait_osc_import_state client ost1 CONNECTING
24414         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24415
24416         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24417         wait_osc_import_state client ost1 IDLE
24418 }
24419 run_test 812b "do not drop no resend request for idle connect"
24420
24421 test_813() {
24422         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24423         [ -z "$file_heat_sav" ] && skip "no file heat support"
24424
24425         local readsample
24426         local writesample
24427         local readbyte
24428         local writebyte
24429         local readsample1
24430         local writesample1
24431         local readbyte1
24432         local writebyte1
24433
24434         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24435         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24436
24437         $LCTL set_param -n llite.*.file_heat=1
24438         echo "Turn on file heat"
24439         echo "Period second: $period_second, Decay percentage: $decay_pct"
24440
24441         echo "QQQQ" > $DIR/$tfile
24442         echo "QQQQ" > $DIR/$tfile
24443         echo "QQQQ" > $DIR/$tfile
24444         cat $DIR/$tfile > /dev/null
24445         cat $DIR/$tfile > /dev/null
24446         cat $DIR/$tfile > /dev/null
24447         cat $DIR/$tfile > /dev/null
24448
24449         local out=$($LFS heat_get $DIR/$tfile)
24450
24451         $LFS heat_get $DIR/$tfile
24452         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24453         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24454         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24455         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24456
24457         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24458         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24459         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24460         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24461
24462         sleep $((period_second + 3))
24463         echo "Sleep $((period_second + 3)) seconds..."
24464         # The recursion formula to calculate the heat of the file f is as
24465         # follow:
24466         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24467         # Where Hi is the heat value in the period between time points i*I and
24468         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24469         # to the weight of Ci.
24470         out=$($LFS heat_get $DIR/$tfile)
24471         $LFS heat_get $DIR/$tfile
24472         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24473         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24474         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24475         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24476
24477         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24478                 error "read sample ($readsample) is wrong"
24479         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24480                 error "write sample ($writesample) is wrong"
24481         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24482                 error "read bytes ($readbyte) is wrong"
24483         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24484                 error "write bytes ($writebyte) is wrong"
24485
24486         echo "QQQQ" > $DIR/$tfile
24487         echo "QQQQ" > $DIR/$tfile
24488         echo "QQQQ" > $DIR/$tfile
24489         cat $DIR/$tfile > /dev/null
24490         cat $DIR/$tfile > /dev/null
24491         cat $DIR/$tfile > /dev/null
24492         cat $DIR/$tfile > /dev/null
24493
24494         sleep $((period_second + 3))
24495         echo "Sleep $((period_second + 3)) seconds..."
24496
24497         out=$($LFS heat_get $DIR/$tfile)
24498         $LFS heat_get $DIR/$tfile
24499         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24500         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24501         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24502         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24503
24504         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24505                 4 * $decay_pct) / 100") -eq 1 ] ||
24506                 error "read sample ($readsample1) is wrong"
24507         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24508                 3 * $decay_pct) / 100") -eq 1 ] ||
24509                 error "write sample ($writesample1) is wrong"
24510         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24511                 20 * $decay_pct) / 100") -eq 1 ] ||
24512                 error "read bytes ($readbyte1) is wrong"
24513         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24514                 15 * $decay_pct) / 100") -eq 1 ] ||
24515                 error "write bytes ($writebyte1) is wrong"
24516
24517         echo "Turn off file heat for the file $DIR/$tfile"
24518         $LFS heat_set -o $DIR/$tfile
24519
24520         echo "QQQQ" > $DIR/$tfile
24521         echo "QQQQ" > $DIR/$tfile
24522         echo "QQQQ" > $DIR/$tfile
24523         cat $DIR/$tfile > /dev/null
24524         cat $DIR/$tfile > /dev/null
24525         cat $DIR/$tfile > /dev/null
24526         cat $DIR/$tfile > /dev/null
24527
24528         out=$($LFS heat_get $DIR/$tfile)
24529         $LFS heat_get $DIR/$tfile
24530         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24531         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24532         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24533         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24534
24535         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24536         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24537         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24538         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24539
24540         echo "Trun on file heat for the file $DIR/$tfile"
24541         $LFS heat_set -O $DIR/$tfile
24542
24543         echo "QQQQ" > $DIR/$tfile
24544         echo "QQQQ" > $DIR/$tfile
24545         echo "QQQQ" > $DIR/$tfile
24546         cat $DIR/$tfile > /dev/null
24547         cat $DIR/$tfile > /dev/null
24548         cat $DIR/$tfile > /dev/null
24549         cat $DIR/$tfile > /dev/null
24550
24551         out=$($LFS heat_get $DIR/$tfile)
24552         $LFS heat_get $DIR/$tfile
24553         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24554         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24555         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24556         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24557
24558         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24559         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24560         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24561         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24562
24563         $LFS heat_set -c $DIR/$tfile
24564         $LCTL set_param -n llite.*.file_heat=0
24565         echo "Turn off file heat support for the Lustre filesystem"
24566
24567         echo "QQQQ" > $DIR/$tfile
24568         echo "QQQQ" > $DIR/$tfile
24569         echo "QQQQ" > $DIR/$tfile
24570         cat $DIR/$tfile > /dev/null
24571         cat $DIR/$tfile > /dev/null
24572         cat $DIR/$tfile > /dev/null
24573         cat $DIR/$tfile > /dev/null
24574
24575         out=$($LFS heat_get $DIR/$tfile)
24576         $LFS heat_get $DIR/$tfile
24577         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24578         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24579         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24580         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24581
24582         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24583         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24584         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24585         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24586
24587         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24588         rm -f $DIR/$tfile
24589 }
24590 run_test 813 "File heat verfication"
24591
24592 test_814()
24593 {
24594         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24595         echo -n y >> $DIR/$tfile
24596         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24597         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24598 }
24599 run_test 814 "sparse cp works as expected (LU-12361)"
24600
24601 test_815()
24602 {
24603         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24604         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24605 }
24606 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24607
24608 test_816() {
24609         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24610         # ensure ost1 is connected
24611         stat $DIR/$tfile >/dev/null || error "can't stat"
24612         wait_osc_import_state client ost1 FULL
24613         # no locks, no reqs to let the connection idle
24614         cancel_lru_locks osc
24615         lru_resize_disable osc
24616         local before
24617         local now
24618         before=$($LCTL get_param -n \
24619                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24620
24621         wait_osc_import_state client ost1 IDLE
24622         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24623         now=$($LCTL get_param -n \
24624               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24625         [ $before == $now ] || error "lru_size changed $before != $now"
24626 }
24627 run_test 816 "do not reset lru_resize on idle reconnect"
24628
24629 cleanup_817() {
24630         umount $tmpdir
24631         exportfs -u localhost:$DIR/nfsexp
24632         rm -rf $DIR/nfsexp
24633 }
24634
24635 test_817() {
24636         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24637
24638         mkdir -p $DIR/nfsexp
24639         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24640                 error "failed to export nfs"
24641
24642         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24643         stack_trap cleanup_817 EXIT
24644
24645         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24646                 error "failed to mount nfs to $tmpdir"
24647
24648         cp /bin/true $tmpdir
24649         $DIR/nfsexp/true || error "failed to execute 'true' command"
24650 }
24651 run_test 817 "nfsd won't cache write lock for exec file"
24652
24653 test_818() {
24654         mkdir $DIR/$tdir
24655         $LFS setstripe -c1 -i0 $DIR/$tfile
24656         $LFS setstripe -c1 -i1 $DIR/$tfile
24657         stop $SINGLEMDS
24658         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24659         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24660         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24661                 error "start $SINGLEMDS failed"
24662         rm -rf $DIR/$tdir
24663 }
24664 run_test 818 "unlink with failed llog"
24665
24666 test_819a() {
24667         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24668         cancel_lru_locks osc
24669         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24670         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24671         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24672         rm -f $TDIR/$tfile
24673 }
24674 run_test 819a "too big niobuf in read"
24675
24676 test_819b() {
24677         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24678         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24679         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24680         cancel_lru_locks osc
24681         sleep 1
24682         rm -f $TDIR/$tfile
24683 }
24684 run_test 819b "too big niobuf in write"
24685
24686
24687 function test_820_start_ost() {
24688         sleep 5
24689
24690         for num in $(seq $OSTCOUNT); do
24691                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24692         done
24693 }
24694
24695 test_820() {
24696         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24697
24698         mkdir $DIR/$tdir
24699         umount_client $MOUNT || error "umount failed"
24700         for num in $(seq $OSTCOUNT); do
24701                 stop ost$num
24702         done
24703
24704         # mount client with no active OSTs
24705         # so that the client can't initialize max LOV EA size
24706         # from OSC notifications
24707         mount_client $MOUNT || error "mount failed"
24708         # delay OST starting to keep this 0 max EA size for a while
24709         test_820_start_ost &
24710
24711         # create a directory on MDS2
24712         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24713                 error "Failed to create directory"
24714         # open intent should update default EA size
24715         # see mdc_update_max_ea_from_body()
24716         # notice this is the very first RPC to MDS2
24717         cp /etc/services $DIR/$tdir/mds2 ||
24718                 error "Failed to copy files to mds$n"
24719 }
24720 run_test 820 "update max EA from open intent"
24721
24722 #
24723 # tests that do cleanup/setup should be run at the end
24724 #
24725
24726 test_900() {
24727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24728         local ls
24729
24730         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24731         $LCTL set_param fail_loc=0x903
24732
24733         cancel_lru_locks MGC
24734
24735         FAIL_ON_ERROR=true cleanup
24736         FAIL_ON_ERROR=true setup
24737 }
24738 run_test 900 "umount should not race with any mgc requeue thread"
24739
24740 # LUS-6253/LU-11185
24741 test_901() {
24742         local oldc
24743         local newc
24744         local olds
24745         local news
24746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24747
24748         # some get_param have a bug to handle dot in param name
24749         cancel_lru_locks MGC
24750         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24751         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24752         umount_client $MOUNT || error "umount failed"
24753         mount_client $MOUNT || error "mount failed"
24754         cancel_lru_locks MGC
24755         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24756         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24757
24758         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24759         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24760
24761         return 0
24762 }
24763 run_test 901 "don't leak a mgc lock on client umount"
24764
24765 # LU-13377
24766 test_902() {
24767         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24768                 skip "client does not have LU-13377 fix"
24769         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24770         $LCTL set_param fail_loc=0x1415
24771         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24772         cancel_lru_locks osc
24773         rm -f $DIR/$tfile
24774 }
24775 run_test 902 "test short write doesn't hang lustre"
24776
24777 complete $SECONDS
24778 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24779 check_and_cleanup_lustre
24780 if [ "$I_MOUNTED" != "yes" ]; then
24781         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24782 fi
24783 exit_status