Whamcloud - gitweb
d0c70f2b817f6c93e336a31eb6f67b0c22f412ca
[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         sleep 2
5986         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5987         sleep 2
5988         if [ $y == "t" ]; then
5989                 if [ $x == "b" ]; then
5990                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5991                 else
5992                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5993                 fi
5994         else
5995                 negref=$DIR/$tfile.negnewer.$x$y
5996                 touch $negref || error "touch $negref failed"
5997         fi
5998
5999         local cmd="$LFS find $dir -newer$x$y $ref"
6000         local nums=$(eval $cmd | wc -l)
6001         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6002
6003         [ $nums -eq $expected ] ||
6004                 error "'$cmd' wrong: found $nums, expected $expected"
6005
6006         cmd="$LFS find $dir ! -newer$x$y $negref"
6007         nums=$(eval $cmd | wc -l)
6008         [ $nums -eq $expected ] ||
6009                 error "'$cmd' wrong: found $nums, expected $expected"
6010
6011         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6012         nums=$(eval $cmd | wc -l)
6013         [ $nums -eq $expected ] ||
6014                 error "'$cmd' wrong: found $nums, expected $expected"
6015
6016         rm -rf $DIR/*
6017 }
6018
6019 test_56oc() {
6020         test_newerXY_base "b" "t"
6021         test_newerXY_base "a" "a"
6022         test_newerXY_base "a" "m"
6023         test_newerXY_base "a" "c"
6024         test_newerXY_base "m" "a"
6025         test_newerXY_base "m" "m"
6026         test_newerXY_base "m" "c"
6027         test_newerXY_base "c" "a"
6028         test_newerXY_base "c" "m"
6029         test_newerXY_base "c" "c"
6030         test_newerXY_base "b" "b"
6031         test_newerXY_base "a" "t"
6032         test_newerXY_base "m" "t"
6033         test_newerXY_base "c" "t"
6034         test_newerXY_base "b" "t"
6035 }
6036 run_test 56oc "check lfs find -newerXY work"
6037
6038 btime_supported() {
6039         local dir=$DIR/$tdir
6040         local rc
6041
6042         mkdir -p $dir
6043         touch $dir/$tfile
6044         $LFS find $dir -btime -1d -type f
6045         rc=$?
6046         rm -rf $dir
6047         return $rc
6048 }
6049
6050 test_56od() {
6051         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6052                 ! btime_supported && skip "btime unsupported on MDS"
6053
6054         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6055                 ! btime_supported && skip "btime unsupported on clients"
6056
6057         local dir=$DIR/$tdir
6058         local ref=$DIR/$tfile.ref
6059         local negref=$DIR/$tfile.negref
6060
6061         mkdir $dir || error "mkdir $dir failed"
6062         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6063         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6064         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6065         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6066         touch $ref || error "touch $ref failed"
6067         # sleep 3 seconds at least
6068         sleep 3
6069
6070         local before=$(do_facet mds1 date +%s)
6071         local skew=$(($(date +%s) - before + 1))
6072
6073         if (( skew < 0 && skew > -5 )); then
6074                 sleep $((0 - skew + 1))
6075                 skew=0
6076         fi
6077
6078         # Set the dir stripe params to limit files all on MDT0,
6079         # otherwise we need to calc the max clock skew between
6080         # the client and MDTs.
6081         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6082         sleep 2
6083         touch $negref || error "touch $negref failed"
6084
6085         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6086         local nums=$($cmd | wc -l)
6087         local expected=$(((NUMFILES + 1) * NUMDIRS))
6088
6089         [ $nums -eq $expected ] ||
6090                 error "'$cmd' wrong: found $nums, expected $expected"
6091
6092         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6093         nums=$($cmd | wc -l)
6094         expected=$((NUMFILES + 1))
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097
6098         [ $skew -lt 0 ] && return
6099
6100         local after=$(do_facet mds1 date +%s)
6101         local age=$((after - before + 1 + skew))
6102
6103         cmd="$LFS find $dir -btime -${age}s -type f"
6104         nums=$($cmd | wc -l)
6105         expected=$(((NUMFILES + 1) * NUMDIRS))
6106
6107         echo "Clock skew between client and server: $skew, age:$age"
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         expected=$(($NUMDIRS + 1))
6112         cmd="$LFS find $dir -btime -${age}s -type d"
6113         nums=$($cmd | wc -l)
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116         rm -f $ref $negref || error "Failed to remove $ref $negref"
6117 }
6118 run_test 56od "check lfs find -btime with units"
6119
6120 test_56p() {
6121         [ $RUNAS_ID -eq $UID ] &&
6122                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6123
6124         local dir=$DIR/$tdir
6125
6126         setup_56 $dir $NUMFILES $NUMDIRS
6127         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6128
6129         local expected=$NUMFILES
6130         local cmd="$LFS find -uid $RUNAS_ID $dir"
6131         local nums=$($cmd | wc -l)
6132
6133         [ $nums -eq $expected ] ||
6134                 error "'$cmd' wrong: found $nums, expected $expected"
6135
6136         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6137         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6138         nums=$($cmd | wc -l)
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141 }
6142 run_test 56p "check lfs find -uid and ! -uid"
6143
6144 test_56q() {
6145         [ $RUNAS_ID -eq $UID ] &&
6146                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6147
6148         local dir=$DIR/$tdir
6149
6150         setup_56 $dir $NUMFILES $NUMDIRS
6151         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6152
6153         local expected=$NUMFILES
6154         local cmd="$LFS find -gid $RUNAS_GID $dir"
6155         local nums=$($cmd | wc -l)
6156
6157         [ $nums -eq $expected ] ||
6158                 error "'$cmd' wrong: found $nums, expected $expected"
6159
6160         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6161         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6162         nums=$($cmd | wc -l)
6163         [ $nums -eq $expected ] ||
6164                 error "'$cmd' wrong: found $nums, expected $expected"
6165 }
6166 run_test 56q "check lfs find -gid and ! -gid"
6167
6168 test_56r() {
6169         local dir=$DIR/$tdir
6170
6171         setup_56 $dir $NUMFILES $NUMDIRS
6172
6173         local expected=12
6174         local cmd="$LFS find -size 0 -type f -lazy $dir"
6175         local nums=$($cmd | wc -l)
6176
6177         [ $nums -eq $expected ] ||
6178                 error "'$cmd' wrong: found $nums, expected $expected"
6179         cmd="$LFS find -size 0 -type f $dir"
6180         nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183
6184         expected=0
6185         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189         cmd="$LFS find ! -size 0 -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         echo "test" > $dir/$tfile
6195         echo "test2" > $dir/$tfile.2 && sync
6196         expected=1
6197         cmd="$LFS find -size 5 -type f -lazy $dir"
6198         nums=$($cmd | wc -l)
6199         [ $nums -eq $expected ] ||
6200                 error "'$cmd' wrong: found $nums, expected $expected"
6201         cmd="$LFS find -size 5 -type f $dir"
6202         nums=$($cmd | wc -l)
6203         [ $nums -eq $expected ] ||
6204                 error "'$cmd' wrong: found $nums, expected $expected"
6205
6206         expected=1
6207         cmd="$LFS find -size +5 -type f -lazy $dir"
6208         nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211         cmd="$LFS find -size +5 -type f $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] ||
6214                 error "'$cmd' wrong: found $nums, expected $expected"
6215
6216         expected=2
6217         cmd="$LFS find -size +0 -type f -lazy $dir"
6218         nums=$($cmd | wc -l)
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221         cmd="$LFS find -size +0 -type f $dir"
6222         nums=$($cmd | wc -l)
6223         [ $nums -eq $expected ] ||
6224                 error "'$cmd' wrong: found $nums, expected $expected"
6225
6226         expected=2
6227         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231         cmd="$LFS find ! -size -5 -type f $dir"
6232         nums=$($cmd | wc -l)
6233         [ $nums -eq $expected ] ||
6234                 error "'$cmd' wrong: found $nums, expected $expected"
6235
6236         expected=12
6237         cmd="$LFS find -size -5 -type f -lazy $dir"
6238         nums=$($cmd | wc -l)
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241         cmd="$LFS find -size -5 -type f $dir"
6242         nums=$($cmd | wc -l)
6243         [ $nums -eq $expected ] ||
6244                 error "'$cmd' wrong: found $nums, expected $expected"
6245 }
6246 run_test 56r "check lfs find -size works"
6247
6248 test_56ra_sub() {
6249         local expected=$1
6250         local glimpses=$2
6251         local cmd="$3"
6252
6253         cancel_lru_locks $OSC
6254
6255         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6256         local nums=$($cmd | wc -l)
6257
6258         [ $nums -eq $expected ] ||
6259                 error "'$cmd' wrong: found $nums, expected $expected"
6260
6261         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6262
6263         if (( rpcs_before + glimpses != rpcs_after )); then
6264                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6265                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6266
6267                 if [[ $glimpses == 0 ]]; then
6268                         error "'$cmd' should not send glimpse RPCs to OST"
6269                 else
6270                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6271                 fi
6272         fi
6273 }
6274
6275 test_56ra() {
6276         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6277                 skip "MDS < 2.12.58 doesn't return LSOM data"
6278         local dir=$DIR/$tdir
6279         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6280
6281         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6282
6283         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6284         $LCTL set_param -n llite.*.statahead_agl=0
6285         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6286
6287         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6288         # open and close all files to ensure LSOM is updated
6289         cancel_lru_locks $OSC
6290         find $dir -type f | xargs cat > /dev/null
6291
6292         #   expect_found  glimpse_rpcs  command_to_run
6293         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6294         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6295         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6296         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6297
6298         echo "test" > $dir/$tfile
6299         echo "test2" > $dir/$tfile.2 && sync
6300         cancel_lru_locks $OSC
6301         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6302
6303         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6304         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6305         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6306         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6307
6308         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6309         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6310         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6311         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6312         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6313         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6314 }
6315 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6316
6317 test_56rb() {
6318         local dir=$DIR/$tdir
6319         local tmp=$TMP/$tfile.log
6320         local mdt_idx;
6321
6322         test_mkdir -p $dir || error "failed to mkdir $dir"
6323         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6324                 error "failed to setstripe $dir/$tfile"
6325         mdt_idx=$($LFS getdirstripe -i $dir)
6326         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6327
6328         stack_trap "rm -f $tmp" EXIT
6329         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6330         ! grep -q obd_uuid $tmp ||
6331                 error "failed to find --size +100K --ost 0 $dir"
6332         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6333         ! grep -q obd_uuid $tmp ||
6334                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6335 }
6336 run_test 56rb "check lfs find --size --ost/--mdt works"
6337
6338 test_56s() { # LU-611 #LU-9369
6339         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6340
6341         local dir=$DIR/$tdir
6342         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6343
6344         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6345         for i in $(seq $NUMDIRS); do
6346                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6347         done
6348
6349         local expected=$NUMDIRS
6350         local cmd="$LFS find -c $OSTCOUNT $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] || {
6354                 $LFS getstripe -R $dir
6355                 error "'$cmd' wrong: found $nums, expected $expected"
6356         }
6357
6358         expected=$((NUMDIRS + onestripe))
6359         cmd="$LFS find -stripe-count +0 -type f $dir"
6360         nums=$($cmd | wc -l)
6361         [ $nums -eq $expected ] || {
6362                 $LFS getstripe -R $dir
6363                 error "'$cmd' wrong: found $nums, expected $expected"
6364         }
6365
6366         expected=$onestripe
6367         cmd="$LFS find -stripe-count 1 -type f $dir"
6368         nums=$($cmd | wc -l)
6369         [ $nums -eq $expected ] || {
6370                 $LFS getstripe -R $dir
6371                 error "'$cmd' wrong: found $nums, expected $expected"
6372         }
6373
6374         cmd="$LFS find -stripe-count -2 -type f $dir"
6375         nums=$($cmd | wc -l)
6376         [ $nums -eq $expected ] || {
6377                 $LFS getstripe -R $dir
6378                 error "'$cmd' wrong: found $nums, expected $expected"
6379         }
6380
6381         expected=0
6382         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6383         nums=$($cmd | wc -l)
6384         [ $nums -eq $expected ] || {
6385                 $LFS getstripe -R $dir
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387         }
6388 }
6389 run_test 56s "check lfs find -stripe-count works"
6390
6391 test_56t() { # LU-611 #LU-9369
6392         local dir=$DIR/$tdir
6393
6394         setup_56 $dir 0 $NUMDIRS
6395         for i in $(seq $NUMDIRS); do
6396                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6397         done
6398
6399         local expected=$NUMDIRS
6400         local cmd="$LFS find -S 8M $dir"
6401         local nums=$($cmd | wc -l)
6402
6403         [ $nums -eq $expected ] || {
6404                 $LFS getstripe -R $dir
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406         }
6407         rm -rf $dir
6408
6409         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6410
6411         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6412
6413         expected=$(((NUMDIRS + 1) * NUMFILES))
6414         cmd="$LFS find -stripe-size 512k -type f $dir"
6415         nums=$($cmd | wc -l)
6416         [ $nums -eq $expected ] ||
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418
6419         cmd="$LFS find -stripe-size +320k -type f $dir"
6420         nums=$($cmd | wc -l)
6421         [ $nums -eq $expected ] ||
6422                 error "'$cmd' wrong: found $nums, expected $expected"
6423
6424         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6425         cmd="$LFS find -stripe-size +200k -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 -640k -type f $dir"
6431         nums=$($cmd | wc -l)
6432         [ $nums -eq $expected ] ||
6433                 error "'$cmd' wrong: found $nums, expected $expected"
6434
6435         expected=4
6436         cmd="$LFS find -stripe-size 256k -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 -320k -type f $dir"
6442         nums=$($cmd | wc -l)
6443         [ $nums -eq $expected ] ||
6444                 error "'$cmd' wrong: found $nums, expected $expected"
6445
6446         expected=0
6447         cmd="$LFS find -stripe-size 1024k -type f $dir"
6448         nums=$($cmd | wc -l)
6449         [ $nums -eq $expected ] ||
6450                 error "'$cmd' wrong: found $nums, expected $expected"
6451 }
6452 run_test 56t "check lfs find -stripe-size works"
6453
6454 test_56u() { # LU-611
6455         local dir=$DIR/$tdir
6456
6457         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6458
6459         if [[ $OSTCOUNT -gt 1 ]]; then
6460                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6461                 onestripe=4
6462         else
6463                 onestripe=0
6464         fi
6465
6466         local expected=$(((NUMDIRS + 1) * NUMFILES))
6467         local cmd="$LFS find -stripe-index 0 -type f $dir"
6468         local nums=$($cmd | wc -l)
6469
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472
6473         expected=$onestripe
6474         cmd="$LFS find -stripe-index 1 -type f $dir"
6475         nums=$($cmd | wc -l)
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478
6479         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6480         nums=$($cmd | wc -l)
6481         [ $nums -eq $expected ] ||
6482                 error "'$cmd' wrong: found $nums, expected $expected"
6483
6484         expected=0
6485         # This should produce an error and not return any files
6486         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6487         nums=$($cmd 2>/dev/null | wc -l)
6488         [ $nums -eq $expected ] ||
6489                 error "'$cmd' wrong: found $nums, expected $expected"
6490
6491         if [[ $OSTCOUNT -gt 1 ]]; then
6492                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6493                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6494                 nums=$($cmd | wc -l)
6495                 [ $nums -eq $expected ] ||
6496                         error "'$cmd' wrong: found $nums, expected $expected"
6497         fi
6498 }
6499 run_test 56u "check lfs find -stripe-index works"
6500
6501 test_56v() {
6502         local mdt_idx=0
6503         local dir=$DIR/$tdir
6504
6505         setup_56 $dir $NUMFILES $NUMDIRS
6506
6507         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6508         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6509
6510         for file in $($LFS find -m $UUID $dir); do
6511                 file_midx=$($LFS getstripe -m $file)
6512                 [ $file_midx -eq $mdt_idx ] ||
6513                         error "lfs find -m $UUID != getstripe -m $file_midx"
6514         done
6515 }
6516 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6517
6518 test_56w() {
6519         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6521
6522         local dir=$DIR/$tdir
6523
6524         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6525
6526         local stripe_size=$($LFS getstripe -S -d $dir) ||
6527                 error "$LFS getstripe -S -d $dir failed"
6528         stripe_size=${stripe_size%% *}
6529
6530         local file_size=$((stripe_size * OSTCOUNT))
6531         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6532         local required_space=$((file_num * file_size))
6533         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6534                            head -n1)
6535         [[ $free_space -le $((required_space / 1024)) ]] &&
6536                 skip_env "need $required_space, have $free_space kbytes"
6537
6538         local dd_bs=65536
6539         local dd_count=$((file_size / dd_bs))
6540
6541         # write data into the files
6542         local i
6543         local j
6544         local file
6545
6546         for i in $(seq $NUMFILES); do
6547                 file=$dir/file$i
6548                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6549                         error "write data into $file failed"
6550         done
6551         for i in $(seq $NUMDIRS); do
6552                 for j in $(seq $NUMFILES); do
6553                         file=$dir/dir$i/file$j
6554                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6555                                 error "write data into $file failed"
6556                 done
6557         done
6558
6559         # $LFS_MIGRATE will fail if hard link migration is unsupported
6560         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6561                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6562                         error "creating links to $dir/dir1/file1 failed"
6563         fi
6564
6565         local expected=-1
6566
6567         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6568
6569         # lfs_migrate file
6570         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6571
6572         echo "$cmd"
6573         eval $cmd || error "$cmd failed"
6574
6575         check_stripe_count $dir/file1 $expected
6576
6577         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6578         then
6579                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6580                 # OST 1 if it is on OST 0. This file is small enough to
6581                 # be on only one stripe.
6582                 file=$dir/migr_1_ost
6583                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6584                         error "write data into $file failed"
6585                 local obdidx=$($LFS getstripe -i $file)
6586                 local oldmd5=$(md5sum $file)
6587                 local newobdidx=0
6588
6589                 [[ $obdidx -eq 0 ]] && newobdidx=1
6590                 cmd="$LFS migrate -i $newobdidx $file"
6591                 echo $cmd
6592                 eval $cmd || error "$cmd failed"
6593
6594                 local realobdix=$($LFS getstripe -i $file)
6595                 local newmd5=$(md5sum $file)
6596
6597                 [[ $newobdidx -ne $realobdix ]] &&
6598                         error "new OST is different (was=$obdidx, "\
6599                               "wanted=$newobdidx, got=$realobdix)"
6600                 [[ "$oldmd5" != "$newmd5" ]] &&
6601                         error "md5sum differ: $oldmd5, $newmd5"
6602         fi
6603
6604         # lfs_migrate dir
6605         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6606         echo "$cmd"
6607         eval $cmd || error "$cmd failed"
6608
6609         for j in $(seq $NUMFILES); do
6610                 check_stripe_count $dir/dir1/file$j $expected
6611         done
6612
6613         # lfs_migrate works with lfs find
6614         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6615              $LFS_MIGRATE -y -c $expected"
6616         echo "$cmd"
6617         eval $cmd || error "$cmd failed"
6618
6619         for i in $(seq 2 $NUMFILES); do
6620                 check_stripe_count $dir/file$i $expected
6621         done
6622         for i in $(seq 2 $NUMDIRS); do
6623                 for j in $(seq $NUMFILES); do
6624                 check_stripe_count $dir/dir$i/file$j $expected
6625                 done
6626         done
6627 }
6628 run_test 56w "check lfs_migrate -c stripe_count works"
6629
6630 test_56wb() {
6631         local file1=$DIR/$tdir/file1
6632         local create_pool=false
6633         local initial_pool=$($LFS getstripe -p $DIR)
6634         local pool_list=()
6635         local pool=""
6636
6637         echo -n "Creating test dir..."
6638         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6639         echo "done."
6640
6641         echo -n "Creating test file..."
6642         touch $file1 || error "cannot create file"
6643         echo "done."
6644
6645         echo -n "Detecting existing pools..."
6646         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6647
6648         if [ ${#pool_list[@]} -gt 0 ]; then
6649                 echo "${pool_list[@]}"
6650                 for thispool in "${pool_list[@]}"; do
6651                         if [[ -z "$initial_pool" ||
6652                               "$initial_pool" != "$thispool" ]]; then
6653                                 pool="$thispool"
6654                                 echo "Using existing pool '$pool'"
6655                                 break
6656                         fi
6657                 done
6658         else
6659                 echo "none detected."
6660         fi
6661         if [ -z "$pool" ]; then
6662                 pool=${POOL:-testpool}
6663                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6664                 echo -n "Creating pool '$pool'..."
6665                 create_pool=true
6666                 pool_add $pool &> /dev/null ||
6667                         error "pool_add failed"
6668                 echo "done."
6669
6670                 echo -n "Adding target to pool..."
6671                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6672                         error "pool_add_targets failed"
6673                 echo "done."
6674         fi
6675
6676         echo -n "Setting pool using -p option..."
6677         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6678                 error "migrate failed rc = $?"
6679         echo "done."
6680
6681         echo -n "Verifying test file is in pool after migrating..."
6682         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6683                 error "file was not migrated to pool $pool"
6684         echo "done."
6685
6686         echo -n "Removing test file from pool '$pool'..."
6687         # "lfs migrate $file" won't remove the file from the pool
6688         # until some striping information is changed.
6689         $LFS migrate -c 1 $file1 &> /dev/null ||
6690                 error "cannot remove from pool"
6691         [ "$($LFS getstripe -p $file1)" ] &&
6692                 error "pool still set"
6693         echo "done."
6694
6695         echo -n "Setting pool using --pool option..."
6696         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6697                 error "migrate failed rc = $?"
6698         echo "done."
6699
6700         # Clean up
6701         rm -f $file1
6702         if $create_pool; then
6703                 destroy_test_pools 2> /dev/null ||
6704                         error "destroy test pools failed"
6705         fi
6706 }
6707 run_test 56wb "check lfs_migrate pool support"
6708
6709 test_56wc() {
6710         local file1="$DIR/$tdir/file1"
6711         local parent_ssize
6712         local parent_scount
6713         local cur_ssize
6714         local cur_scount
6715         local orig_ssize
6716
6717         echo -n "Creating test dir..."
6718         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6719         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6720                 error "cannot set stripe by '-S 1M -c 1'"
6721         echo "done"
6722
6723         echo -n "Setting initial stripe for test file..."
6724         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6725                 error "cannot set stripe"
6726         cur_ssize=$($LFS getstripe -S "$file1")
6727         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6728         echo "done."
6729
6730         # File currently set to -S 512K -c 1
6731
6732         # Ensure -c and -S options are rejected when -R is set
6733         echo -n "Verifying incompatible options are detected..."
6734         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6735                 error "incompatible -c and -R options not detected"
6736         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6737                 error "incompatible -S and -R options not detected"
6738         echo "done."
6739
6740         # Ensure unrecognized options are passed through to 'lfs migrate'
6741         echo -n "Verifying -S option is passed through to lfs migrate..."
6742         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6743                 error "migration failed"
6744         cur_ssize=$($LFS getstripe -S "$file1")
6745         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6746         echo "done."
6747
6748         # File currently set to -S 1M -c 1
6749
6750         # Ensure long options are supported
6751         echo -n "Verifying long options supported..."
6752         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6753                 error "long option without argument not supported"
6754         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6755                 error "long option with argument not supported"
6756         cur_ssize=$($LFS getstripe -S "$file1")
6757         [ $cur_ssize -eq 524288 ] ||
6758                 error "migrate --stripe-size $cur_ssize != 524288"
6759         echo "done."
6760
6761         # File currently set to -S 512K -c 1
6762
6763         if [ "$OSTCOUNT" -gt 1 ]; then
6764                 echo -n "Verifying explicit stripe count can be set..."
6765                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6766                         error "migrate failed"
6767                 cur_scount=$($LFS getstripe -c "$file1")
6768                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6769                 echo "done."
6770         fi
6771
6772         # File currently set to -S 512K -c 1 or -S 512K -c 2
6773
6774         # Ensure parent striping is used if -R is set, and no stripe
6775         # count or size is specified
6776         echo -n "Setting stripe for parent directory..."
6777         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6778                 error "cannot set stripe '-S 2M -c 1'"
6779         echo "done."
6780
6781         echo -n "Verifying restripe option uses parent stripe settings..."
6782         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6783         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6784         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6785                 error "migrate failed"
6786         cur_ssize=$($LFS getstripe -S "$file1")
6787         [ $cur_ssize -eq $parent_ssize ] ||
6788                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6789         cur_scount=$($LFS getstripe -c "$file1")
6790         [ $cur_scount -eq $parent_scount ] ||
6791                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6792         echo "done."
6793
6794         # File currently set to -S 1M -c 1
6795
6796         # Ensure striping is preserved if -R is not set, and no stripe
6797         # count or size is specified
6798         echo -n "Verifying striping size preserved when not specified..."
6799         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6800         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6801                 error "cannot set stripe on parent directory"
6802         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6803                 error "migrate failed"
6804         cur_ssize=$($LFS getstripe -S "$file1")
6805         [ $cur_ssize -eq $orig_ssize ] ||
6806                 error "migrate by default $cur_ssize != $orig_ssize"
6807         echo "done."
6808
6809         # Ensure file name properly detected when final option has no argument
6810         echo -n "Verifying file name properly detected..."
6811         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6812                 error "file name interpreted as option argument"
6813         echo "done."
6814
6815         # Clean up
6816         rm -f "$file1"
6817 }
6818 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6819
6820 test_56wd() {
6821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6822
6823         local file1=$DIR/$tdir/file1
6824
6825         echo -n "Creating test dir..."
6826         test_mkdir $DIR/$tdir || error "cannot create dir"
6827         echo "done."
6828
6829         echo -n "Creating test file..."
6830         touch $file1
6831         echo "done."
6832
6833         # Ensure 'lfs migrate' will fail by using a non-existent option,
6834         # and make sure rsync is not called to recover
6835         echo -n "Make sure --no-rsync option works..."
6836         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6837                 grep -q 'refusing to fall back to rsync' ||
6838                 error "rsync was called with --no-rsync set"
6839         echo "done."
6840
6841         # Ensure rsync is called without trying 'lfs migrate' first
6842         echo -n "Make sure --rsync option works..."
6843         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6844                 grep -q 'falling back to rsync' &&
6845                 error "lfs migrate was called with --rsync set"
6846         echo "done."
6847
6848         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6849         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6850                 grep -q 'at the same time' ||
6851                 error "--rsync and --no-rsync accepted concurrently"
6852         echo "done."
6853
6854         # Clean up
6855         rm -f $file1
6856 }
6857 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6858
6859 test_56we() {
6860         local td=$DIR/$tdir
6861         local tf=$td/$tfile
6862
6863         test_mkdir $td || error "cannot create $td"
6864         touch $tf || error "cannot touch $tf"
6865
6866         echo -n "Make sure --non-direct|-D works..."
6867         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6868                 grep -q "lfs migrate --non-direct" ||
6869                 error "--non-direct option cannot work correctly"
6870         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6871                 grep -q "lfs migrate -D" ||
6872                 error "-D option cannot work correctly"
6873         echo "done."
6874 }
6875 run_test 56we "check lfs_migrate --non-direct|-D support"
6876
6877 test_56x() {
6878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6879         check_swap_layouts_support
6880
6881         local dir=$DIR/$tdir
6882         local ref1=/etc/passwd
6883         local file1=$dir/file1
6884
6885         test_mkdir $dir || error "creating dir $dir"
6886         $LFS setstripe -c 2 $file1
6887         cp $ref1 $file1
6888         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6889         stripe=$($LFS getstripe -c $file1)
6890         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6891         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6892
6893         # clean up
6894         rm -f $file1
6895 }
6896 run_test 56x "lfs migration support"
6897
6898 test_56xa() {
6899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6900         check_swap_layouts_support
6901
6902         local dir=$DIR/$tdir/$testnum
6903
6904         test_mkdir -p $dir
6905
6906         local ref1=/etc/passwd
6907         local file1=$dir/file1
6908
6909         $LFS setstripe -c 2 $file1
6910         cp $ref1 $file1
6911         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6912
6913         local stripe=$($LFS getstripe -c $file1)
6914
6915         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6916         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6917
6918         # clean up
6919         rm -f $file1
6920 }
6921 run_test 56xa "lfs migration --block support"
6922
6923 check_migrate_links() {
6924         local dir="$1"
6925         local file1="$dir/file1"
6926         local begin="$2"
6927         local count="$3"
6928         local runas="$4"
6929         local total_count=$(($begin + $count - 1))
6930         local symlink_count=10
6931         local uniq_count=10
6932
6933         if [ ! -f "$file1" ]; then
6934                 echo -n "creating initial file..."
6935                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6936                         error "cannot setstripe initial file"
6937                 echo "done"
6938
6939                 echo -n "creating symlinks..."
6940                 for s in $(seq 1 $symlink_count); do
6941                         ln -s "$file1" "$dir/slink$s" ||
6942                                 error "cannot create symlinks"
6943                 done
6944                 echo "done"
6945
6946                 echo -n "creating nonlinked files..."
6947                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6948                         error "cannot create nonlinked files"
6949                 echo "done"
6950         fi
6951
6952         # create hard links
6953         if [ ! -f "$dir/file$total_count" ]; then
6954                 echo -n "creating hard links $begin:$total_count..."
6955                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6956                         /dev/null || error "cannot create hard links"
6957                 echo "done"
6958         fi
6959
6960         echo -n "checking number of hard links listed in xattrs..."
6961         local fid=$($LFS getstripe -F "$file1")
6962         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6963
6964         echo "${#paths[*]}"
6965         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6966                         skip "hard link list has unexpected size, skipping test"
6967         fi
6968         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6969                         error "link names should exceed xattrs size"
6970         fi
6971
6972         echo -n "migrating files..."
6973         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6974         local rc=$?
6975         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6976         echo "done"
6977
6978         # make sure all links have been properly migrated
6979         echo -n "verifying files..."
6980         fid=$($LFS getstripe -F "$file1") ||
6981                 error "cannot get fid for file $file1"
6982         for i in $(seq 2 $total_count); do
6983                 local fid2=$($LFS getstripe -F $dir/file$i)
6984
6985                 [ "$fid2" == "$fid" ] ||
6986                         error "migrated hard link has mismatched FID"
6987         done
6988
6989         # make sure hard links were properly detected, and migration was
6990         # performed only once for the entire link set; nonlinked files should
6991         # also be migrated
6992         local actual=$(grep -c 'done' <<< "$migrate_out")
6993         local expected=$(($uniq_count + 1))
6994
6995         [ "$actual" -eq  "$expected" ] ||
6996                 error "hard links individually migrated ($actual != $expected)"
6997
6998         # make sure the correct number of hard links are present
6999         local hardlinks=$(stat -c '%h' "$file1")
7000
7001         [ $hardlinks -eq $total_count ] ||
7002                 error "num hard links $hardlinks != $total_count"
7003         echo "done"
7004
7005         return 0
7006 }
7007
7008 test_56xb() {
7009         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7010                 skip "Need MDS version at least 2.10.55"
7011
7012         local dir="$DIR/$tdir"
7013
7014         test_mkdir "$dir" || error "cannot create dir $dir"
7015
7016         echo "testing lfs migrate mode when all links fit within xattrs"
7017         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7018
7019         echo "testing rsync mode when all links fit within xattrs"
7020         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7021
7022         echo "testing lfs migrate mode when all links do not fit within xattrs"
7023         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7024
7025         echo "testing rsync mode when all links do not fit within xattrs"
7026         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7027
7028         chown -R $RUNAS_ID $dir
7029         echo "testing non-root lfs migrate mode when not all links are in xattr"
7030         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7031
7032         # clean up
7033         rm -rf $dir
7034 }
7035 run_test 56xb "lfs migration hard link support"
7036
7037 test_56xc() {
7038         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7039
7040         local dir="$DIR/$tdir"
7041
7042         test_mkdir "$dir" || error "cannot create dir $dir"
7043
7044         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7045         echo -n "Setting initial stripe for 20MB test file..."
7046         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7047                 error "cannot setstripe 20MB file"
7048         echo "done"
7049         echo -n "Sizing 20MB test file..."
7050         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7051         echo "done"
7052         echo -n "Verifying small file autostripe count is 1..."
7053         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7054                 error "cannot migrate 20MB file"
7055         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7056                 error "cannot get stripe for $dir/20mb"
7057         [ $stripe_count -eq 1 ] ||
7058                 error "unexpected stripe count $stripe_count for 20MB file"
7059         rm -f "$dir/20mb"
7060         echo "done"
7061
7062         # Test 2: File is small enough to fit within the available space on
7063         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7064         # have at least an additional 1KB for each desired stripe for test 3
7065         echo -n "Setting stripe for 1GB test file..."
7066         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7067         echo "done"
7068         echo -n "Sizing 1GB test file..."
7069         # File size is 1GB + 3KB
7070         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7071         echo "done"
7072
7073         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7074         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7075         if (( avail > 524288 * OSTCOUNT )); then
7076                 echo -n "Migrating 1GB file..."
7077                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7078                         error "cannot migrate 1GB file"
7079                 echo "done"
7080                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7081                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7082                         error "cannot getstripe for 1GB file"
7083                 [ $stripe_count -eq 2 ] ||
7084                         error "unexpected stripe count $stripe_count != 2"
7085                 echo "done"
7086         fi
7087
7088         # Test 3: File is too large to fit within the available space on
7089         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7090         if [ $OSTCOUNT -ge 3 ]; then
7091                 # The required available space is calculated as
7092                 # file size (1GB + 3KB) / OST count (3).
7093                 local kb_per_ost=349526
7094
7095                 echo -n "Migrating 1GB file with limit..."
7096                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7097                         error "cannot migrate 1GB file with limit"
7098                 echo "done"
7099
7100                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7101                 echo -n "Verifying 1GB autostripe count with limited space..."
7102                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7103                         error "unexpected stripe count $stripe_count (min 3)"
7104                 echo "done"
7105         fi
7106
7107         # clean up
7108         rm -rf $dir
7109 }
7110 run_test 56xc "lfs migration autostripe"
7111
7112 test_56xd() {
7113         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7114
7115         local dir=$DIR/$tdir
7116         local f_mgrt=$dir/$tfile.mgrt
7117         local f_yaml=$dir/$tfile.yaml
7118         local f_copy=$dir/$tfile.copy
7119         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7120         local layout_copy="-c 2 -S 2M -i 1"
7121         local yamlfile=$dir/yamlfile
7122         local layout_before;
7123         local layout_after;
7124
7125         test_mkdir "$dir" || error "cannot create dir $dir"
7126         $LFS setstripe $layout_yaml $f_yaml ||
7127                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7128         $LFS getstripe --yaml $f_yaml > $yamlfile
7129         $LFS setstripe $layout_copy $f_copy ||
7130                 error "cannot setstripe $f_copy with layout $layout_copy"
7131         touch $f_mgrt
7132         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7133
7134         # 1. test option --yaml
7135         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7136                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7137         layout_before=$(get_layout_param $f_yaml)
7138         layout_after=$(get_layout_param $f_mgrt)
7139         [ "$layout_after" == "$layout_before" ] ||
7140                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7141
7142         # 2. test option --copy
7143         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7144                 error "cannot migrate $f_mgrt with --copy $f_copy"
7145         layout_before=$(get_layout_param $f_copy)
7146         layout_after=$(get_layout_param $f_mgrt)
7147         [ "$layout_after" == "$layout_before" ] ||
7148                 error "lfs_migrate --copy: $layout_after != $layout_before"
7149 }
7150 run_test 56xd "check lfs_migrate --yaml and --copy support"
7151
7152 test_56xe() {
7153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7154
7155         local dir=$DIR/$tdir
7156         local f_comp=$dir/$tfile
7157         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7158         local layout_before=""
7159         local layout_after=""
7160
7161         test_mkdir "$dir" || error "cannot create dir $dir"
7162         $LFS setstripe $layout $f_comp ||
7163                 error "cannot setstripe $f_comp with layout $layout"
7164         layout_before=$(get_layout_param $f_comp)
7165         dd if=/dev/zero of=$f_comp bs=1M count=4
7166
7167         # 1. migrate a comp layout file by lfs_migrate
7168         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7169         layout_after=$(get_layout_param $f_comp)
7170         [ "$layout_before" == "$layout_after" ] ||
7171                 error "lfs_migrate: $layout_before != $layout_after"
7172
7173         # 2. migrate a comp layout file by lfs migrate
7174         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7175         layout_after=$(get_layout_param $f_comp)
7176         [ "$layout_before" == "$layout_after" ] ||
7177                 error "lfs migrate: $layout_before != $layout_after"
7178 }
7179 run_test 56xe "migrate a composite layout file"
7180
7181 test_56xf() {
7182         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7183
7184         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7185                 skip "Need server version at least 2.13.53"
7186
7187         local dir=$DIR/$tdir
7188         local f_comp=$dir/$tfile
7189         local layout="-E 1M -c1 -E -1 -c2"
7190         local fid_before=""
7191         local fid_after=""
7192
7193         test_mkdir "$dir" || error "cannot create dir $dir"
7194         $LFS setstripe $layout $f_comp ||
7195                 error "cannot setstripe $f_comp with layout $layout"
7196         fid_before=$($LFS getstripe --fid $f_comp)
7197         dd if=/dev/zero of=$f_comp bs=1M count=4
7198
7199         # 1. migrate a comp layout file to a comp layout
7200         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7201         fid_after=$($LFS getstripe --fid $f_comp)
7202         [ "$fid_before" == "$fid_after" ] ||
7203                 error "comp-to-comp migrate: $fid_before != $fid_after"
7204
7205         # 2. migrate a comp layout file to a plain layout
7206         $LFS migrate -c2 $f_comp ||
7207                 error "cannot migrate $f_comp by lfs migrate"
7208         fid_after=$($LFS getstripe --fid $f_comp)
7209         [ "$fid_before" == "$fid_after" ] ||
7210                 error "comp-to-plain migrate: $fid_before != $fid_after"
7211
7212         # 3. migrate a plain layout file to a comp layout
7213         $LFS migrate $layout $f_comp ||
7214                 error "cannot migrate $f_comp by lfs migrate"
7215         fid_after=$($LFS getstripe --fid $f_comp)
7216         [ "$fid_before" == "$fid_after" ] ||
7217                 error "plain-to-comp migrate: $fid_before != $fid_after"
7218 }
7219 run_test 56xf "FID is not lost during migration of a composite layout file"
7220
7221 test_56y() {
7222         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7223                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7224
7225         local res=""
7226         local dir=$DIR/$tdir
7227         local f1=$dir/file1
7228         local f2=$dir/file2
7229
7230         test_mkdir -p $dir || error "creating dir $dir"
7231         touch $f1 || error "creating std file $f1"
7232         $MULTIOP $f2 H2c || error "creating released file $f2"
7233
7234         # a directory can be raid0, so ask only for files
7235         res=$($LFS find $dir -L raid0 -type f | wc -l)
7236         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7237
7238         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7239         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7240
7241         # only files can be released, so no need to force file search
7242         res=$($LFS find $dir -L released)
7243         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7244
7245         res=$($LFS find $dir -type f \! -L released)
7246         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7247 }
7248 run_test 56y "lfs find -L raid0|released"
7249
7250 test_56z() { # LU-4824
7251         # This checks to make sure 'lfs find' continues after errors
7252         # There are two classes of errors that should be caught:
7253         # - If multiple paths are provided, all should be searched even if one
7254         #   errors out
7255         # - If errors are encountered during the search, it should not terminate
7256         #   early
7257         local dir=$DIR/$tdir
7258         local i
7259
7260         test_mkdir $dir
7261         for i in d{0..9}; do
7262                 test_mkdir $dir/$i
7263                 touch $dir/$i/$tfile
7264         done
7265         $LFS find $DIR/non_existent_dir $dir &&
7266                 error "$LFS find did not return an error"
7267         # Make a directory unsearchable. This should NOT be the last entry in
7268         # directory order.  Arbitrarily pick the 6th entry
7269         chmod 700 $($LFS find $dir -type d | sed '6!d')
7270
7271         $RUNAS $LFS find $DIR/non_existent $dir
7272         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7273
7274         # The user should be able to see 10 directories and 9 files
7275         (( count == 19 )) ||
7276                 error "$LFS find found $count != 19 entries after error"
7277 }
7278 run_test 56z "lfs find should continue after an error"
7279
7280 test_56aa() { # LU-5937
7281         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7282
7283         local dir=$DIR/$tdir
7284
7285         mkdir $dir
7286         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7287
7288         createmany -o $dir/striped_dir/${tfile}- 1024
7289         local dirs=$($LFS find --size +8k $dir/)
7290
7291         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7292 }
7293 run_test 56aa "lfs find --size under striped dir"
7294
7295 test_56ab() { # LU-10705
7296         test_mkdir $DIR/$tdir
7297         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7298         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7299         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7300         # Flush writes to ensure valid blocks.  Need to be more thorough for
7301         # ZFS, since blocks are not allocated/returned to client immediately.
7302         sync_all_data
7303         wait_zfs_commit ost1 2
7304         cancel_lru_locks osc
7305         ls -ls $DIR/$tdir
7306
7307         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7308
7309         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7310
7311         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7312         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7313
7314         rm -f $DIR/$tdir/$tfile.[123]
7315 }
7316 run_test 56ab "lfs find --blocks"
7317
7318 test_56ba() {
7319         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7320                 skip "Need MDS version at least 2.10.50"
7321
7322         # Create composite files with one component
7323         local dir=$DIR/$tdir
7324
7325         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7326         # Create composite files with three components
7327         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7328         # Create non-composite files
7329         createmany -o $dir/${tfile}- 10
7330
7331         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7332
7333         [[ $nfiles == 10 ]] ||
7334                 error "lfs find -E 1M found $nfiles != 10 files"
7335
7336         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7337         [[ $nfiles == 25 ]] ||
7338                 error "lfs find ! -E 1M found $nfiles != 25 files"
7339
7340         # All files have a component that starts at 0
7341         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7342         [[ $nfiles == 35 ]] ||
7343                 error "lfs find --component-start 0 - $nfiles != 35 files"
7344
7345         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7346         [[ $nfiles == 15 ]] ||
7347                 error "lfs find --component-start 2M - $nfiles != 15 files"
7348
7349         # All files created here have a componenet that does not starts at 2M
7350         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7351         [[ $nfiles == 35 ]] ||
7352                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7353
7354         # Find files with a specified number of components
7355         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7356         [[ $nfiles == 15 ]] ||
7357                 error "lfs find --component-count 3 - $nfiles != 15 files"
7358
7359         # Remember non-composite files have a component count of zero
7360         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7361         [[ $nfiles == 10 ]] ||
7362                 error "lfs find --component-count 0 - $nfiles != 10 files"
7363
7364         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7365         [[ $nfiles == 20 ]] ||
7366                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7367
7368         # All files have a flag called "init"
7369         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7370         [[ $nfiles == 35 ]] ||
7371                 error "lfs find --component-flags init - $nfiles != 35 files"
7372
7373         # Multi-component files will have a component not initialized
7374         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7375         [[ $nfiles == 15 ]] ||
7376                 error "lfs find !--component-flags init - $nfiles != 15 files"
7377
7378         rm -rf $dir
7379
7380 }
7381 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7382
7383 test_56ca() {
7384         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7385                 skip "Need MDS version at least 2.10.57"
7386
7387         local td=$DIR/$tdir
7388         local tf=$td/$tfile
7389         local dir
7390         local nfiles
7391         local cmd
7392         local i
7393         local j
7394
7395         # create mirrored directories and mirrored files
7396         mkdir $td || error "mkdir $td failed"
7397         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7398         createmany -o $tf- 10 || error "create $tf- failed"
7399
7400         for i in $(seq 2); do
7401                 dir=$td/dir$i
7402                 mkdir $dir || error "mkdir $dir failed"
7403                 $LFS mirror create -N$((3 + i)) $dir ||
7404                         error "create mirrored dir $dir failed"
7405                 createmany -o $dir/$tfile- 10 ||
7406                         error "create $dir/$tfile- failed"
7407         done
7408
7409         # change the states of some mirrored files
7410         echo foo > $tf-6
7411         for i in $(seq 2); do
7412                 dir=$td/dir$i
7413                 for j in $(seq 4 9); do
7414                         echo foo > $dir/$tfile-$j
7415                 done
7416         done
7417
7418         # find mirrored files with specific mirror count
7419         cmd="$LFS find --mirror-count 3 --type f $td"
7420         nfiles=$($cmd | wc -l)
7421         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7422
7423         cmd="$LFS find ! --mirror-count 3 --type f $td"
7424         nfiles=$($cmd | wc -l)
7425         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7426
7427         cmd="$LFS find --mirror-count +2 --type f $td"
7428         nfiles=$($cmd | wc -l)
7429         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7430
7431         cmd="$LFS find --mirror-count -6 --type f $td"
7432         nfiles=$($cmd | wc -l)
7433         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7434
7435         # find mirrored files with specific file state
7436         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7437         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7438
7439         cmd="$LFS find --mirror-state=ro --type f $td"
7440         nfiles=$($cmd | wc -l)
7441         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7442
7443         cmd="$LFS find ! --mirror-state=ro --type f $td"
7444         nfiles=$($cmd | wc -l)
7445         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7446
7447         cmd="$LFS find --mirror-state=wp --type f $td"
7448         nfiles=$($cmd | wc -l)
7449         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7450
7451         cmd="$LFS find ! --mirror-state=sp --type f $td"
7452         nfiles=$($cmd | wc -l)
7453         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7454 }
7455 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7456
7457 test_57a() {
7458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7459         # note test will not do anything if MDS is not local
7460         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7461                 skip_env "ldiskfs only test"
7462         fi
7463         remote_mds_nodsh && skip "remote MDS with nodsh"
7464
7465         local MNTDEV="osd*.*MDT*.mntdev"
7466         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7467         [ -z "$DEV" ] && error "can't access $MNTDEV"
7468         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7469                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7470                         error "can't access $DEV"
7471                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7472                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7473                 rm $TMP/t57a.dump
7474         done
7475 }
7476 run_test 57a "verify MDS filesystem created with large inodes =="
7477
7478 test_57b() {
7479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7480         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7481                 skip_env "ldiskfs only test"
7482         fi
7483         remote_mds_nodsh && skip "remote MDS with nodsh"
7484
7485         local dir=$DIR/$tdir
7486         local filecount=100
7487         local file1=$dir/f1
7488         local fileN=$dir/f$filecount
7489
7490         rm -rf $dir || error "removing $dir"
7491         test_mkdir -c1 $dir
7492         local mdtidx=$($LFS getstripe -m $dir)
7493         local mdtname=MDT$(printf %04x $mdtidx)
7494         local facet=mds$((mdtidx + 1))
7495
7496         echo "mcreating $filecount files"
7497         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7498
7499         # verify that files do not have EAs yet
7500         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7501                 error "$file1 has an EA"
7502         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7503                 error "$fileN has an EA"
7504
7505         sync
7506         sleep 1
7507         df $dir  #make sure we get new statfs data
7508         local mdsfree=$(do_facet $facet \
7509                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7510         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7511         local file
7512
7513         echo "opening files to create objects/EAs"
7514         for file in $(seq -f $dir/f%g 1 $filecount); do
7515                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7516                         error "opening $file"
7517         done
7518
7519         # verify that files have EAs now
7520         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7521         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7522
7523         sleep 1  #make sure we get new statfs data
7524         df $dir
7525         local mdsfree2=$(do_facet $facet \
7526                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7527         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7528
7529         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7530                 if [ "$mdsfree" != "$mdsfree2" ]; then
7531                         error "MDC before $mdcfree != after $mdcfree2"
7532                 else
7533                         echo "MDC before $mdcfree != after $mdcfree2"
7534                         echo "unable to confirm if MDS has large inodes"
7535                 fi
7536         fi
7537         rm -rf $dir
7538 }
7539 run_test 57b "default LOV EAs are stored inside large inodes ==="
7540
7541 test_58() {
7542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7543         [ -z "$(which wiretest 2>/dev/null)" ] &&
7544                         skip_env "could not find wiretest"
7545
7546         wiretest
7547 }
7548 run_test 58 "verify cross-platform wire constants =============="
7549
7550 test_59() {
7551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7552
7553         echo "touch 130 files"
7554         createmany -o $DIR/f59- 130
7555         echo "rm 130 files"
7556         unlinkmany $DIR/f59- 130
7557         sync
7558         # wait for commitment of removal
7559         wait_delete_completed
7560 }
7561 run_test 59 "verify cancellation of llog records async ========="
7562
7563 TEST60_HEAD="test_60 run $RANDOM"
7564 test_60a() {
7565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7566         remote_mgs_nodsh && skip "remote MGS with nodsh"
7567         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7568                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7569                         skip_env "missing subtest run-llog.sh"
7570
7571         log "$TEST60_HEAD - from kernel mode"
7572         do_facet mgs "$LCTL dk > /dev/null"
7573         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7574         do_facet mgs $LCTL dk > $TMP/$tfile
7575
7576         # LU-6388: test llog_reader
7577         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7578         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7579         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7580                         skip_env "missing llog_reader"
7581         local fstype=$(facet_fstype mgs)
7582         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7583                 skip_env "Only for ldiskfs or zfs type mgs"
7584
7585         local mntpt=$(facet_mntpt mgs)
7586         local mgsdev=$(mgsdevname 1)
7587         local fid_list
7588         local fid
7589         local rec_list
7590         local rec
7591         local rec_type
7592         local obj_file
7593         local path
7594         local seq
7595         local oid
7596         local pass=true
7597
7598         #get fid and record list
7599         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7600                 tail -n 4))
7601         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7602                 tail -n 4))
7603         #remount mgs as ldiskfs or zfs type
7604         stop mgs || error "stop mgs failed"
7605         mount_fstype mgs || error "remount mgs failed"
7606         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7607                 fid=${fid_list[i]}
7608                 rec=${rec_list[i]}
7609                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7610                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7611                 oid=$((16#$oid))
7612
7613                 case $fstype in
7614                         ldiskfs )
7615                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7616                         zfs )
7617                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7618                 esac
7619                 echo "obj_file is $obj_file"
7620                 do_facet mgs $llog_reader $obj_file
7621
7622                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7623                         awk '{ print $3 }' | sed -e "s/^type=//g")
7624                 if [ $rec_type != $rec ]; then
7625                         echo "FAILED test_60a wrong record type $rec_type," \
7626                               "should be $rec"
7627                         pass=false
7628                         break
7629                 fi
7630
7631                 #check obj path if record type is LLOG_LOGID_MAGIC
7632                 if [ "$rec" == "1064553b" ]; then
7633                         path=$(do_facet mgs $llog_reader $obj_file |
7634                                 grep "path=" | awk '{ print $NF }' |
7635                                 sed -e "s/^path=//g")
7636                         if [ $obj_file != $mntpt/$path ]; then
7637                                 echo "FAILED test_60a wrong obj path" \
7638                                       "$montpt/$path, should be $obj_file"
7639                                 pass=false
7640                                 break
7641                         fi
7642                 fi
7643         done
7644         rm -f $TMP/$tfile
7645         #restart mgs before "error", otherwise it will block the next test
7646         stop mgs || error "stop mgs failed"
7647         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7648         $pass || error "test failed, see FAILED test_60a messages for specifics"
7649 }
7650 run_test 60a "llog_test run from kernel module and test llog_reader"
7651
7652 test_60b() { # bug 6411
7653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7654
7655         dmesg > $DIR/$tfile
7656         LLOG_COUNT=$(do_facet mgs dmesg |
7657                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7658                           /llog_[a-z]*.c:[0-9]/ {
7659                                 if (marker)
7660                                         from_marker++
7661                                 from_begin++
7662                           }
7663                           END {
7664                                 if (marker)
7665                                         print from_marker
7666                                 else
7667                                         print from_begin
7668                           }")
7669
7670         [[ $LLOG_COUNT -gt 120 ]] &&
7671                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7672 }
7673 run_test 60b "limit repeated messages from CERROR/CWARN"
7674
7675 test_60c() {
7676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7677
7678         echo "create 5000 files"
7679         createmany -o $DIR/f60c- 5000
7680 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7681         lctl set_param fail_loc=0x80000137
7682         unlinkmany $DIR/f60c- 5000
7683         lctl set_param fail_loc=0
7684 }
7685 run_test 60c "unlink file when mds full"
7686
7687 test_60d() {
7688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7689
7690         SAVEPRINTK=$(lctl get_param -n printk)
7691         # verify "lctl mark" is even working"
7692         MESSAGE="test message ID $RANDOM $$"
7693         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7694         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7695
7696         lctl set_param printk=0 || error "set lnet.printk failed"
7697         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7698         MESSAGE="new test message ID $RANDOM $$"
7699         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7700         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7701         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7702
7703         lctl set_param -n printk="$SAVEPRINTK"
7704 }
7705 run_test 60d "test printk console message masking"
7706
7707 test_60e() {
7708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7709         remote_mds_nodsh && skip "remote MDS with nodsh"
7710
7711         touch $DIR/$tfile
7712 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7713         do_facet mds1 lctl set_param fail_loc=0x15b
7714         rm $DIR/$tfile
7715 }
7716 run_test 60e "no space while new llog is being created"
7717
7718 test_60g() {
7719         local pid
7720         local i
7721
7722         test_mkdir -c $MDSCOUNT $DIR/$tdir
7723
7724         (
7725                 local index=0
7726                 while true; do
7727                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7728                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7729                                 2>/dev/null
7730                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7731                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7732                         index=$((index + 1))
7733                 done
7734         ) &
7735
7736         pid=$!
7737
7738         for i in {0..100}; do
7739                 # define OBD_FAIL_OSD_TXN_START    0x19a
7740                 local index=$((i % MDSCOUNT + 1))
7741
7742                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7743                         > /dev/null
7744                 sleep 0.01
7745         done
7746
7747         kill -9 $pid
7748
7749         for i in $(seq $MDSCOUNT); do
7750                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7751         done
7752
7753         mkdir $DIR/$tdir/new || error "mkdir failed"
7754         rmdir $DIR/$tdir/new || error "rmdir failed"
7755
7756         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7757                 -t namespace
7758         for i in $(seq $MDSCOUNT); do
7759                 wait_update_facet mds$i "$LCTL get_param -n \
7760                         mdd.$(facet_svc mds$i).lfsck_namespace |
7761                         awk '/^status/ { print \\\$2 }'" "completed"
7762         done
7763
7764         ls -R $DIR/$tdir || error "ls failed"
7765         rm -rf $DIR/$tdir || error "rmdir failed"
7766 }
7767 run_test 60g "transaction abort won't cause MDT hung"
7768
7769 test_60h() {
7770         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7771                 skip "Need MDS version at least 2.12.52"
7772         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7773
7774         local f
7775
7776         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7777         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7778         for fail_loc in 0x80000188 0x80000189; do
7779                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7780                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7781                         error "mkdir $dir-$fail_loc failed"
7782                 for i in {0..10}; do
7783                         # create may fail on missing stripe
7784                         echo $i > $DIR/$tdir-$fail_loc/$i
7785                 done
7786                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7787                         error "getdirstripe $tdir-$fail_loc failed"
7788                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7789                         error "migrate $tdir-$fail_loc failed"
7790                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7791                         error "getdirstripe $tdir-$fail_loc failed"
7792                 pushd $DIR/$tdir-$fail_loc
7793                 for f in *; do
7794                         echo $f | cmp $f - || error "$f data mismatch"
7795                 done
7796                 popd
7797                 rm -rf $DIR/$tdir-$fail_loc
7798         done
7799 }
7800 run_test 60h "striped directory with missing stripes can be accessed"
7801
7802 test_61a() {
7803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7804
7805         f="$DIR/f61"
7806         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7807         cancel_lru_locks osc
7808         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7809         sync
7810 }
7811 run_test 61a "mmap() writes don't make sync hang ================"
7812
7813 test_61b() {
7814         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7815 }
7816 run_test 61b "mmap() of unstriped file is successful"
7817
7818 # bug 2330 - insufficient obd_match error checking causes LBUG
7819 test_62() {
7820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7821
7822         f="$DIR/f62"
7823         echo foo > $f
7824         cancel_lru_locks osc
7825         lctl set_param fail_loc=0x405
7826         cat $f && error "cat succeeded, expect -EIO"
7827         lctl set_param fail_loc=0
7828 }
7829 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7830 # match every page all of the time.
7831 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7832
7833 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7834 # Though this test is irrelevant anymore, it helped to reveal some
7835 # other grant bugs (LU-4482), let's keep it.
7836 test_63a() {   # was test_63
7837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7838
7839         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7840
7841         for i in `seq 10` ; do
7842                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7843                 sleep 5
7844                 kill $!
7845                 sleep 1
7846         done
7847
7848         rm -f $DIR/f63 || true
7849 }
7850 run_test 63a "Verify oig_wait interruption does not crash ======="
7851
7852 # bug 2248 - async write errors didn't return to application on sync
7853 # bug 3677 - async write errors left page locked
7854 test_63b() {
7855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7856
7857         debugsave
7858         lctl set_param debug=-1
7859
7860         # ensure we have a grant to do async writes
7861         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7862         rm $DIR/$tfile
7863
7864         sync    # sync lest earlier test intercept the fail_loc
7865
7866         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7867         lctl set_param fail_loc=0x80000406
7868         $MULTIOP $DIR/$tfile Owy && \
7869                 error "sync didn't return ENOMEM"
7870         sync; sleep 2; sync     # do a real sync this time to flush page
7871         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7872                 error "locked page left in cache after async error" || true
7873         debugrestore
7874 }
7875 run_test 63b "async write errors should be returned to fsync ==="
7876
7877 test_64a () {
7878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7879
7880         lfs df $DIR
7881         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7882 }
7883 run_test 64a "verify filter grant calculations (in kernel) ====="
7884
7885 test_64b () {
7886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7887
7888         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7889 }
7890 run_test 64b "check out-of-space detection on client"
7891
7892 test_64c() {
7893         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7894 }
7895 run_test 64c "verify grant shrink"
7896
7897 import_param() {
7898         local tgt=$1
7899         local param=$2
7900
7901         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7902 }
7903
7904 # this does exactly what osc_request.c:osc_announce_cached() does in
7905 # order to calculate max amount of grants to ask from server
7906 want_grant() {
7907         local tgt=$1
7908
7909         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7910         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7911
7912         ((rpc_in_flight++));
7913         nrpages=$((nrpages * rpc_in_flight))
7914
7915         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7916
7917         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7918
7919         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7920         local undirty=$((nrpages * PAGE_SIZE))
7921
7922         local max_extent_pages
7923         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7924         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7925         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7926         local grant_extent_tax
7927         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7928
7929         undirty=$((undirty + nrextents * grant_extent_tax))
7930
7931         echo $undirty
7932 }
7933
7934 # this is size of unit for grant allocation. It should be equal to
7935 # what tgt_grant.c:tgt_grant_chunk() calculates
7936 grant_chunk() {
7937         local tgt=$1
7938         local max_brw_size
7939         local grant_extent_tax
7940
7941         max_brw_size=$(import_param $tgt max_brw_size)
7942
7943         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7944
7945         echo $(((max_brw_size + grant_extent_tax) * 2))
7946 }
7947
7948 test_64d() {
7949         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7950                 skip "OST < 2.10.55 doesn't limit grants enough"
7951
7952         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7953
7954         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7955                 skip "no grant_param connect flag"
7956
7957         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7958
7959         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7960         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7961
7962
7963         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7964         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7965
7966         $LFS setstripe $DIR/$tfile -i 0 -c 1
7967         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7968         ddpid=$!
7969
7970         while kill -0 $ddpid; do
7971                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7972
7973                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7974                         kill $ddpid
7975                         error "cur_grant $cur_grant > $max_cur_granted"
7976                 fi
7977
7978                 sleep 1
7979         done
7980 }
7981 run_test 64d "check grant limit exceed"
7982
7983 check_grants() {
7984         local tgt=$1
7985         local expected=$2
7986         local msg=$3
7987         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7988
7989         ((cur_grants == expected)) ||
7990                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7991 }
7992
7993 round_up_p2() {
7994         echo $((($1 + $2 - 1) & ~($2 - 1)))
7995 }
7996
7997 test_64e() {
7998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7999         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8000                 skip "Need OSS version at least 2.11.56"
8001
8002         # Remount client to reset grant
8003         remount_client $MOUNT || error "failed to remount client"
8004         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8005
8006         local init_grants=$(import_param $osc_tgt initial_grant)
8007
8008         check_grants $osc_tgt $init_grants "init grants"
8009
8010         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8011         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8012         local gbs=$(import_param $osc_tgt grant_block_size)
8013
8014         # write random number of bytes from max_brw_size / 4 to max_brw_size
8015         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8016         # align for direct io
8017         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8018         # round to grant consumption unit
8019         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8020
8021         local grants=$((wb_round_up + extent_tax))
8022
8023         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8024
8025         # define OBD_FAIL_TGT_NO_GRANT 0x725
8026         # make the server not grant more back
8027         do_facet ost1 $LCTL set_param fail_loc=0x725
8028         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8029
8030         do_facet ost1 $LCTL set_param fail_loc=0
8031
8032         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8033
8034         rm -f $DIR/$tfile || error "rm failed"
8035
8036         # Remount client to reset grant
8037         remount_client $MOUNT || error "failed to remount client"
8038         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8039
8040         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8041
8042         # define OBD_FAIL_TGT_NO_GRANT 0x725
8043         # make the server not grant more back
8044         do_facet ost1 $LCTL set_param fail_loc=0x725
8045         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8046         do_facet ost1 $LCTL set_param fail_loc=0
8047
8048         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8049 }
8050 run_test 64e "check grant consumption (no grant allocation)"
8051
8052 test_64f() {
8053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8054
8055         # Remount client to reset grant
8056         remount_client $MOUNT || error "failed to remount client"
8057         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8058
8059         local init_grants=$(import_param $osc_tgt initial_grant)
8060         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8061         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8062         local gbs=$(import_param $osc_tgt grant_block_size)
8063         local chunk=$(grant_chunk $osc_tgt)
8064
8065         # write random number of bytes from max_brw_size / 4 to max_brw_size
8066         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8067         # align for direct io
8068         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8069         # round to grant consumption unit
8070         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8071
8072         local grants=$((wb_round_up + extent_tax))
8073
8074         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8075         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8076                 error "error writing to $DIR/$tfile"
8077
8078         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8079                 "direct io with grant allocation"
8080
8081         rm -f $DIR/$tfile || error "rm failed"
8082
8083         # Remount client to reset grant
8084         remount_client $MOUNT || error "failed to remount client"
8085         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8086
8087         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8088
8089         local cmd="oO_WRONLY:w${write_bytes}_yc"
8090
8091         $MULTIOP $DIR/$tfile $cmd &
8092         MULTIPID=$!
8093         sleep 1
8094
8095         check_grants $osc_tgt $((init_grants - grants)) \
8096                 "buffered io, not write rpc"
8097
8098         kill -USR1 $MULTIPID
8099         wait
8100
8101         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8102                 "buffered io, one RPC"
8103 }
8104 run_test 64f "check grant consumption (with grant allocation)"
8105
8106 # bug 1414 - set/get directories' stripe info
8107 test_65a() {
8108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8109
8110         test_mkdir $DIR/$tdir
8111         touch $DIR/$tdir/f1
8112         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8113 }
8114 run_test 65a "directory with no stripe info"
8115
8116 test_65b() {
8117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8118
8119         test_mkdir $DIR/$tdir
8120         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8121
8122         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8123                                                 error "setstripe"
8124         touch $DIR/$tdir/f2
8125         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8126 }
8127 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8128
8129 test_65c() {
8130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8131         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8132
8133         test_mkdir $DIR/$tdir
8134         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8135
8136         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8137                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8138         touch $DIR/$tdir/f3
8139         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8140 }
8141 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8142
8143 test_65d() {
8144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8145
8146         test_mkdir $DIR/$tdir
8147         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8148         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8149
8150         if [[ $STRIPECOUNT -le 0 ]]; then
8151                 sc=1
8152         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8153                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8154                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8155         else
8156                 sc=$(($STRIPECOUNT - 1))
8157         fi
8158         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8159         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8160         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8161                 error "lverify failed"
8162 }
8163 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8164
8165 test_65e() {
8166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8167
8168         test_mkdir $DIR/$tdir
8169
8170         $LFS setstripe $DIR/$tdir || error "setstripe"
8171         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8172                                         error "no stripe info failed"
8173         touch $DIR/$tdir/f6
8174         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8175 }
8176 run_test 65e "directory setstripe defaults"
8177
8178 test_65f() {
8179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8180
8181         test_mkdir $DIR/${tdir}f
8182         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8183                 error "setstripe succeeded" || true
8184 }
8185 run_test 65f "dir setstripe permission (should return error) ==="
8186
8187 test_65g() {
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         test_mkdir $DIR/$tdir
8191         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8192
8193         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8194                 error "setstripe -S failed"
8195         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8196         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8197                 error "delete default stripe failed"
8198 }
8199 run_test 65g "directory setstripe -d"
8200
8201 test_65h() {
8202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8203
8204         test_mkdir $DIR/$tdir
8205         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8206
8207         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8208                 error "setstripe -S failed"
8209         test_mkdir $DIR/$tdir/dd1
8210         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8211                 error "stripe info inherit failed"
8212 }
8213 run_test 65h "directory stripe info inherit ===================="
8214
8215 test_65i() {
8216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8217
8218         save_layout_restore_at_exit $MOUNT
8219
8220         # bug6367: set non-default striping on root directory
8221         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8222
8223         # bug12836: getstripe on -1 default directory striping
8224         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8225
8226         # bug12836: getstripe -v on -1 default directory striping
8227         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8228
8229         # bug12836: new find on -1 default directory striping
8230         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8231 }
8232 run_test 65i "various tests to set root directory striping"
8233
8234 test_65j() { # bug6367
8235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8236
8237         sync; sleep 1
8238
8239         # if we aren't already remounting for each test, do so for this test
8240         if [ "$I_MOUNTED" = "yes" ]; then
8241                 cleanup || error "failed to unmount"
8242                 setup
8243         fi
8244
8245         save_layout_restore_at_exit $MOUNT
8246
8247         $LFS setstripe -d $MOUNT || error "setstripe failed"
8248 }
8249 run_test 65j "set default striping on root directory (bug 6367)="
8250
8251 cleanup_65k() {
8252         rm -rf $DIR/$tdir
8253         wait_delete_completed
8254         do_facet $SINGLEMDS "lctl set_param -n \
8255                 osp.$ost*MDT0000.max_create_count=$max_count"
8256         do_facet $SINGLEMDS "lctl set_param -n \
8257                 osp.$ost*MDT0000.create_count=$count"
8258         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8259         echo $INACTIVE_OSC "is Activate"
8260
8261         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8262 }
8263
8264 test_65k() { # bug11679
8265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8266         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8267         remote_mds_nodsh && skip "remote MDS with nodsh"
8268
8269         local disable_precreate=true
8270         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8271                 disable_precreate=false
8272
8273         echo "Check OST status: "
8274         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8275                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8276
8277         for OSC in $MDS_OSCS; do
8278                 echo $OSC "is active"
8279                 do_facet $SINGLEMDS lctl --device %$OSC activate
8280         done
8281
8282         for INACTIVE_OSC in $MDS_OSCS; do
8283                 local ost=$(osc_to_ost $INACTIVE_OSC)
8284                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8285                                lov.*md*.target_obd |
8286                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8287
8288                 mkdir -p $DIR/$tdir
8289                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8290                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8291
8292                 echo "Deactivate: " $INACTIVE_OSC
8293                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8294
8295                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8296                               osp.$ost*MDT0000.create_count")
8297                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8298                                   osp.$ost*MDT0000.max_create_count")
8299                 $disable_precreate &&
8300                         do_facet $SINGLEMDS "lctl set_param -n \
8301                                 osp.$ost*MDT0000.max_create_count=0"
8302
8303                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8304                         [ -f $DIR/$tdir/$idx ] && continue
8305                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8306                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8307                                 { cleanup_65k;
8308                                   error "setstripe $idx should succeed"; }
8309                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8310                 done
8311                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8312                 rmdir $DIR/$tdir
8313
8314                 do_facet $SINGLEMDS "lctl set_param -n \
8315                         osp.$ost*MDT0000.max_create_count=$max_count"
8316                 do_facet $SINGLEMDS "lctl set_param -n \
8317                         osp.$ost*MDT0000.create_count=$count"
8318                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8319                 echo $INACTIVE_OSC "is Activate"
8320
8321                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8322         done
8323 }
8324 run_test 65k "validate manual striping works properly with deactivated OSCs"
8325
8326 test_65l() { # bug 12836
8327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8328
8329         test_mkdir -p $DIR/$tdir/test_dir
8330         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8331         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8332 }
8333 run_test 65l "lfs find on -1 stripe dir ========================"
8334
8335 test_65m() {
8336         local layout=$(save_layout $MOUNT)
8337         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8338                 restore_layout $MOUNT $layout
8339                 error "setstripe should fail by non-root users"
8340         }
8341         true
8342 }
8343 run_test 65m "normal user can't set filesystem default stripe"
8344
8345 test_65n() {
8346         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8347         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8348                 skip "Need MDS version at least 2.12.50"
8349         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8350
8351         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8352         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8353         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8354
8355         local root_layout=$(save_layout $MOUNT)
8356         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8357
8358         # new subdirectory under root directory should not inherit
8359         # the default layout from root
8360         local dir1=$MOUNT/$tdir-1
8361         mkdir $dir1 || error "mkdir $dir1 failed"
8362         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8363                 error "$dir1 shouldn't have LOV EA"
8364
8365         # delete the default layout on root directory
8366         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8367
8368         local dir2=$MOUNT/$tdir-2
8369         mkdir $dir2 || error "mkdir $dir2 failed"
8370         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8371                 error "$dir2 shouldn't have LOV EA"
8372
8373         # set a new striping pattern on root directory
8374         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8375         local new_def_stripe_size=$((def_stripe_size * 2))
8376         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8377                 error "set stripe size on $MOUNT failed"
8378
8379         # new file created in $dir2 should inherit the new stripe size from
8380         # the filesystem default
8381         local file2=$dir2/$tfile-2
8382         touch $file2 || error "touch $file2 failed"
8383
8384         local file2_stripe_size=$($LFS getstripe -S $file2)
8385         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8386                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8387
8388         local dir3=$MOUNT/$tdir-3
8389         mkdir $dir3 || error "mkdir $dir3 failed"
8390         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8391         # the root layout, which is the actual default layout that will be used
8392         # when new files are created in $dir3.
8393         local dir3_layout=$(get_layout_param $dir3)
8394         local root_dir_layout=$(get_layout_param $MOUNT)
8395         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8396                 error "$dir3 should show the default layout from $MOUNT"
8397
8398         # set OST pool on root directory
8399         local pool=$TESTNAME
8400         pool_add $pool || error "add $pool failed"
8401         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8402                 error "add targets to $pool failed"
8403
8404         $LFS setstripe -p $pool $MOUNT ||
8405                 error "set OST pool on $MOUNT failed"
8406
8407         # new file created in $dir3 should inherit the pool from
8408         # the filesystem default
8409         local file3=$dir3/$tfile-3
8410         touch $file3 || error "touch $file3 failed"
8411
8412         local file3_pool=$($LFS getstripe -p $file3)
8413         [[ "$file3_pool" = "$pool" ]] ||
8414                 error "$file3 didn't inherit OST pool $pool"
8415
8416         local dir4=$MOUNT/$tdir-4
8417         mkdir $dir4 || error "mkdir $dir4 failed"
8418         local dir4_layout=$(get_layout_param $dir4)
8419         root_dir_layout=$(get_layout_param $MOUNT)
8420         echo "$LFS getstripe -d $dir4"
8421         $LFS getstripe -d $dir4
8422         echo "$LFS getstripe -d $MOUNT"
8423         $LFS getstripe -d $MOUNT
8424         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8425                 error "$dir4 should show the default layout from $MOUNT"
8426
8427         # new file created in $dir4 should inherit the pool from
8428         # the filesystem default
8429         local file4=$dir4/$tfile-4
8430         touch $file4 || error "touch $file4 failed"
8431
8432         local file4_pool=$($LFS getstripe -p $file4)
8433         [[ "$file4_pool" = "$pool" ]] ||
8434                 error "$file4 didn't inherit OST pool $pool"
8435
8436         # new subdirectory under non-root directory should inherit
8437         # the default layout from its parent directory
8438         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8439                 error "set directory layout on $dir4 failed"
8440
8441         local dir5=$dir4/$tdir-5
8442         mkdir $dir5 || error "mkdir $dir5 failed"
8443
8444         dir4_layout=$(get_layout_param $dir4)
8445         local dir5_layout=$(get_layout_param $dir5)
8446         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8447                 error "$dir5 should inherit the default layout from $dir4"
8448
8449         # though subdir under ROOT doesn't inherit default layout, but
8450         # its sub dir/file should be created with default layout.
8451         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8452         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8453                 skip "Need MDS version at least 2.12.59"
8454
8455         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8456         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8457         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8458
8459         if [ $default_lmv_hash == "none" ]; then
8460                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8461         else
8462                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8463                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8464         fi
8465
8466         $LFS setdirstripe -D -c 2 $MOUNT ||
8467                 error "setdirstripe -D -c 2 failed"
8468         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8469         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8470         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8471 }
8472 run_test 65n "don't inherit default layout from root for new subdirectories"
8473
8474 # bug 2543 - update blocks count on client
8475 test_66() {
8476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8477
8478         COUNT=${COUNT:-8}
8479         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8480         sync; sync_all_data; sync; sync_all_data
8481         cancel_lru_locks osc
8482         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8483         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8484 }
8485 run_test 66 "update inode blocks count on client ==============="
8486
8487 meminfo() {
8488         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8489 }
8490
8491 swap_used() {
8492         swapon -s | awk '($1 == "'$1'") { print $4 }'
8493 }
8494
8495 # bug5265, obdfilter oa2dentry return -ENOENT
8496 # #define OBD_FAIL_SRV_ENOENT 0x217
8497 test_69() {
8498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8499         remote_ost_nodsh && skip "remote OST with nodsh"
8500
8501         f="$DIR/$tfile"
8502         $LFS setstripe -c 1 -i 0 $f
8503
8504         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8505
8506         do_facet ost1 lctl set_param fail_loc=0x217
8507         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8508         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8509
8510         do_facet ost1 lctl set_param fail_loc=0
8511         $DIRECTIO write $f 0 2 || error "write error"
8512
8513         cancel_lru_locks osc
8514         $DIRECTIO read $f 0 1 || error "read error"
8515
8516         do_facet ost1 lctl set_param fail_loc=0x217
8517         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8518
8519         do_facet ost1 lctl set_param fail_loc=0
8520         rm -f $f
8521 }
8522 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8523
8524 test_71() {
8525         test_mkdir $DIR/$tdir
8526         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8527         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8528 }
8529 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8530
8531 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8533         [ "$RUNAS_ID" = "$UID" ] &&
8534                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8535         # Check that testing environment is properly set up. Skip if not
8536         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8537                 skip_env "User $RUNAS_ID does not exist - skipping"
8538
8539         touch $DIR/$tfile
8540         chmod 777 $DIR/$tfile
8541         chmod ug+s $DIR/$tfile
8542         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8543                 error "$RUNAS dd $DIR/$tfile failed"
8544         # See if we are still setuid/sgid
8545         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8546                 error "S/gid is not dropped on write"
8547         # Now test that MDS is updated too
8548         cancel_lru_locks mdc
8549         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8550                 error "S/gid is not dropped on MDS"
8551         rm -f $DIR/$tfile
8552 }
8553 run_test 72a "Test that remove suid works properly (bug5695) ===="
8554
8555 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8556         local perm
8557
8558         [ "$RUNAS_ID" = "$UID" ] &&
8559                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8560         [ "$RUNAS_ID" -eq 0 ] &&
8561                 skip_env "RUNAS_ID = 0 -- skipping"
8562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8563         # Check that testing environment is properly set up. Skip if not
8564         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8565                 skip_env "User $RUNAS_ID does not exist - skipping"
8566
8567         touch $DIR/${tfile}-f{g,u}
8568         test_mkdir $DIR/${tfile}-dg
8569         test_mkdir $DIR/${tfile}-du
8570         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8571         chmod g+s $DIR/${tfile}-{f,d}g
8572         chmod u+s $DIR/${tfile}-{f,d}u
8573         for perm in 777 2777 4777; do
8574                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8575                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8576                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8577                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8578         done
8579         true
8580 }
8581 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8582
8583 # bug 3462 - multiple simultaneous MDC requests
8584 test_73() {
8585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8586
8587         test_mkdir $DIR/d73-1
8588         test_mkdir $DIR/d73-2
8589         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8590         pid1=$!
8591
8592         lctl set_param fail_loc=0x80000129
8593         $MULTIOP $DIR/d73-1/f73-2 Oc &
8594         sleep 1
8595         lctl set_param fail_loc=0
8596
8597         $MULTIOP $DIR/d73-2/f73-3 Oc &
8598         pid3=$!
8599
8600         kill -USR1 $pid1
8601         wait $pid1 || return 1
8602
8603         sleep 25
8604
8605         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8606         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8607         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8608
8609         rm -rf $DIR/d73-*
8610 }
8611 run_test 73 "multiple MDC requests (should not deadlock)"
8612
8613 test_74a() { # bug 6149, 6184
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         touch $DIR/f74a
8617         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8618         #
8619         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8620         # will spin in a tight reconnection loop
8621         $LCTL set_param fail_loc=0x8000030e
8622         # get any lock that won't be difficult - lookup works.
8623         ls $DIR/f74a
8624         $LCTL set_param fail_loc=0
8625         rm -f $DIR/f74a
8626         true
8627 }
8628 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8629
8630 test_74b() { # bug 13310
8631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8632
8633         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8634         #
8635         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8636         # will spin in a tight reconnection loop
8637         $LCTL set_param fail_loc=0x8000030e
8638         # get a "difficult" lock
8639         touch $DIR/f74b
8640         $LCTL set_param fail_loc=0
8641         rm -f $DIR/f74b
8642         true
8643 }
8644 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8645
8646 test_74c() {
8647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8648
8649         #define OBD_FAIL_LDLM_NEW_LOCK
8650         $LCTL set_param fail_loc=0x319
8651         touch $DIR/$tfile && error "touch successful"
8652         $LCTL set_param fail_loc=0
8653         true
8654 }
8655 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8656
8657 slab_lic=/sys/kernel/slab/lustre_inode_cache
8658 num_objects() {
8659         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8660         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8661                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8662 }
8663
8664 test_76a() { # Now for b=20433, added originally in b=1443
8665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8666
8667         cancel_lru_locks osc
8668         # there may be some slab objects cached per core
8669         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8670         local before=$(num_objects)
8671         local count=$((512 * cpus))
8672         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8673         local margin=$((count / 10))
8674         if [[ -f $slab_lic/aliases ]]; then
8675                 local aliases=$(cat $slab_lic/aliases)
8676                 (( aliases > 0 )) && margin=$((margin * aliases))
8677         fi
8678
8679         echo "before slab objects: $before"
8680         for i in $(seq $count); do
8681                 touch $DIR/$tfile
8682                 rm -f $DIR/$tfile
8683         done
8684         cancel_lru_locks osc
8685         local after=$(num_objects)
8686         echo "created: $count, after slab objects: $after"
8687         # shared slab counts are not very accurate, allow significant margin
8688         # the main goal is that the cache growth is not permanently > $count
8689         while (( after > before + margin )); do
8690                 sleep 1
8691                 after=$(num_objects)
8692                 wait=$((wait + 1))
8693                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8694                 if (( wait > 60 )); then
8695                         error "inode slab grew from $before+$margin to $after"
8696                 fi
8697         done
8698 }
8699 run_test 76a "confirm clients recycle inodes properly ===="
8700
8701 test_76b() {
8702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8703         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8704
8705         local count=512
8706         local before=$(num_objects)
8707
8708         for i in $(seq $count); do
8709                 mkdir $DIR/$tdir
8710                 rmdir $DIR/$tdir
8711         done
8712
8713         local after=$(num_objects)
8714         local wait=0
8715
8716         while (( after > before )); do
8717                 sleep 1
8718                 after=$(num_objects)
8719                 wait=$((wait + 1))
8720                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8721                 if (( wait > 60 )); then
8722                         error "inode slab grew from $before to $after"
8723                 fi
8724         done
8725
8726         echo "slab objects before: $before, after: $after"
8727 }
8728 run_test 76b "confirm clients recycle directory inodes properly ===="
8729
8730 export ORIG_CSUM=""
8731 set_checksums()
8732 {
8733         # Note: in sptlrpc modes which enable its own bulk checksum, the
8734         # original crc32_le bulk checksum will be automatically disabled,
8735         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8736         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8737         # In this case set_checksums() will not be no-op, because sptlrpc
8738         # bulk checksum will be enabled all through the test.
8739
8740         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8741         lctl set_param -n osc.*.checksums $1
8742         return 0
8743 }
8744
8745 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8746                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8747 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8748                              tr -d [] | head -n1)}
8749 set_checksum_type()
8750 {
8751         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8752         rc=$?
8753         log "set checksum type to $1, rc = $rc"
8754         return $rc
8755 }
8756
8757 get_osc_checksum_type()
8758 {
8759         # arugment 1: OST name, like OST0000
8760         ost=$1
8761         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8762                         sed 's/.*\[\(.*\)\].*/\1/g')
8763         rc=$?
8764         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8765         echo $checksum_type
8766 }
8767
8768 F77_TMP=$TMP/f77-temp
8769 F77SZ=8
8770 setup_f77() {
8771         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8772                 error "error writing to $F77_TMP"
8773 }
8774
8775 test_77a() { # bug 10889
8776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8777         $GSS && skip_env "could not run with gss"
8778
8779         [ ! -f $F77_TMP ] && setup_f77
8780         set_checksums 1
8781         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8782         set_checksums 0
8783         rm -f $DIR/$tfile
8784 }
8785 run_test 77a "normal checksum read/write operation"
8786
8787 test_77b() { # bug 10889
8788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8789         $GSS && skip_env "could not run with gss"
8790
8791         [ ! -f $F77_TMP ] && setup_f77
8792         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8793         $LCTL set_param fail_loc=0x80000409
8794         set_checksums 1
8795
8796         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8797                 error "dd error: $?"
8798         $LCTL set_param fail_loc=0
8799
8800         for algo in $CKSUM_TYPES; do
8801                 cancel_lru_locks osc
8802                 set_checksum_type $algo
8803                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8804                 $LCTL set_param fail_loc=0x80000408
8805                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8806                 $LCTL set_param fail_loc=0
8807         done
8808         set_checksums 0
8809         set_checksum_type $ORIG_CSUM_TYPE
8810         rm -f $DIR/$tfile
8811 }
8812 run_test 77b "checksum error on client write, read"
8813
8814 cleanup_77c() {
8815         trap 0
8816         set_checksums 0
8817         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8818         $check_ost &&
8819                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8820         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8821         $check_ost && [ -n "$ost_file_prefix" ] &&
8822                 do_facet ost1 rm -f ${ost_file_prefix}\*
8823 }
8824
8825 test_77c() {
8826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8827         $GSS && skip_env "could not run with gss"
8828         remote_ost_nodsh && skip "remote OST with nodsh"
8829
8830         local bad1
8831         local osc_file_prefix
8832         local osc_file
8833         local check_ost=false
8834         local ost_file_prefix
8835         local ost_file
8836         local orig_cksum
8837         local dump_cksum
8838         local fid
8839
8840         # ensure corruption will occur on first OSS/OST
8841         $LFS setstripe -i 0 $DIR/$tfile
8842
8843         [ ! -f $F77_TMP ] && setup_f77
8844         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8845                 error "dd write error: $?"
8846         fid=$($LFS path2fid $DIR/$tfile)
8847
8848         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8849         then
8850                 check_ost=true
8851                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8852                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8853         else
8854                 echo "OSS do not support bulk pages dump upon error"
8855         fi
8856
8857         osc_file_prefix=$($LCTL get_param -n debug_path)
8858         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8859
8860         trap cleanup_77c EXIT
8861
8862         set_checksums 1
8863         # enable bulk pages dump upon error on Client
8864         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8865         # enable bulk pages dump upon error on OSS
8866         $check_ost &&
8867                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8868
8869         # flush Client cache to allow next read to reach OSS
8870         cancel_lru_locks osc
8871
8872         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8873         $LCTL set_param fail_loc=0x80000408
8874         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8875         $LCTL set_param fail_loc=0
8876
8877         rm -f $DIR/$tfile
8878
8879         # check cksum dump on Client
8880         osc_file=$(ls ${osc_file_prefix}*)
8881         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8882         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8883         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8884         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8885         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8886                      cksum)
8887         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8888         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8889                 error "dump content does not match on Client"
8890
8891         $check_ost || skip "No need to check cksum dump on OSS"
8892
8893         # check cksum dump on OSS
8894         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8895         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8896         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8897         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8898         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8899                 error "dump content does not match on OSS"
8900
8901         cleanup_77c
8902 }
8903 run_test 77c "checksum error on client read with debug"
8904
8905 test_77d() { # bug 10889
8906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8907         $GSS && skip_env "could not run with gss"
8908
8909         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8910         $LCTL set_param fail_loc=0x80000409
8911         set_checksums 1
8912         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8913                 error "direct write: rc=$?"
8914         $LCTL set_param fail_loc=0
8915         set_checksums 0
8916
8917         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8918         $LCTL set_param fail_loc=0x80000408
8919         set_checksums 1
8920         cancel_lru_locks osc
8921         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8922                 error "direct read: rc=$?"
8923         $LCTL set_param fail_loc=0
8924         set_checksums 0
8925 }
8926 run_test 77d "checksum error on OST direct write, read"
8927
8928 test_77f() { # bug 10889
8929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8930         $GSS && skip_env "could not run with gss"
8931
8932         set_checksums 1
8933         for algo in $CKSUM_TYPES; do
8934                 cancel_lru_locks osc
8935                 set_checksum_type $algo
8936                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8937                 $LCTL set_param fail_loc=0x409
8938                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8939                         error "direct write succeeded"
8940                 $LCTL set_param fail_loc=0
8941         done
8942         set_checksum_type $ORIG_CSUM_TYPE
8943         set_checksums 0
8944 }
8945 run_test 77f "repeat checksum error on write (expect error)"
8946
8947 test_77g() { # bug 10889
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949         $GSS && skip_env "could not run with gss"
8950         remote_ost_nodsh && skip "remote OST with nodsh"
8951
8952         [ ! -f $F77_TMP ] && setup_f77
8953
8954         local file=$DIR/$tfile
8955         stack_trap "rm -f $file" EXIT
8956
8957         $LFS setstripe -c 1 -i 0 $file
8958         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8959         do_facet ost1 lctl set_param fail_loc=0x8000021a
8960         set_checksums 1
8961         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8962                 error "write error: rc=$?"
8963         do_facet ost1 lctl set_param fail_loc=0
8964         set_checksums 0
8965
8966         cancel_lru_locks osc
8967         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8968         do_facet ost1 lctl set_param fail_loc=0x8000021b
8969         set_checksums 1
8970         cmp $F77_TMP $file || error "file compare failed"
8971         do_facet ost1 lctl set_param fail_loc=0
8972         set_checksums 0
8973 }
8974 run_test 77g "checksum error on OST write, read"
8975
8976 test_77k() { # LU-10906
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8978         $GSS && skip_env "could not run with gss"
8979
8980         local cksum_param="osc.$FSNAME*.checksums"
8981         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8982         local checksum
8983         local i
8984
8985         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8986         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8987         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8988
8989         for i in 0 1; do
8990                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8991                         error "failed to set checksum=$i on MGS"
8992                 wait_update $HOSTNAME "$get_checksum" $i
8993                 #remount
8994                 echo "remount client, checksum should be $i"
8995                 remount_client $MOUNT || error "failed to remount client"
8996                 checksum=$(eval $get_checksum)
8997                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8998         done
8999         # remove persistent param to avoid races with checksum mountopt below
9000         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9001                 error "failed to delete checksum on MGS"
9002
9003         for opt in "checksum" "nochecksum"; do
9004                 #remount with mount option
9005                 echo "remount client with option $opt, checksum should be $i"
9006                 umount_client $MOUNT || error "failed to umount client"
9007                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9008                         error "failed to mount client with option '$opt'"
9009                 checksum=$(eval $get_checksum)
9010                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9011                 i=$((i - 1))
9012         done
9013
9014         remount_client $MOUNT || error "failed to remount client"
9015 }
9016 run_test 77k "enable/disable checksum correctly"
9017
9018 test_77l() {
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020         $GSS && skip_env "could not run with gss"
9021
9022         set_checksums 1
9023         stack_trap "set_checksums $ORIG_CSUM" EXIT
9024         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9025
9026         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9027
9028         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9029         for algo in $CKSUM_TYPES; do
9030                 set_checksum_type $algo || error "fail to set checksum type $algo"
9031                 osc_algo=$(get_osc_checksum_type OST0000)
9032                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9033
9034                 # no locks, no reqs to let the connection idle
9035                 cancel_lru_locks osc
9036                 lru_resize_disable osc
9037                 wait_osc_import_state client ost1 IDLE
9038
9039                 # ensure ost1 is connected
9040                 stat $DIR/$tfile >/dev/null || error "can't stat"
9041                 wait_osc_import_state client ost1 FULL
9042
9043                 osc_algo=$(get_osc_checksum_type OST0000)
9044                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9045         done
9046         return 0
9047 }
9048 run_test 77l "preferred checksum type is remembered after reconnected"
9049
9050 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9051 rm -f $F77_TMP
9052 unset F77_TMP
9053
9054 cleanup_test_78() {
9055         trap 0
9056         rm -f $DIR/$tfile
9057 }
9058
9059 test_78() { # bug 10901
9060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9061         remote_ost || skip_env "local OST"
9062
9063         NSEQ=5
9064         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9065         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9066         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9067         echo "MemTotal: $MEMTOTAL"
9068
9069         # reserve 256MB of memory for the kernel and other running processes,
9070         # and then take 1/2 of the remaining memory for the read/write buffers.
9071         if [ $MEMTOTAL -gt 512 ] ;then
9072                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9073         else
9074                 # for those poor memory-starved high-end clusters...
9075                 MEMTOTAL=$((MEMTOTAL / 2))
9076         fi
9077         echo "Mem to use for directio: $MEMTOTAL"
9078
9079         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9080         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9081         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9082         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9083                 head -n1)
9084         echo "Smallest OST: $SMALLESTOST"
9085         [[ $SMALLESTOST -lt 10240 ]] &&
9086                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9087
9088         trap cleanup_test_78 EXIT
9089
9090         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9091                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9092
9093         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9094         echo "File size: $F78SIZE"
9095         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9096         for i in $(seq 1 $NSEQ); do
9097                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9098                 echo directIO rdwr round $i of $NSEQ
9099                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9100         done
9101
9102         cleanup_test_78
9103 }
9104 run_test 78 "handle large O_DIRECT writes correctly ============"
9105
9106 test_79() { # bug 12743
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108
9109         wait_delete_completed
9110
9111         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9112         BKFREE=$(calc_osc_kbytes kbytesfree)
9113         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9114
9115         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9116         DFTOTAL=`echo $STRING | cut -d, -f1`
9117         DFUSED=`echo $STRING  | cut -d, -f2`
9118         DFAVAIL=`echo $STRING | cut -d, -f3`
9119         DFFREE=$(($DFTOTAL - $DFUSED))
9120
9121         ALLOWANCE=$((64 * $OSTCOUNT))
9122
9123         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9124            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9125                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9126         fi
9127         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9128            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9129                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9130         fi
9131         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9132            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9133                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9134         fi
9135 }
9136 run_test 79 "df report consistency check ======================="
9137
9138 test_80() { # bug 10718
9139         remote_ost_nodsh && skip "remote OST with nodsh"
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141
9142         # relax strong synchronous semantics for slow backends like ZFS
9143         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9144                 local soc="obdfilter.*.sync_lock_cancel"
9145                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9146
9147                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9148                 if [ -z "$save" ]; then
9149                         soc="obdfilter.*.sync_on_lock_cancel"
9150                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9151                 fi
9152
9153                 if [ "$save" != "never" ]; then
9154                         local hosts=$(comma_list $(osts_nodes))
9155
9156                         do_nodes $hosts $LCTL set_param $soc=never
9157                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9158                 fi
9159         fi
9160
9161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9162         sync; sleep 1; sync
9163         local before=$(date +%s)
9164         cancel_lru_locks osc
9165         local after=$(date +%s)
9166         local diff=$((after - before))
9167         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9168
9169         rm -f $DIR/$tfile
9170 }
9171 run_test 80 "Page eviction is equally fast at high offsets too"
9172
9173 test_81a() { # LU-456
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175         remote_ost_nodsh && skip "remote OST with nodsh"
9176
9177         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9178         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9179         do_facet ost1 lctl set_param fail_loc=0x80000228
9180
9181         # write should trigger a retry and success
9182         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9183         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9184         RC=$?
9185         if [ $RC -ne 0 ] ; then
9186                 error "write should success, but failed for $RC"
9187         fi
9188 }
9189 run_test 81a "OST should retry write when get -ENOSPC ==============="
9190
9191 test_81b() { # LU-456
9192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9193         remote_ost_nodsh && skip "remote OST with nodsh"
9194
9195         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9196         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9197         do_facet ost1 lctl set_param fail_loc=0x228
9198
9199         # write should retry several times and return -ENOSPC finally
9200         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9201         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9202         RC=$?
9203         ENOSPC=28
9204         if [ $RC -ne $ENOSPC ] ; then
9205                 error "dd should fail for -ENOSPC, but succeed."
9206         fi
9207 }
9208 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9209
9210 test_99() {
9211         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9212
9213         test_mkdir $DIR/$tdir.cvsroot
9214         chown $RUNAS_ID $DIR/$tdir.cvsroot
9215
9216         cd $TMP
9217         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9218
9219         cd /etc/init.d
9220         # some versions of cvs import exit(1) when asked to import links or
9221         # files they can't read.  ignore those files.
9222         local toignore=$(find . -type l -printf '-I %f\n' -o \
9223                          ! -perm /4 -printf '-I %f\n')
9224         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9225                 $tdir.reposname vtag rtag
9226
9227         cd $DIR
9228         test_mkdir $DIR/$tdir.reposname
9229         chown $RUNAS_ID $DIR/$tdir.reposname
9230         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9231
9232         cd $DIR/$tdir.reposname
9233         $RUNAS touch foo99
9234         $RUNAS cvs add -m 'addmsg' foo99
9235         $RUNAS cvs update
9236         $RUNAS cvs commit -m 'nomsg' foo99
9237         rm -fr $DIR/$tdir.cvsroot
9238 }
9239 run_test 99 "cvs strange file/directory operations"
9240
9241 test_100() {
9242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9243         [[ "$NETTYPE" =~ tcp ]] ||
9244                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9245         remote_ost_nodsh && skip "remote OST with nodsh"
9246         remote_mds_nodsh && skip "remote MDS with nodsh"
9247         remote_servers ||
9248                 skip "useless for local single node setup"
9249
9250         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9251                 [ "$PROT" != "tcp" ] && continue
9252                 RPORT=$(echo $REMOTE | cut -d: -f2)
9253                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9254
9255                 rc=0
9256                 LPORT=`echo $LOCAL | cut -d: -f2`
9257                 if [ $LPORT -ge 1024 ]; then
9258                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9259                         netstat -tna
9260                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9261                 fi
9262         done
9263         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9264 }
9265 run_test 100 "check local port using privileged port ==========="
9266
9267 function get_named_value()
9268 {
9269     local tag
9270
9271     tag=$1
9272     while read ;do
9273         line=$REPLY
9274         case $line in
9275         $tag*)
9276             echo $line | sed "s/^$tag[ ]*//"
9277             break
9278             ;;
9279         esac
9280     done
9281 }
9282
9283 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9284                    awk '/^max_cached_mb/ { print $2 }')
9285
9286 cleanup_101a() {
9287         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9288         trap 0
9289 }
9290
9291 test_101a() {
9292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9293
9294         local s
9295         local discard
9296         local nreads=10000
9297         local cache_limit=32
9298
9299         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9300         trap cleanup_101a EXIT
9301         $LCTL set_param -n llite.*.read_ahead_stats 0
9302         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9303
9304         #
9305         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9306         #
9307         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9308         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9309
9310         discard=0
9311         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9312                 get_named_value 'read but discarded' | cut -d" " -f1); do
9313                         discard=$(($discard + $s))
9314         done
9315         cleanup_101a
9316
9317         $LCTL get_param osc.*-osc*.rpc_stats
9318         $LCTL get_param llite.*.read_ahead_stats
9319
9320         # Discard is generally zero, but sometimes a few random reads line up
9321         # and trigger larger readahead, which is wasted & leads to discards.
9322         if [[ $(($discard)) -gt $nreads ]]; then
9323                 error "too many ($discard) discarded pages"
9324         fi
9325         rm -f $DIR/$tfile || true
9326 }
9327 run_test 101a "check read-ahead for random reads"
9328
9329 setup_test101bc() {
9330         test_mkdir $DIR/$tdir
9331         local ssize=$1
9332         local FILE_LENGTH=$2
9333         STRIPE_OFFSET=0
9334
9335         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9336
9337         local list=$(comma_list $(osts_nodes))
9338         set_osd_param $list '' read_cache_enable 0
9339         set_osd_param $list '' writethrough_cache_enable 0
9340
9341         trap cleanup_test101bc EXIT
9342         # prepare the read-ahead file
9343         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9344
9345         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9346                                 count=$FILE_SIZE_MB 2> /dev/null
9347
9348 }
9349
9350 cleanup_test101bc() {
9351         trap 0
9352         rm -rf $DIR/$tdir
9353         rm -f $DIR/$tfile
9354
9355         local list=$(comma_list $(osts_nodes))
9356         set_osd_param $list '' read_cache_enable 1
9357         set_osd_param $list '' writethrough_cache_enable 1
9358 }
9359
9360 calc_total() {
9361         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9362 }
9363
9364 ra_check_101() {
9365         local READ_SIZE=$1
9366         local STRIPE_SIZE=$2
9367         local FILE_LENGTH=$3
9368         local RA_INC=1048576
9369         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9370         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9371                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9372         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9373                         get_named_value 'read but discarded' |
9374                         cut -d" " -f1 | calc_total)
9375         if [[ $DISCARD -gt $discard_limit ]]; then
9376                 $LCTL get_param llite.*.read_ahead_stats
9377                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9378         else
9379                 echo "Read-ahead success for size ${READ_SIZE}"
9380         fi
9381 }
9382
9383 test_101b() {
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9386
9387         local STRIPE_SIZE=1048576
9388         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9389
9390         if [ $SLOW == "yes" ]; then
9391                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9392         else
9393                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9394         fi
9395
9396         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9397
9398         # prepare the read-ahead file
9399         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9400         cancel_lru_locks osc
9401         for BIDX in 2 4 8 16 32 64 128 256
9402         do
9403                 local BSIZE=$((BIDX*4096))
9404                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9405                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9406                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9407                 $LCTL set_param -n llite.*.read_ahead_stats 0
9408                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9409                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9410                 cancel_lru_locks osc
9411                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9412         done
9413         cleanup_test101bc
9414         true
9415 }
9416 run_test 101b "check stride-io mode read-ahead ================="
9417
9418 test_101c() {
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420
9421         local STRIPE_SIZE=1048576
9422         local FILE_LENGTH=$((STRIPE_SIZE*100))
9423         local nreads=10000
9424         local rsize=65536
9425         local osc_rpc_stats
9426
9427         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9428
9429         cancel_lru_locks osc
9430         $LCTL set_param osc.*.rpc_stats 0
9431         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9432         $LCTL get_param osc.*.rpc_stats
9433         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9434                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9435                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9436                 local size
9437
9438                 if [ $lines -le 20 ]; then
9439                         echo "continue debug"
9440                         continue
9441                 fi
9442                 for size in 1 2 4 8; do
9443                         local rpc=$(echo "$stats" |
9444                                     awk '($1 == "'$size':") {print $2; exit; }')
9445                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9446                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9447                 done
9448                 echo "$osc_rpc_stats check passed!"
9449         done
9450         cleanup_test101bc
9451         true
9452 }
9453 run_test 101c "check stripe_size aligned read-ahead ================="
9454
9455 test_101d() {
9456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9457
9458         local file=$DIR/$tfile
9459         local sz_MB=${FILESIZE_101d:-80}
9460         local ra_MB=${READAHEAD_MB:-40}
9461
9462         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9463         [ $free_MB -lt $sz_MB ] &&
9464                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9465
9466         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9467         $LFS setstripe -c -1 $file || error "setstripe failed"
9468
9469         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9470         echo Cancel LRU locks on lustre client to flush the client cache
9471         cancel_lru_locks osc
9472
9473         echo Disable read-ahead
9474         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9475         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9476         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9477         $LCTL get_param -n llite.*.max_read_ahead_mb
9478
9479         echo "Reading the test file $file with read-ahead disabled"
9480         local sz_KB=$((sz_MB * 1024 / 4))
9481         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9482         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9483         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9484                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9485
9486         echo "Cancel LRU locks on lustre client to flush the client cache"
9487         cancel_lru_locks osc
9488         echo Enable read-ahead with ${ra_MB}MB
9489         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9490
9491         echo "Reading the test file $file with read-ahead enabled"
9492         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9493                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9494
9495         echo "read-ahead disabled time read $raOFF"
9496         echo "read-ahead enabled time read $raON"
9497
9498         rm -f $file
9499         wait_delete_completed
9500
9501         # use awk for this check instead of bash because it handles decimals
9502         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9503                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9504 }
9505 run_test 101d "file read with and without read-ahead enabled"
9506
9507 test_101e() {
9508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9509
9510         local file=$DIR/$tfile
9511         local size_KB=500  #KB
9512         local count=100
9513         local bsize=1024
9514
9515         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9516         local need_KB=$((count * size_KB))
9517         [[ $free_KB -le $need_KB ]] &&
9518                 skip_env "Need free space $need_KB, have $free_KB"
9519
9520         echo "Creating $count ${size_KB}K test files"
9521         for ((i = 0; i < $count; i++)); do
9522                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9523         done
9524
9525         echo "Cancel LRU locks on lustre client to flush the client cache"
9526         cancel_lru_locks $OSC
9527
9528         echo "Reset readahead stats"
9529         $LCTL set_param -n llite.*.read_ahead_stats 0
9530
9531         for ((i = 0; i < $count; i++)); do
9532                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9533         done
9534
9535         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9536                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9537
9538         for ((i = 0; i < $count; i++)); do
9539                 rm -rf $file.$i 2>/dev/null
9540         done
9541
9542         #10000 means 20% reads are missing in readahead
9543         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9544 }
9545 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9546
9547 test_101f() {
9548         which iozone || skip_env "no iozone installed"
9549
9550         local old_debug=$($LCTL get_param debug)
9551         old_debug=${old_debug#*=}
9552         $LCTL set_param debug="reada mmap"
9553
9554         # create a test file
9555         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9556
9557         echo Cancel LRU locks on lustre client to flush the client cache
9558         cancel_lru_locks osc
9559
9560         echo Reset readahead stats
9561         $LCTL set_param -n llite.*.read_ahead_stats 0
9562
9563         echo mmap read the file with small block size
9564         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9565                 > /dev/null 2>&1
9566
9567         echo checking missing pages
9568         $LCTL get_param llite.*.read_ahead_stats
9569         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9570                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9571
9572         $LCTL set_param debug="$old_debug"
9573         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9574         rm -f $DIR/$tfile
9575 }
9576 run_test 101f "check mmap read performance"
9577
9578 test_101g_brw_size_test() {
9579         local mb=$1
9580         local pages=$((mb * 1048576 / PAGE_SIZE))
9581         local file=$DIR/$tfile
9582
9583         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9584                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9585         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9586                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9587                         return 2
9588         done
9589
9590         stack_trap "rm -f $file" EXIT
9591         $LCTL set_param -n osc.*.rpc_stats=0
9592
9593         # 10 RPCs should be enough for the test
9594         local count=10
9595         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9596                 { error "dd write ${mb} MB blocks failed"; return 3; }
9597         cancel_lru_locks osc
9598         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9599                 { error "dd write ${mb} MB blocks failed"; return 4; }
9600
9601         # calculate number of full-sized read and write RPCs
9602         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9603                 sed -n '/pages per rpc/,/^$/p' |
9604                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9605                 END { print reads,writes }'))
9606         # allow one extra full-sized read RPC for async readahead
9607         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9608                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9609         [[ ${rpcs[1]} == $count ]] ||
9610                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9611 }
9612
9613 test_101g() {
9614         remote_ost_nodsh && skip "remote OST with nodsh"
9615
9616         local rpcs
9617         local osts=$(get_facets OST)
9618         local list=$(comma_list $(osts_nodes))
9619         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9620         local brw_size="obdfilter.*.brw_size"
9621
9622         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9623
9624         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9625
9626         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9627                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9628                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9629            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9630                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9631                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9632
9633                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9634                         suffix="M"
9635
9636                 if [[ $orig_mb -lt 16 ]]; then
9637                         save_lustre_params $osts "$brw_size" > $p
9638                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9639                                 error "set 16MB RPC size failed"
9640
9641                         echo "remount client to enable new RPC size"
9642                         remount_client $MOUNT || error "remount_client failed"
9643                 fi
9644
9645                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9646                 # should be able to set brw_size=12, but no rpc_stats for that
9647                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9648         fi
9649
9650         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9651
9652         if [[ $orig_mb -lt 16 ]]; then
9653                 restore_lustre_params < $p
9654                 remount_client $MOUNT || error "remount_client restore failed"
9655         fi
9656
9657         rm -f $p $DIR/$tfile
9658 }
9659 run_test 101g "Big bulk(4/16 MiB) readahead"
9660
9661 test_101h() {
9662         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9663
9664         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9665                 error "dd 70M file failed"
9666         echo Cancel LRU locks on lustre client to flush the client cache
9667         cancel_lru_locks osc
9668
9669         echo "Reset readahead stats"
9670         $LCTL set_param -n llite.*.read_ahead_stats 0
9671
9672         echo "Read 10M of data but cross 64M bundary"
9673         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9674         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9675                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9676         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9677         rm -f $p $DIR/$tfile
9678 }
9679 run_test 101h "Readahead should cover current read window"
9680
9681 test_101i() {
9682         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9683                 error "dd 10M file failed"
9684
9685         local max_per_file_mb=$($LCTL get_param -n \
9686                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9687         cancel_lru_locks osc
9688         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9689         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9690                 error "set max_read_ahead_per_file_mb to 1 failed"
9691
9692         echo "Reset readahead stats"
9693         $LCTL set_param llite.*.read_ahead_stats=0
9694
9695         dd if=$DIR/$tfile of=/dev/null bs=2M
9696
9697         $LCTL get_param llite.*.read_ahead_stats
9698         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9699                      awk '/misses/ { print $2 }')
9700         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9701         rm -f $DIR/$tfile
9702 }
9703 run_test 101i "allow current readahead to exceed reservation"
9704
9705 test_101j() {
9706         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9707                 error "setstripe $DIR/$tfile failed"
9708         local file_size=$((1048576 * 16))
9709         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9710         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9711
9712         echo Disable read-ahead
9713         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9714
9715         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9716         for blk in $PAGE_SIZE 1048576 $file_size; do
9717                 cancel_lru_locks osc
9718                 echo "Reset readahead stats"
9719                 $LCTL set_param -n llite.*.read_ahead_stats=0
9720                 local count=$(($file_size / $blk))
9721                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9722                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9723                              get_named_value 'failed to fast read' |
9724                              cut -d" " -f1 | calc_total)
9725                 $LCTL get_param -n llite.*.read_ahead_stats
9726                 [ $miss -eq $count ] || error "expected $count got $miss"
9727         done
9728
9729         rm -f $p $DIR/$tfile
9730 }
9731 run_test 101j "A complete read block should be submitted when no RA"
9732
9733 setup_test102() {
9734         test_mkdir $DIR/$tdir
9735         chown $RUNAS_ID $DIR/$tdir
9736         STRIPE_SIZE=65536
9737         STRIPE_OFFSET=1
9738         STRIPE_COUNT=$OSTCOUNT
9739         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9740
9741         trap cleanup_test102 EXIT
9742         cd $DIR
9743         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9744         cd $DIR/$tdir
9745         for num in 1 2 3 4; do
9746                 for count in $(seq 1 $STRIPE_COUNT); do
9747                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9748                                 local size=`expr $STRIPE_SIZE \* $num`
9749                                 local file=file"$num-$idx-$count"
9750                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9751                         done
9752                 done
9753         done
9754
9755         cd $DIR
9756         $1 tar cf $TMP/f102.tar $tdir --xattrs
9757 }
9758
9759 cleanup_test102() {
9760         trap 0
9761         rm -f $TMP/f102.tar
9762         rm -rf $DIR/d0.sanity/d102
9763 }
9764
9765 test_102a() {
9766         [ "$UID" != 0 ] && skip "must run as root"
9767         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9768                 skip_env "must have user_xattr"
9769
9770         [ -z "$(which setfattr 2>/dev/null)" ] &&
9771                 skip_env "could not find setfattr"
9772
9773         local testfile=$DIR/$tfile
9774
9775         touch $testfile
9776         echo "set/get xattr..."
9777         setfattr -n trusted.name1 -v value1 $testfile ||
9778                 error "setfattr -n trusted.name1=value1 $testfile failed"
9779         getfattr -n trusted.name1 $testfile 2> /dev/null |
9780           grep "trusted.name1=.value1" ||
9781                 error "$testfile missing trusted.name1=value1"
9782
9783         setfattr -n user.author1 -v author1 $testfile ||
9784                 error "setfattr -n user.author1=author1 $testfile failed"
9785         getfattr -n user.author1 $testfile 2> /dev/null |
9786           grep "user.author1=.author1" ||
9787                 error "$testfile missing trusted.author1=author1"
9788
9789         echo "listxattr..."
9790         setfattr -n trusted.name2 -v value2 $testfile ||
9791                 error "$testfile unable to set trusted.name2"
9792         setfattr -n trusted.name3 -v value3 $testfile ||
9793                 error "$testfile unable to set trusted.name3"
9794         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9795             grep "trusted.name" | wc -l) -eq 3 ] ||
9796                 error "$testfile missing 3 trusted.name xattrs"
9797
9798         setfattr -n user.author2 -v author2 $testfile ||
9799                 error "$testfile unable to set user.author2"
9800         setfattr -n user.author3 -v author3 $testfile ||
9801                 error "$testfile unable to set user.author3"
9802         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9803             grep "user.author" | wc -l) -eq 3 ] ||
9804                 error "$testfile missing 3 user.author xattrs"
9805
9806         echo "remove xattr..."
9807         setfattr -x trusted.name1 $testfile ||
9808                 error "$testfile error deleting trusted.name1"
9809         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9810                 error "$testfile did not delete trusted.name1 xattr"
9811
9812         setfattr -x user.author1 $testfile ||
9813                 error "$testfile error deleting user.author1"
9814         echo "set lustre special xattr ..."
9815         $LFS setstripe -c1 $testfile
9816         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9817                 awk -F "=" '/trusted.lov/ { print $2 }' )
9818         setfattr -n "trusted.lov" -v $lovea $testfile ||
9819                 error "$testfile doesn't ignore setting trusted.lov again"
9820         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9821                 error "$testfile allow setting invalid trusted.lov"
9822         rm -f $testfile
9823 }
9824 run_test 102a "user xattr test =================================="
9825
9826 check_102b_layout() {
9827         local layout="$*"
9828         local testfile=$DIR/$tfile
9829
9830         echo "test layout '$layout'"
9831         $LFS setstripe $layout $testfile || error "setstripe failed"
9832         $LFS getstripe -y $testfile
9833
9834         echo "get/set/list trusted.lov xattr ..." # b=10930
9835         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9836         [[ "$value" =~ "trusted.lov" ]] ||
9837                 error "can't get trusted.lov from $testfile"
9838         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9839                 error "getstripe failed"
9840
9841         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9842
9843         value=$(cut -d= -f2 <<<$value)
9844         # LU-13168: truncated xattr should fail if short lov_user_md header
9845         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9846                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9847         for len in $lens; do
9848                 echo "setfattr $len $testfile.2"
9849                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9850                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9851         done
9852         local stripe_size=$($LFS getstripe -S $testfile.2)
9853         local stripe_count=$($LFS getstripe -c $testfile.2)
9854         [[ $stripe_size -eq 65536 ]] ||
9855                 error "stripe size $stripe_size != 65536"
9856         [[ $stripe_count -eq $stripe_count_orig ]] ||
9857                 error "stripe count $stripe_count != $stripe_count_orig"
9858         rm $testfile $testfile.2
9859 }
9860
9861 test_102b() {
9862         [ -z "$(which setfattr 2>/dev/null)" ] &&
9863                 skip_env "could not find setfattr"
9864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9865
9866         # check plain layout
9867         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9868
9869         # and also check composite layout
9870         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9871
9872 }
9873 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9874
9875 test_102c() {
9876         [ -z "$(which setfattr 2>/dev/null)" ] &&
9877                 skip_env "could not find setfattr"
9878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9879
9880         # b10930: get/set/list lustre.lov xattr
9881         echo "get/set/list lustre.lov xattr ..."
9882         test_mkdir $DIR/$tdir
9883         chown $RUNAS_ID $DIR/$tdir
9884         local testfile=$DIR/$tdir/$tfile
9885         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9886                 error "setstripe failed"
9887         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9888                 error "getstripe failed"
9889         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9890         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9891
9892         local testfile2=${testfile}2
9893         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9894                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9895
9896         $RUNAS $MCREATE $testfile2
9897         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9898         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9899         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9900         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9901         [ $stripe_count -eq $STRIPECOUNT ] ||
9902                 error "stripe count $stripe_count != $STRIPECOUNT"
9903 }
9904 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9905
9906 compare_stripe_info1() {
9907         local stripe_index_all_zero=true
9908
9909         for num in 1 2 3 4; do
9910                 for count in $(seq 1 $STRIPE_COUNT); do
9911                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9912                                 local size=$((STRIPE_SIZE * num))
9913                                 local file=file"$num-$offset-$count"
9914                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9915                                 [[ $stripe_size -ne $size ]] &&
9916                                     error "$file: size $stripe_size != $size"
9917                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9918                                 # allow fewer stripes to be created, ORI-601
9919                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9920                                     error "$file: count $stripe_count != $count"
9921                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9922                                 [[ $stripe_index -ne 0 ]] &&
9923                                         stripe_index_all_zero=false
9924                         done
9925                 done
9926         done
9927         $stripe_index_all_zero &&
9928                 error "all files are being extracted starting from OST index 0"
9929         return 0
9930 }
9931
9932 have_xattrs_include() {
9933         tar --help | grep -q xattrs-include &&
9934                 echo --xattrs-include="lustre.*"
9935 }
9936
9937 test_102d() {
9938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9939         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9940
9941         XINC=$(have_xattrs_include)
9942         setup_test102
9943         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9944         cd $DIR/$tdir/$tdir
9945         compare_stripe_info1
9946 }
9947 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9948
9949 test_102f() {
9950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9951         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9952
9953         XINC=$(have_xattrs_include)
9954         setup_test102
9955         test_mkdir $DIR/$tdir.restore
9956         cd $DIR
9957         tar cf - --xattrs $tdir | tar xf - \
9958                 -C $DIR/$tdir.restore --xattrs $XINC
9959         cd $DIR/$tdir.restore/$tdir
9960         compare_stripe_info1
9961 }
9962 run_test 102f "tar copy files, not keep osts"
9963
9964 grow_xattr() {
9965         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9966                 skip "must have user_xattr"
9967         [ -z "$(which setfattr 2>/dev/null)" ] &&
9968                 skip_env "could not find setfattr"
9969         [ -z "$(which getfattr 2>/dev/null)" ] &&
9970                 skip_env "could not find getfattr"
9971
9972         local xsize=${1:-1024}  # in bytes
9973         local file=$DIR/$tfile
9974         local value="$(generate_string $xsize)"
9975         local xbig=trusted.big
9976         local toobig=$2
9977
9978         touch $file
9979         log "save $xbig on $file"
9980         if [ -z "$toobig" ]
9981         then
9982                 setfattr -n $xbig -v $value $file ||
9983                         error "saving $xbig on $file failed"
9984         else
9985                 setfattr -n $xbig -v $value $file &&
9986                         error "saving $xbig on $file succeeded"
9987                 return 0
9988         fi
9989
9990         local orig=$(get_xattr_value $xbig $file)
9991         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9992
9993         local xsml=trusted.sml
9994         log "save $xsml on $file"
9995         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9996
9997         local new=$(get_xattr_value $xbig $file)
9998         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9999
10000         log "grow $xsml on $file"
10001         setfattr -n $xsml -v "$value" $file ||
10002                 error "growing $xsml on $file failed"
10003
10004         new=$(get_xattr_value $xbig $file)
10005         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10006         log "$xbig still valid after growing $xsml"
10007
10008         rm -f $file
10009 }
10010
10011 test_102h() { # bug 15777
10012         grow_xattr 1024
10013 }
10014 run_test 102h "grow xattr from inside inode to external block"
10015
10016 test_102ha() {
10017         large_xattr_enabled || skip_env "ea_inode feature disabled"
10018
10019         echo "setting xattr of max xattr size: $(max_xattr_size)"
10020         grow_xattr $(max_xattr_size)
10021
10022         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10023         echo "This should fail:"
10024         grow_xattr $(($(max_xattr_size) + 10)) 1
10025 }
10026 run_test 102ha "grow xattr from inside inode to external inode"
10027
10028 test_102i() { # bug 17038
10029         [ -z "$(which getfattr 2>/dev/null)" ] &&
10030                 skip "could not find getfattr"
10031
10032         touch $DIR/$tfile
10033         ln -s $DIR/$tfile $DIR/${tfile}link
10034         getfattr -n trusted.lov $DIR/$tfile ||
10035                 error "lgetxattr on $DIR/$tfile failed"
10036         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10037                 grep -i "no such attr" ||
10038                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10039         rm -f $DIR/$tfile $DIR/${tfile}link
10040 }
10041 run_test 102i "lgetxattr test on symbolic link ============"
10042
10043 test_102j() {
10044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10045         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10046
10047         XINC=$(have_xattrs_include)
10048         setup_test102 "$RUNAS"
10049         chown $RUNAS_ID $DIR/$tdir
10050         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10051         cd $DIR/$tdir/$tdir
10052         compare_stripe_info1 "$RUNAS"
10053 }
10054 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10055
10056 test_102k() {
10057         [ -z "$(which setfattr 2>/dev/null)" ] &&
10058                 skip "could not find setfattr"
10059
10060         touch $DIR/$tfile
10061         # b22187 just check that does not crash for regular file.
10062         setfattr -n trusted.lov $DIR/$tfile
10063         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10064         local test_kdir=$DIR/$tdir
10065         test_mkdir $test_kdir
10066         local default_size=$($LFS getstripe -S $test_kdir)
10067         local default_count=$($LFS getstripe -c $test_kdir)
10068         local default_offset=$($LFS getstripe -i $test_kdir)
10069         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10070                 error 'dir setstripe failed'
10071         setfattr -n trusted.lov $test_kdir
10072         local stripe_size=$($LFS getstripe -S $test_kdir)
10073         local stripe_count=$($LFS getstripe -c $test_kdir)
10074         local stripe_offset=$($LFS getstripe -i $test_kdir)
10075         [ $stripe_size -eq $default_size ] ||
10076                 error "stripe size $stripe_size != $default_size"
10077         [ $stripe_count -eq $default_count ] ||
10078                 error "stripe count $stripe_count != $default_count"
10079         [ $stripe_offset -eq $default_offset ] ||
10080                 error "stripe offset $stripe_offset != $default_offset"
10081         rm -rf $DIR/$tfile $test_kdir
10082 }
10083 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10084
10085 test_102l() {
10086         [ -z "$(which getfattr 2>/dev/null)" ] &&
10087                 skip "could not find getfattr"
10088
10089         # LU-532 trusted. xattr is invisible to non-root
10090         local testfile=$DIR/$tfile
10091
10092         touch $testfile
10093
10094         echo "listxattr as user..."
10095         chown $RUNAS_ID $testfile
10096         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10097             grep -q "trusted" &&
10098                 error "$testfile trusted xattrs are user visible"
10099
10100         return 0;
10101 }
10102 run_test 102l "listxattr size test =================================="
10103
10104 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10105         local path=$DIR/$tfile
10106         touch $path
10107
10108         listxattr_size_check $path || error "listattr_size_check $path failed"
10109 }
10110 run_test 102m "Ensure listxattr fails on small bufffer ========"
10111
10112 cleanup_test102
10113
10114 getxattr() { # getxattr path name
10115         # Return the base64 encoding of the value of xattr name on path.
10116         local path=$1
10117         local name=$2
10118
10119         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10120         # file: $path
10121         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10122         #
10123         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10124
10125         getfattr --absolute-names --encoding=base64 --name=$name $path |
10126                 awk -F= -v name=$name '$1 == name {
10127                         print substr($0, index($0, "=") + 1);
10128         }'
10129 }
10130
10131 test_102n() { # LU-4101 mdt: protect internal xattrs
10132         [ -z "$(which setfattr 2>/dev/null)" ] &&
10133                 skip "could not find setfattr"
10134         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10135         then
10136                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10137         fi
10138
10139         local file0=$DIR/$tfile.0
10140         local file1=$DIR/$tfile.1
10141         local xattr0=$TMP/$tfile.0
10142         local xattr1=$TMP/$tfile.1
10143         local namelist="lov lma lmv link fid version som hsm"
10144         local name
10145         local value
10146
10147         rm -rf $file0 $file1 $xattr0 $xattr1
10148         touch $file0 $file1
10149
10150         # Get 'before' xattrs of $file1.
10151         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10152
10153         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10154                 namelist+=" lfsck_namespace"
10155         for name in $namelist; do
10156                 # Try to copy xattr from $file0 to $file1.
10157                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10158
10159                 setfattr --name=trusted.$name --value="$value" $file1 ||
10160                         error "setxattr 'trusted.$name' failed"
10161
10162                 # Try to set a garbage xattr.
10163                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10164
10165                 if [[ x$name == "xlov" ]]; then
10166                         setfattr --name=trusted.lov --value="$value" $file1 &&
10167                         error "setxattr invalid 'trusted.lov' success"
10168                 else
10169                         setfattr --name=trusted.$name --value="$value" $file1 ||
10170                                 error "setxattr invalid 'trusted.$name' failed"
10171                 fi
10172
10173                 # Try to remove the xattr from $file1. We don't care if this
10174                 # appears to succeed or fail, we just don't want there to be
10175                 # any changes or crashes.
10176                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10177         done
10178
10179         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10180         then
10181                 name="lfsck_ns"
10182                 # Try to copy xattr from $file0 to $file1.
10183                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10184
10185                 setfattr --name=trusted.$name --value="$value" $file1 ||
10186                         error "setxattr 'trusted.$name' failed"
10187
10188                 # Try to set a garbage xattr.
10189                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10190
10191                 setfattr --name=trusted.$name --value="$value" $file1 ||
10192                         error "setxattr 'trusted.$name' failed"
10193
10194                 # Try to remove the xattr from $file1. We don't care if this
10195                 # appears to succeed or fail, we just don't want there to be
10196                 # any changes or crashes.
10197                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10198         fi
10199
10200         # Get 'after' xattrs of file1.
10201         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10202
10203         if ! diff $xattr0 $xattr1; then
10204                 error "before and after xattrs of '$file1' differ"
10205         fi
10206
10207         rm -rf $file0 $file1 $xattr0 $xattr1
10208
10209         return 0
10210 }
10211 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10212
10213 test_102p() { # LU-4703 setxattr did not check ownership
10214         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10215                 skip "MDS needs to be at least 2.5.56"
10216
10217         local testfile=$DIR/$tfile
10218
10219         touch $testfile
10220
10221         echo "setfacl as user..."
10222         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10223         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10224
10225         echo "setfattr as user..."
10226         setfacl -m "u:$RUNAS_ID:---" $testfile
10227         $RUNAS setfattr -x system.posix_acl_access $testfile
10228         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10229 }
10230 run_test 102p "check setxattr(2) correctly fails without permission"
10231
10232 test_102q() {
10233         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10234                 skip "MDS needs to be at least 2.6.92"
10235
10236         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10237 }
10238 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10239
10240 test_102r() {
10241         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10242                 skip "MDS needs to be at least 2.6.93"
10243
10244         touch $DIR/$tfile || error "touch"
10245         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10246         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10247         rm $DIR/$tfile || error "rm"
10248
10249         #normal directory
10250         mkdir -p $DIR/$tdir || error "mkdir"
10251         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10252         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10253         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10254                 error "$testfile error deleting user.author1"
10255         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10256                 grep "user.$(basename $tdir)" &&
10257                 error "$tdir did not delete user.$(basename $tdir)"
10258         rmdir $DIR/$tdir || error "rmdir"
10259
10260         #striped directory
10261         test_mkdir $DIR/$tdir
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 "rm striped dir"
10270 }
10271 run_test 102r "set EAs with empty values"
10272
10273 test_102s() {
10274         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10275                 skip "MDS needs to be at least 2.11.52"
10276
10277         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10278
10279         save_lustre_params client "llite.*.xattr_cache" > $save
10280
10281         for cache in 0 1; do
10282                 lctl set_param llite.*.xattr_cache=$cache
10283
10284                 rm -f $DIR/$tfile
10285                 touch $DIR/$tfile || error "touch"
10286                 for prefix in lustre security system trusted user; do
10287                         # Note getxattr() may fail with 'Operation not
10288                         # supported' or 'No such attribute' depending
10289                         # on prefix and cache.
10290                         getfattr -n $prefix.n102s $DIR/$tfile &&
10291                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10292                 done
10293         done
10294
10295         restore_lustre_params < $save
10296 }
10297 run_test 102s "getting nonexistent xattrs should fail"
10298
10299 test_102t() {
10300         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10301                 skip "MDS needs to be at least 2.11.52"
10302
10303         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10304
10305         save_lustre_params client "llite.*.xattr_cache" > $save
10306
10307         for cache in 0 1; do
10308                 lctl set_param llite.*.xattr_cache=$cache
10309
10310                 for buf_size in 0 256; do
10311                         rm -f $DIR/$tfile
10312                         touch $DIR/$tfile || error "touch"
10313                         setfattr -n user.multiop $DIR/$tfile
10314                         $MULTIOP $DIR/$tfile oa$buf_size ||
10315                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10316                 done
10317         done
10318
10319         restore_lustre_params < $save
10320 }
10321 run_test 102t "zero length xattr values handled correctly"
10322
10323 run_acl_subtest()
10324 {
10325     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10326     return $?
10327 }
10328
10329 test_103a() {
10330         [ "$UID" != 0 ] && skip "must run as root"
10331         $GSS && skip_env "could not run under gss"
10332         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10333                 skip_env "must have acl enabled"
10334         [ -z "$(which setfacl 2>/dev/null)" ] &&
10335                 skip_env "could not find setfacl"
10336         remote_mds_nodsh && skip "remote MDS with nodsh"
10337
10338         gpasswd -a daemon bin                           # LU-5641
10339         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10340
10341         declare -a identity_old
10342
10343         for num in $(seq $MDSCOUNT); do
10344                 switch_identity $num true || identity_old[$num]=$?
10345         done
10346
10347         SAVE_UMASK=$(umask)
10348         umask 0022
10349         mkdir -p $DIR/$tdir
10350         cd $DIR/$tdir
10351
10352         echo "performing cp ..."
10353         run_acl_subtest cp || error "run_acl_subtest cp failed"
10354         echo "performing getfacl-noacl..."
10355         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10356         echo "performing misc..."
10357         run_acl_subtest misc || error  "misc test failed"
10358         echo "performing permissions..."
10359         run_acl_subtest permissions || error "permissions failed"
10360         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10361         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10362                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10363                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10364         then
10365                 echo "performing permissions xattr..."
10366                 run_acl_subtest permissions_xattr ||
10367                         error "permissions_xattr failed"
10368         fi
10369         echo "performing setfacl..."
10370         run_acl_subtest setfacl || error  "setfacl test failed"
10371
10372         # inheritance test got from HP
10373         echo "performing inheritance..."
10374         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10375         chmod +x make-tree || error "chmod +x failed"
10376         run_acl_subtest inheritance || error "inheritance test failed"
10377         rm -f make-tree
10378
10379         echo "LU-974 ignore umask when acl is enabled..."
10380         run_acl_subtest 974 || error "LU-974 umask test failed"
10381         if [ $MDSCOUNT -ge 2 ]; then
10382                 run_acl_subtest 974_remote ||
10383                         error "LU-974 umask test failed under remote dir"
10384         fi
10385
10386         echo "LU-2561 newly created file is same size as directory..."
10387         if [ "$mds1_FSTYPE" != "zfs" ]; then
10388                 run_acl_subtest 2561 || error "LU-2561 test failed"
10389         else
10390                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10391         fi
10392
10393         run_acl_subtest 4924 || error "LU-4924 test failed"
10394
10395         cd $SAVE_PWD
10396         umask $SAVE_UMASK
10397
10398         for num in $(seq $MDSCOUNT); do
10399                 if [ "${identity_old[$num]}" = 1 ]; then
10400                         switch_identity $num false || identity_old[$num]=$?
10401                 fi
10402         done
10403 }
10404 run_test 103a "acl test"
10405
10406 test_103b() {
10407         declare -a pids
10408         local U
10409
10410         for U in {0..511}; do
10411                 {
10412                 local O=$(printf "%04o" $U)
10413
10414                 umask $(printf "%04o" $((511 ^ $O)))
10415                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10416                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10417
10418                 (( $S == ($O & 0666) )) ||
10419                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10420
10421                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10422                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10423                 (( $S == ($O & 0666) )) ||
10424                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10425
10426                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10427                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10428                 (( $S == ($O & 0666) )) ||
10429                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10430                 rm -f $DIR/$tfile.[smp]$0
10431                 } &
10432                 local pid=$!
10433
10434                 # limit the concurrently running threads to 64. LU-11878
10435                 local idx=$((U % 64))
10436                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10437                 pids[idx]=$pid
10438         done
10439         wait
10440 }
10441 run_test 103b "umask lfs setstripe"
10442
10443 test_103c() {
10444         mkdir -p $DIR/$tdir
10445         cp -rp $DIR/$tdir $DIR/$tdir.bak
10446
10447         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10448                 error "$DIR/$tdir shouldn't contain default ACL"
10449         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10450                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10451         true
10452 }
10453 run_test 103c "'cp -rp' won't set empty acl"
10454
10455 test_104a() {
10456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10457
10458         touch $DIR/$tfile
10459         lfs df || error "lfs df failed"
10460         lfs df -ih || error "lfs df -ih failed"
10461         lfs df -h $DIR || error "lfs df -h $DIR failed"
10462         lfs df -i $DIR || error "lfs df -i $DIR failed"
10463         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10464         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10465
10466         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10467         lctl --device %$OSC deactivate
10468         lfs df || error "lfs df with deactivated OSC failed"
10469         lctl --device %$OSC activate
10470         # wait the osc back to normal
10471         wait_osc_import_ready client ost
10472
10473         lfs df || error "lfs df with reactivated OSC failed"
10474         rm -f $DIR/$tfile
10475 }
10476 run_test 104a "lfs df [-ih] [path] test ========================="
10477
10478 test_104b() {
10479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10480         [ $RUNAS_ID -eq $UID ] &&
10481                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10482
10483         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10484                         grep "Permission denied" | wc -l)))
10485         if [ $denied_cnt -ne 0 ]; then
10486                 error "lfs check servers test failed"
10487         fi
10488 }
10489 run_test 104b "$RUNAS lfs check servers test ===================="
10490
10491 test_105a() {
10492         # doesn't work on 2.4 kernels
10493         touch $DIR/$tfile
10494         if $(flock_is_enabled); then
10495                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10496         else
10497                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10498         fi
10499         rm -f $DIR/$tfile
10500 }
10501 run_test 105a "flock when mounted without -o flock test ========"
10502
10503 test_105b() {
10504         touch $DIR/$tfile
10505         if $(flock_is_enabled); then
10506                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10507         else
10508                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10509         fi
10510         rm -f $DIR/$tfile
10511 }
10512 run_test 105b "fcntl when mounted without -o flock test ========"
10513
10514 test_105c() {
10515         touch $DIR/$tfile
10516         if $(flock_is_enabled); then
10517                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10518         else
10519                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10520         fi
10521         rm -f $DIR/$tfile
10522 }
10523 run_test 105c "lockf when mounted without -o flock test"
10524
10525 test_105d() { # bug 15924
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527
10528         test_mkdir $DIR/$tdir
10529         flock_is_enabled || skip_env "mount w/o flock enabled"
10530         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10531         $LCTL set_param fail_loc=0x80000315
10532         flocks_test 2 $DIR/$tdir
10533 }
10534 run_test 105d "flock race (should not freeze) ========"
10535
10536 test_105e() { # bug 22660 && 22040
10537         flock_is_enabled || skip_env "mount w/o flock enabled"
10538
10539         touch $DIR/$tfile
10540         flocks_test 3 $DIR/$tfile
10541 }
10542 run_test 105e "Two conflicting flocks from same process"
10543
10544 test_106() { #bug 10921
10545         test_mkdir $DIR/$tdir
10546         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10547         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10548 }
10549 run_test 106 "attempt exec of dir followed by chown of that dir"
10550
10551 test_107() {
10552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10553
10554         CDIR=`pwd`
10555         local file=core
10556
10557         cd $DIR
10558         rm -f $file
10559
10560         local save_pattern=$(sysctl -n kernel.core_pattern)
10561         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10562         sysctl -w kernel.core_pattern=$file
10563         sysctl -w kernel.core_uses_pid=0
10564
10565         ulimit -c unlimited
10566         sleep 60 &
10567         SLEEPPID=$!
10568
10569         sleep 1
10570
10571         kill -s 11 $SLEEPPID
10572         wait $SLEEPPID
10573         if [ -e $file ]; then
10574                 size=`stat -c%s $file`
10575                 [ $size -eq 0 ] && error "Fail to create core file $file"
10576         else
10577                 error "Fail to create core file $file"
10578         fi
10579         rm -f $file
10580         sysctl -w kernel.core_pattern=$save_pattern
10581         sysctl -w kernel.core_uses_pid=$save_uses_pid
10582         cd $CDIR
10583 }
10584 run_test 107 "Coredump on SIG"
10585
10586 test_110() {
10587         test_mkdir $DIR/$tdir
10588         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10589         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10590                 error "mkdir with 256 char should fail, but did not"
10591         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10592                 error "create with 255 char failed"
10593         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10594                 error "create with 256 char should fail, but did not"
10595
10596         ls -l $DIR/$tdir
10597         rm -rf $DIR/$tdir
10598 }
10599 run_test 110 "filename length checking"
10600
10601 #
10602 # Purpose: To verify dynamic thread (OSS) creation.
10603 #
10604 test_115() {
10605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10606         remote_ost_nodsh && skip "remote OST with nodsh"
10607
10608         # Lustre does not stop service threads once they are started.
10609         # Reset number of running threads to default.
10610         stopall
10611         setupall
10612
10613         local OSTIO_pre
10614         local save_params="$TMP/sanity-$TESTNAME.parameters"
10615
10616         # Get ll_ost_io count before I/O
10617         OSTIO_pre=$(do_facet ost1 \
10618                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10619         # Exit if lustre is not running (ll_ost_io not running).
10620         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10621
10622         echo "Starting with $OSTIO_pre threads"
10623         local thread_max=$((OSTIO_pre * 2))
10624         local rpc_in_flight=$((thread_max * 2))
10625         # Number of I/O Process proposed to be started.
10626         local nfiles
10627         local facets=$(get_facets OST)
10628
10629         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10630         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10631
10632         # Set in_flight to $rpc_in_flight
10633         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10634                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10635         nfiles=${rpc_in_flight}
10636         # Set ost thread_max to $thread_max
10637         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10638
10639         # 5 Minutes should be sufficient for max number of OSS
10640         # threads(thread_max) to be created.
10641         local timeout=300
10642
10643         # Start I/O.
10644         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10645         test_mkdir $DIR/$tdir
10646         for i in $(seq $nfiles); do
10647                 local file=$DIR/$tdir/${tfile}-$i
10648                 $LFS setstripe -c -1 -i 0 $file
10649                 ($WTL $file $timeout)&
10650         done
10651
10652         # I/O Started - Wait for thread_started to reach thread_max or report
10653         # error if thread_started is more than thread_max.
10654         echo "Waiting for thread_started to reach thread_max"
10655         local thread_started=0
10656         local end_time=$((SECONDS + timeout))
10657
10658         while [ $SECONDS -le $end_time ] ; do
10659                 echo -n "."
10660                 # Get ost i/o thread_started count.
10661                 thread_started=$(do_facet ost1 \
10662                         "$LCTL get_param \
10663                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10664                 # Break out if thread_started is equal/greater than thread_max
10665                 if [[ $thread_started -ge $thread_max ]]; then
10666                         echo ll_ost_io thread_started $thread_started, \
10667                                 equal/greater than thread_max $thread_max
10668                         break
10669                 fi
10670                 sleep 1
10671         done
10672
10673         # Cleanup - We have the numbers, Kill i/o jobs if running.
10674         jobcount=($(jobs -p))
10675         for i in $(seq 0 $((${#jobcount[@]}-1)))
10676         do
10677                 kill -9 ${jobcount[$i]}
10678                 if [ $? -ne 0 ] ; then
10679                         echo Warning: \
10680                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10681                 fi
10682         done
10683
10684         # Cleanup files left by WTL binary.
10685         for i in $(seq $nfiles); do
10686                 local file=$DIR/$tdir/${tfile}-$i
10687                 rm -rf $file
10688                 if [ $? -ne 0 ] ; then
10689                         echo "Warning: Failed to delete file $file"
10690                 fi
10691         done
10692
10693         restore_lustre_params <$save_params
10694         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10695
10696         # Error out if no new thread has started or Thread started is greater
10697         # than thread max.
10698         if [[ $thread_started -le $OSTIO_pre ||
10699                         $thread_started -gt $thread_max ]]; then
10700                 error "ll_ost_io: thread_started $thread_started" \
10701                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10702                       "No new thread started or thread started greater " \
10703                       "than thread_max."
10704         fi
10705 }
10706 run_test 115 "verify dynamic thread creation===================="
10707
10708 free_min_max () {
10709         wait_delete_completed
10710         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10711         echo "OST kbytes available: ${AVAIL[@]}"
10712         MAXV=${AVAIL[0]}
10713         MAXI=0
10714         MINV=${AVAIL[0]}
10715         MINI=0
10716         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10717                 #echo OST $i: ${AVAIL[i]}kb
10718                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10719                         MAXV=${AVAIL[i]}
10720                         MAXI=$i
10721                 fi
10722                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10723                         MINV=${AVAIL[i]}
10724                         MINI=$i
10725                 fi
10726         done
10727         echo "Min free space: OST $MINI: $MINV"
10728         echo "Max free space: OST $MAXI: $MAXV"
10729 }
10730
10731 test_116a() { # was previously test_116()
10732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10734         remote_mds_nodsh && skip "remote MDS with nodsh"
10735
10736         echo -n "Free space priority "
10737         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10738                 head -n1
10739         declare -a AVAIL
10740         free_min_max
10741
10742         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10743         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10744         trap simple_cleanup_common EXIT
10745
10746         # Check if we need to generate uneven OSTs
10747         test_mkdir -p $DIR/$tdir/OST${MINI}
10748         local FILL=$((MINV / 4))
10749         local DIFF=$((MAXV - MINV))
10750         local DIFF2=$((DIFF * 100 / MINV))
10751
10752         local threshold=$(do_facet $SINGLEMDS \
10753                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10754         threshold=${threshold%%%}
10755         echo -n "Check for uneven OSTs: "
10756         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10757
10758         if [[ $DIFF2 -gt $threshold ]]; then
10759                 echo "ok"
10760                 echo "Don't need to fill OST$MINI"
10761         else
10762                 # generate uneven OSTs. Write 2% over the QOS threshold value
10763                 echo "no"
10764                 DIFF=$((threshold - DIFF2 + 2))
10765                 DIFF2=$((MINV * DIFF / 100))
10766                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10767                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10768                         error "setstripe failed"
10769                 DIFF=$((DIFF2 / 2048))
10770                 i=0
10771                 while [ $i -lt $DIFF ]; do
10772                         i=$((i + 1))
10773                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10774                                 bs=2M count=1 2>/dev/null
10775                         echo -n .
10776                 done
10777                 echo .
10778                 sync
10779                 sleep_maxage
10780                 free_min_max
10781         fi
10782
10783         DIFF=$((MAXV - MINV))
10784         DIFF2=$((DIFF * 100 / MINV))
10785         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10786         if [ $DIFF2 -gt $threshold ]; then
10787                 echo "ok"
10788         else
10789                 echo "failed - QOS mode won't be used"
10790                 simple_cleanup_common
10791                 skip "QOS imbalance criteria not met"
10792         fi
10793
10794         MINI1=$MINI
10795         MINV1=$MINV
10796         MAXI1=$MAXI
10797         MAXV1=$MAXV
10798
10799         # now fill using QOS
10800         $LFS setstripe -c 1 $DIR/$tdir
10801         FILL=$((FILL / 200))
10802         if [ $FILL -gt 600 ]; then
10803                 FILL=600
10804         fi
10805         echo "writing $FILL files to QOS-assigned OSTs"
10806         i=0
10807         while [ $i -lt $FILL ]; do
10808                 i=$((i + 1))
10809                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10810                         count=1 2>/dev/null
10811                 echo -n .
10812         done
10813         echo "wrote $i 200k files"
10814         sync
10815         sleep_maxage
10816
10817         echo "Note: free space may not be updated, so measurements might be off"
10818         free_min_max
10819         DIFF2=$((MAXV - MINV))
10820         echo "free space delta: orig $DIFF final $DIFF2"
10821         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10822         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10823         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10824         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10825         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10826         if [[ $DIFF -gt 0 ]]; then
10827                 FILL=$((DIFF2 * 100 / DIFF - 100))
10828                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10829         fi
10830
10831         # Figure out which files were written where
10832         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10833                awk '/'$MINI1': / {print $2; exit}')
10834         echo $UUID
10835         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10836         echo "$MINC files created on smaller OST $MINI1"
10837         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10838                awk '/'$MAXI1': / {print $2; exit}')
10839         echo $UUID
10840         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10841         echo "$MAXC files created on larger OST $MAXI1"
10842         if [[ $MINC -gt 0 ]]; then
10843                 FILL=$((MAXC * 100 / MINC - 100))
10844                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10845         fi
10846         [[ $MAXC -gt $MINC ]] ||
10847                 error_ignore LU-9 "stripe QOS didn't balance free space"
10848         simple_cleanup_common
10849 }
10850 run_test 116a "stripe QOS: free space balance ==================="
10851
10852 test_116b() { # LU-2093
10853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10854         remote_mds_nodsh && skip "remote MDS with nodsh"
10855
10856 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10857         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10858                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10859         [ -z "$old_rr" ] && skip "no QOS"
10860         do_facet $SINGLEMDS lctl set_param \
10861                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10862         mkdir -p $DIR/$tdir
10863         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10864         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10865         do_facet $SINGLEMDS lctl set_param fail_loc=0
10866         rm -rf $DIR/$tdir
10867         do_facet $SINGLEMDS lctl set_param \
10868                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10869 }
10870 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10871
10872 test_117() # bug 10891
10873 {
10874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10875
10876         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10877         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10878         lctl set_param fail_loc=0x21e
10879         > $DIR/$tfile || error "truncate failed"
10880         lctl set_param fail_loc=0
10881         echo "Truncate succeeded."
10882         rm -f $DIR/$tfile
10883 }
10884 run_test 117 "verify osd extend =========="
10885
10886 NO_SLOW_RESENDCOUNT=4
10887 export OLD_RESENDCOUNT=""
10888 set_resend_count () {
10889         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10890         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10891         lctl set_param -n $PROC_RESENDCOUNT $1
10892         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10893 }
10894
10895 # for reduce test_118* time (b=14842)
10896 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10897
10898 # Reset async IO behavior after error case
10899 reset_async() {
10900         FILE=$DIR/reset_async
10901
10902         # Ensure all OSCs are cleared
10903         $LFS setstripe -c -1 $FILE
10904         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10905         sync
10906         rm $FILE
10907 }
10908
10909 test_118a() #bug 11710
10910 {
10911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10912
10913         reset_async
10914
10915         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10916         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10917         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10918
10919         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10920                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10921                 return 1;
10922         fi
10923         rm -f $DIR/$tfile
10924 }
10925 run_test 118a "verify O_SYNC works =========="
10926
10927 test_118b()
10928 {
10929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10930         remote_ost_nodsh && skip "remote OST with nodsh"
10931
10932         reset_async
10933
10934         #define OBD_FAIL_SRV_ENOENT 0x217
10935         set_nodes_failloc "$(osts_nodes)" 0x217
10936         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10937         RC=$?
10938         set_nodes_failloc "$(osts_nodes)" 0
10939         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10940         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10941                     grep -c writeback)
10942
10943         if [[ $RC -eq 0 ]]; then
10944                 error "Must return error due to dropped pages, rc=$RC"
10945                 return 1;
10946         fi
10947
10948         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10949                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10950                 return 1;
10951         fi
10952
10953         echo "Dirty pages not leaked on ENOENT"
10954
10955         # Due to the above error the OSC will issue all RPCs syncronously
10956         # until a subsequent RPC completes successfully without error.
10957         $MULTIOP $DIR/$tfile Ow4096yc
10958         rm -f $DIR/$tfile
10959
10960         return 0
10961 }
10962 run_test 118b "Reclaim dirty pages on fatal error =========="
10963
10964 test_118c()
10965 {
10966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10967
10968         # for 118c, restore the original resend count, LU-1940
10969         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10970                                 set_resend_count $OLD_RESENDCOUNT
10971         remote_ost_nodsh && skip "remote OST with nodsh"
10972
10973         reset_async
10974
10975         #define OBD_FAIL_OST_EROFS               0x216
10976         set_nodes_failloc "$(osts_nodes)" 0x216
10977
10978         # multiop should block due to fsync until pages are written
10979         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10980         MULTIPID=$!
10981         sleep 1
10982
10983         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10984                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10985         fi
10986
10987         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10988                     grep -c writeback)
10989         if [[ $WRITEBACK -eq 0 ]]; then
10990                 error "No page in writeback, writeback=$WRITEBACK"
10991         fi
10992
10993         set_nodes_failloc "$(osts_nodes)" 0
10994         wait $MULTIPID
10995         RC=$?
10996         if [[ $RC -ne 0 ]]; then
10997                 error "Multiop fsync failed, rc=$RC"
10998         fi
10999
11000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11002                     grep -c writeback)
11003         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11004                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11005         fi
11006
11007         rm -f $DIR/$tfile
11008         echo "Dirty pages flushed via fsync on EROFS"
11009         return 0
11010 }
11011 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11012
11013 # continue to use small resend count to reduce test_118* time (b=14842)
11014 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11015
11016 test_118d()
11017 {
11018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11019         remote_ost_nodsh && skip "remote OST with nodsh"
11020
11021         reset_async
11022
11023         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11024         set_nodes_failloc "$(osts_nodes)" 0x214
11025         # multiop should block due to fsync until pages are written
11026         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11027         MULTIPID=$!
11028         sleep 1
11029
11030         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11031                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11032         fi
11033
11034         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11035                     grep -c writeback)
11036         if [[ $WRITEBACK -eq 0 ]]; then
11037                 error "No page in writeback, writeback=$WRITEBACK"
11038         fi
11039
11040         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11041         set_nodes_failloc "$(osts_nodes)" 0
11042
11043         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11044         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11045                     grep -c writeback)
11046         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11047                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11048         fi
11049
11050         rm -f $DIR/$tfile
11051         echo "Dirty pages gaurenteed flushed via fsync"
11052         return 0
11053 }
11054 run_test 118d "Fsync validation inject a delay of the bulk =========="
11055
11056 test_118f() {
11057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11058
11059         reset_async
11060
11061         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11062         lctl set_param fail_loc=0x8000040a
11063
11064         # Should simulate EINVAL error which is fatal
11065         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11066         RC=$?
11067         if [[ $RC -eq 0 ]]; then
11068                 error "Must return error due to dropped pages, rc=$RC"
11069         fi
11070
11071         lctl set_param fail_loc=0x0
11072
11073         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11074         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11075         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11076                     grep -c writeback)
11077         if [[ $LOCKED -ne 0 ]]; then
11078                 error "Locked pages remain in cache, locked=$LOCKED"
11079         fi
11080
11081         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11082                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11083         fi
11084
11085         rm -f $DIR/$tfile
11086         echo "No pages locked after fsync"
11087
11088         reset_async
11089         return 0
11090 }
11091 run_test 118f "Simulate unrecoverable OSC side error =========="
11092
11093 test_118g() {
11094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11095
11096         reset_async
11097
11098         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11099         lctl set_param fail_loc=0x406
11100
11101         # simulate local -ENOMEM
11102         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11103         RC=$?
11104
11105         lctl set_param fail_loc=0
11106         if [[ $RC -eq 0 ]]; then
11107                 error "Must return error due to dropped pages, rc=$RC"
11108         fi
11109
11110         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11111         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11112         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11113                         grep -c writeback)
11114         if [[ $LOCKED -ne 0 ]]; then
11115                 error "Locked pages remain in cache, locked=$LOCKED"
11116         fi
11117
11118         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11119                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11120         fi
11121
11122         rm -f $DIR/$tfile
11123         echo "No pages locked after fsync"
11124
11125         reset_async
11126         return 0
11127 }
11128 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11129
11130 test_118h() {
11131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11132         remote_ost_nodsh && skip "remote OST with nodsh"
11133
11134         reset_async
11135
11136         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11137         set_nodes_failloc "$(osts_nodes)" 0x20e
11138         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11139         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11140         RC=$?
11141
11142         set_nodes_failloc "$(osts_nodes)" 0
11143         if [[ $RC -eq 0 ]]; then
11144                 error "Must return error due to dropped pages, rc=$RC"
11145         fi
11146
11147         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11148         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11149         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11150                     grep -c writeback)
11151         if [[ $LOCKED -ne 0 ]]; then
11152                 error "Locked pages remain in cache, locked=$LOCKED"
11153         fi
11154
11155         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11156                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11157         fi
11158
11159         rm -f $DIR/$tfile
11160         echo "No pages locked after fsync"
11161
11162         return 0
11163 }
11164 run_test 118h "Verify timeout in handling recoverables errors  =========="
11165
11166 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11167
11168 test_118i() {
11169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11170         remote_ost_nodsh && skip "remote OST with nodsh"
11171
11172         reset_async
11173
11174         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11175         set_nodes_failloc "$(osts_nodes)" 0x20e
11176
11177         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11178         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11179         PID=$!
11180         sleep 5
11181         set_nodes_failloc "$(osts_nodes)" 0
11182
11183         wait $PID
11184         RC=$?
11185         if [[ $RC -ne 0 ]]; then
11186                 error "got error, but should be not, rc=$RC"
11187         fi
11188
11189         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11190         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11191         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11192         if [[ $LOCKED -ne 0 ]]; then
11193                 error "Locked pages remain in cache, locked=$LOCKED"
11194         fi
11195
11196         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11197                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11198         fi
11199
11200         rm -f $DIR/$tfile
11201         echo "No pages locked after fsync"
11202
11203         return 0
11204 }
11205 run_test 118i "Fix error before timeout in recoverable error  =========="
11206
11207 [ "$SLOW" = "no" ] && set_resend_count 4
11208
11209 test_118j() {
11210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11211         remote_ost_nodsh && skip "remote OST with nodsh"
11212
11213         reset_async
11214
11215         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11216         set_nodes_failloc "$(osts_nodes)" 0x220
11217
11218         # return -EIO from OST
11219         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11220         RC=$?
11221         set_nodes_failloc "$(osts_nodes)" 0x0
11222         if [[ $RC -eq 0 ]]; then
11223                 error "Must return error due to dropped pages, rc=$RC"
11224         fi
11225
11226         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11227         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11228         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11229         if [[ $LOCKED -ne 0 ]]; then
11230                 error "Locked pages remain in cache, locked=$LOCKED"
11231         fi
11232
11233         # in recoverable error on OST we want resend and stay until it finished
11234         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11235                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11236         fi
11237
11238         rm -f $DIR/$tfile
11239         echo "No pages locked after fsync"
11240
11241         return 0
11242 }
11243 run_test 118j "Simulate unrecoverable OST side error =========="
11244
11245 test_118k()
11246 {
11247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11248         remote_ost_nodsh && skip "remote OSTs with nodsh"
11249
11250         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11251         set_nodes_failloc "$(osts_nodes)" 0x20e
11252         test_mkdir $DIR/$tdir
11253
11254         for ((i=0;i<10;i++)); do
11255                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11256                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11257                 SLEEPPID=$!
11258                 sleep 0.500s
11259                 kill $SLEEPPID
11260                 wait $SLEEPPID
11261         done
11262
11263         set_nodes_failloc "$(osts_nodes)" 0
11264         rm -rf $DIR/$tdir
11265 }
11266 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11267
11268 test_118l() # LU-646
11269 {
11270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11271
11272         test_mkdir $DIR/$tdir
11273         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11274         rm -rf $DIR/$tdir
11275 }
11276 run_test 118l "fsync dir"
11277
11278 test_118m() # LU-3066
11279 {
11280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11281
11282         test_mkdir $DIR/$tdir
11283         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11284         rm -rf $DIR/$tdir
11285 }
11286 run_test 118m "fdatasync dir ========="
11287
11288 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11289
11290 test_118n()
11291 {
11292         local begin
11293         local end
11294
11295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11296         remote_ost_nodsh && skip "remote OSTs with nodsh"
11297
11298         # Sleep to avoid a cached response.
11299         #define OBD_STATFS_CACHE_SECONDS 1
11300         sleep 2
11301
11302         # Inject a 10 second delay in the OST_STATFS handler.
11303         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11304         set_nodes_failloc "$(osts_nodes)" 0x242
11305
11306         begin=$SECONDS
11307         stat --file-system $MOUNT > /dev/null
11308         end=$SECONDS
11309
11310         set_nodes_failloc "$(osts_nodes)" 0
11311
11312         if ((end - begin > 20)); then
11313             error "statfs took $((end - begin)) seconds, expected 10"
11314         fi
11315 }
11316 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11317
11318 test_119a() # bug 11737
11319 {
11320         BSIZE=$((512 * 1024))
11321         directio write $DIR/$tfile 0 1 $BSIZE
11322         # We ask to read two blocks, which is more than a file size.
11323         # directio will indicate an error when requested and actual
11324         # sizes aren't equeal (a normal situation in this case) and
11325         # print actual read amount.
11326         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11327         if [ "$NOB" != "$BSIZE" ]; then
11328                 error "read $NOB bytes instead of $BSIZE"
11329         fi
11330         rm -f $DIR/$tfile
11331 }
11332 run_test 119a "Short directIO read must return actual read amount"
11333
11334 test_119b() # bug 11737
11335 {
11336         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11337
11338         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11339         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11340         sync
11341         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11342                 error "direct read failed"
11343         rm -f $DIR/$tfile
11344 }
11345 run_test 119b "Sparse directIO read must return actual read amount"
11346
11347 test_119c() # bug 13099
11348 {
11349         BSIZE=1048576
11350         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11351         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11352         rm -f $DIR/$tfile
11353 }
11354 run_test 119c "Testing for direct read hitting hole"
11355
11356 test_119d() # bug 15950
11357 {
11358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11359
11360         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11361         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11362         BSIZE=1048576
11363         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11364         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11365         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11366         lctl set_param fail_loc=0x40d
11367         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11368         pid_dio=$!
11369         sleep 1
11370         cat $DIR/$tfile > /dev/null &
11371         lctl set_param fail_loc=0
11372         pid_reads=$!
11373         wait $pid_dio
11374         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11375         sleep 2
11376         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11377         error "the read rpcs have not completed in 2s"
11378         rm -f $DIR/$tfile
11379         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11380 }
11381 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11382
11383 test_120a() {
11384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11385         remote_mds_nodsh && skip "remote MDS with nodsh"
11386         test_mkdir -i0 -c1 $DIR/$tdir
11387         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11388                 skip_env "no early lock cancel on server"
11389
11390         lru_resize_disable mdc
11391         lru_resize_disable osc
11392         cancel_lru_locks mdc
11393         # asynchronous object destroy at MDT could cause bl ast to client
11394         cancel_lru_locks osc
11395
11396         stat $DIR/$tdir > /dev/null
11397         can1=$(do_facet mds1 \
11398                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11399                awk '/ldlm_cancel/ {print $2}')
11400         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11401                awk '/ldlm_bl_callback/ {print $2}')
11402         test_mkdir -i0 -c1 $DIR/$tdir/d1
11403         can2=$(do_facet mds1 \
11404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11405                awk '/ldlm_cancel/ {print $2}')
11406         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11407                awk '/ldlm_bl_callback/ {print $2}')
11408         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11409         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11410         lru_resize_enable mdc
11411         lru_resize_enable osc
11412 }
11413 run_test 120a "Early Lock Cancel: mkdir test"
11414
11415 test_120b() {
11416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11417         remote_mds_nodsh && skip "remote MDS with nodsh"
11418         test_mkdir $DIR/$tdir
11419         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11420                 skip_env "no early lock cancel on server"
11421
11422         lru_resize_disable mdc
11423         lru_resize_disable osc
11424         cancel_lru_locks mdc
11425         stat $DIR/$tdir > /dev/null
11426         can1=$(do_facet $SINGLEMDS \
11427                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11428                awk '/ldlm_cancel/ {print $2}')
11429         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11430                awk '/ldlm_bl_callback/ {print $2}')
11431         touch $DIR/$tdir/f1
11432         can2=$(do_facet $SINGLEMDS \
11433                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11434                awk '/ldlm_cancel/ {print $2}')
11435         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11436                awk '/ldlm_bl_callback/ {print $2}')
11437         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11438         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11439         lru_resize_enable mdc
11440         lru_resize_enable osc
11441 }
11442 run_test 120b "Early Lock Cancel: create test"
11443
11444 test_120c() {
11445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11446         remote_mds_nodsh && skip "remote MDS with nodsh"
11447         test_mkdir -i0 -c1 $DIR/$tdir
11448         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11449                 skip "no early lock cancel on server"
11450
11451         lru_resize_disable mdc
11452         lru_resize_disable osc
11453         test_mkdir -i0 -c1 $DIR/$tdir/d1
11454         test_mkdir -i0 -c1 $DIR/$tdir/d2
11455         touch $DIR/$tdir/d1/f1
11456         cancel_lru_locks mdc
11457         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11458         can1=$(do_facet mds1 \
11459                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11460                awk '/ldlm_cancel/ {print $2}')
11461         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11462                awk '/ldlm_bl_callback/ {print $2}')
11463         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11464         can2=$(do_facet mds1 \
11465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11466                awk '/ldlm_cancel/ {print $2}')
11467         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11468                awk '/ldlm_bl_callback/ {print $2}')
11469         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11470         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11471         lru_resize_enable mdc
11472         lru_resize_enable osc
11473 }
11474 run_test 120c "Early Lock Cancel: link test"
11475
11476 test_120d() {
11477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11478         remote_mds_nodsh && skip "remote MDS with nodsh"
11479         test_mkdir -i0 -c1 $DIR/$tdir
11480         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11481                 skip_env "no early lock cancel on server"
11482
11483         lru_resize_disable mdc
11484         lru_resize_disable osc
11485         touch $DIR/$tdir
11486         cancel_lru_locks mdc
11487         stat $DIR/$tdir > /dev/null
11488         can1=$(do_facet mds1 \
11489                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11490                awk '/ldlm_cancel/ {print $2}')
11491         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11492                awk '/ldlm_bl_callback/ {print $2}')
11493         chmod a+x $DIR/$tdir
11494         can2=$(do_facet mds1 \
11495                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11496                awk '/ldlm_cancel/ {print $2}')
11497         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11498                awk '/ldlm_bl_callback/ {print $2}')
11499         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11500         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11501         lru_resize_enable mdc
11502         lru_resize_enable osc
11503 }
11504 run_test 120d "Early Lock Cancel: setattr test"
11505
11506 test_120e() {
11507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11508         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11509                 skip_env "no early lock cancel on server"
11510         remote_mds_nodsh && skip "remote MDS with nodsh"
11511
11512         local dlmtrace_set=false
11513
11514         test_mkdir -i0 -c1 $DIR/$tdir
11515         lru_resize_disable mdc
11516         lru_resize_disable osc
11517         ! $LCTL get_param debug | grep -q dlmtrace &&
11518                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11519         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11520         cancel_lru_locks mdc
11521         cancel_lru_locks osc
11522         dd if=$DIR/$tdir/f1 of=/dev/null
11523         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11524         # XXX client can not do early lock cancel of OST lock
11525         # during unlink (LU-4206), so cancel osc lock now.
11526         sleep 2
11527         cancel_lru_locks osc
11528         can1=$(do_facet mds1 \
11529                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11530                awk '/ldlm_cancel/ {print $2}')
11531         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11532                awk '/ldlm_bl_callback/ {print $2}')
11533         unlink $DIR/$tdir/f1
11534         sleep 5
11535         can2=$(do_facet mds1 \
11536                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11537                awk '/ldlm_cancel/ {print $2}')
11538         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11539                awk '/ldlm_bl_callback/ {print $2}')
11540         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11541                 $LCTL dk $TMP/cancel.debug.txt
11542         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11543                 $LCTL dk $TMP/blocking.debug.txt
11544         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11545         lru_resize_enable mdc
11546         lru_resize_enable osc
11547 }
11548 run_test 120e "Early Lock Cancel: unlink test"
11549
11550 test_120f() {
11551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11552         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11553                 skip_env "no early lock cancel on server"
11554         remote_mds_nodsh && skip "remote MDS with nodsh"
11555
11556         test_mkdir -i0 -c1 $DIR/$tdir
11557         lru_resize_disable mdc
11558         lru_resize_disable osc
11559         test_mkdir -i0 -c1 $DIR/$tdir/d1
11560         test_mkdir -i0 -c1 $DIR/$tdir/d2
11561         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11562         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11563         cancel_lru_locks mdc
11564         cancel_lru_locks osc
11565         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11566         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11567         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11568         # XXX client can not do early lock cancel of OST lock
11569         # during rename (LU-4206), so cancel osc lock now.
11570         sleep 2
11571         cancel_lru_locks osc
11572         can1=$(do_facet mds1 \
11573                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11574                awk '/ldlm_cancel/ {print $2}')
11575         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11576                awk '/ldlm_bl_callback/ {print $2}')
11577         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11578         sleep 5
11579         can2=$(do_facet mds1 \
11580                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11581                awk '/ldlm_cancel/ {print $2}')
11582         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11583                awk '/ldlm_bl_callback/ {print $2}')
11584         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11585         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11586         lru_resize_enable mdc
11587         lru_resize_enable osc
11588 }
11589 run_test 120f "Early Lock Cancel: rename test"
11590
11591 test_120g() {
11592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11593         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11594                 skip_env "no early lock cancel on server"
11595         remote_mds_nodsh && skip "remote MDS with nodsh"
11596
11597         lru_resize_disable mdc
11598         lru_resize_disable osc
11599         count=10000
11600         echo create $count files
11601         test_mkdir $DIR/$tdir
11602         cancel_lru_locks mdc
11603         cancel_lru_locks osc
11604         t0=$(date +%s)
11605
11606         can0=$(do_facet $SINGLEMDS \
11607                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11608                awk '/ldlm_cancel/ {print $2}')
11609         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11610                awk '/ldlm_bl_callback/ {print $2}')
11611         createmany -o $DIR/$tdir/f $count
11612         sync
11613         can1=$(do_facet $SINGLEMDS \
11614                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11615                awk '/ldlm_cancel/ {print $2}')
11616         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11617                awk '/ldlm_bl_callback/ {print $2}')
11618         t1=$(date +%s)
11619         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11620         echo rm $count files
11621         rm -r $DIR/$tdir
11622         sync
11623         can2=$(do_facet $SINGLEMDS \
11624                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11625                awk '/ldlm_cancel/ {print $2}')
11626         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11627                awk '/ldlm_bl_callback/ {print $2}')
11628         t2=$(date +%s)
11629         echo total: $count removes in $((t2-t1))
11630         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11631         sleep 2
11632         # wait for commitment of removal
11633         lru_resize_enable mdc
11634         lru_resize_enable osc
11635 }
11636 run_test 120g "Early Lock Cancel: performance test"
11637
11638 test_121() { #bug #10589
11639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11640
11641         rm -rf $DIR/$tfile
11642         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11643 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11644         lctl set_param fail_loc=0x310
11645         cancel_lru_locks osc > /dev/null
11646         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11647         lctl set_param fail_loc=0
11648         [[ $reads -eq $writes ]] ||
11649                 error "read $reads blocks, must be $writes blocks"
11650 }
11651 run_test 121 "read cancel race ========="
11652
11653 test_123a_base() { # was test 123, statahead(bug 11401)
11654         local lsx="$1"
11655
11656         SLOWOK=0
11657         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11658                 log "testing UP system. Performance may be lower than expected."
11659                 SLOWOK=1
11660         fi
11661
11662         rm -rf $DIR/$tdir
11663         test_mkdir $DIR/$tdir
11664         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11665         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11666         MULT=10
11667         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11668                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11669
11670                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11671                 lctl set_param -n llite.*.statahead_max 0
11672                 lctl get_param llite.*.statahead_max
11673                 cancel_lru_locks mdc
11674                 cancel_lru_locks osc
11675                 stime=$(date +%s)
11676                 time $lsx $DIR/$tdir | wc -l
11677                 etime=$(date +%s)
11678                 delta=$((etime - stime))
11679                 log "$lsx $i files without statahead: $delta sec"
11680                 lctl set_param llite.*.statahead_max=$max
11681
11682                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11683                         grep "statahead wrong:" | awk '{print $3}')
11684                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11685                 cancel_lru_locks mdc
11686                 cancel_lru_locks osc
11687                 stime=$(date +%s)
11688                 time $lsx $DIR/$tdir | wc -l
11689                 etime=$(date +%s)
11690                 delta_sa=$((etime - stime))
11691                 log "$lsx $i files with statahead: $delta_sa sec"
11692                 lctl get_param -n llite.*.statahead_stats
11693                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11694                         grep "statahead wrong:" | awk '{print $3}')
11695
11696                 [[ $swrong -lt $ewrong ]] &&
11697                         log "statahead was stopped, maybe too many locks held!"
11698                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11699
11700                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11701                         max=$(lctl get_param -n llite.*.statahead_max |
11702                                 head -n 1)
11703                         lctl set_param -n llite.*.statahead_max 0
11704                         lctl get_param llite.*.statahead_max
11705                         cancel_lru_locks mdc
11706                         cancel_lru_locks osc
11707                         stime=$(date +%s)
11708                         time $lsx $DIR/$tdir | wc -l
11709                         etime=$(date +%s)
11710                         delta=$((etime - stime))
11711                         log "$lsx $i files again without statahead: $delta sec"
11712                         lctl set_param llite.*.statahead_max=$max
11713                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11714                                 if [  $SLOWOK -eq 0 ]; then
11715                                         error "$lsx $i files is slower with statahead!"
11716                                 else
11717                                         log "$lsx $i files is slower with statahead!"
11718                                 fi
11719                                 break
11720                         fi
11721                 fi
11722
11723                 [ $delta -gt 20 ] && break
11724                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11725                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11726         done
11727         log "$lsx done"
11728
11729         stime=$(date +%s)
11730         rm -r $DIR/$tdir
11731         sync
11732         etime=$(date +%s)
11733         delta=$((etime - stime))
11734         log "rm -r $DIR/$tdir/: $delta seconds"
11735         log "rm done"
11736         lctl get_param -n llite.*.statahead_stats
11737 }
11738
11739 test_123aa() {
11740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11741
11742         test_123a_base "ls -l"
11743 }
11744 run_test 123aa "verify statahead work"
11745
11746 test_123ab() {
11747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11748
11749         statx_supported || skip_env "Test must be statx() syscall supported"
11750
11751         test_123a_base "$STATX -l"
11752 }
11753 run_test 123ab "verify statahead work by using statx"
11754
11755 test_123ac() {
11756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11757
11758         statx_supported || skip_env "Test must be statx() syscall supported"
11759
11760         local rpcs_before
11761         local rpcs_after
11762         local agl_before
11763         local agl_after
11764
11765         cancel_lru_locks $OSC
11766         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11767         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11768                 awk '/agl.total:/ {print $3}')
11769         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11770         test_123a_base "$STATX --cached=always -D"
11771         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11772                 awk '/agl.total:/ {print $3}')
11773         [ $agl_before -eq $agl_after ] ||
11774                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11775         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11776         [ $rpcs_after -eq $rpcs_before ] ||
11777                 error "$STATX should not send glimpse RPCs to $OSC"
11778 }
11779 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11780
11781 test_123b () { # statahead(bug 15027)
11782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11783
11784         test_mkdir $DIR/$tdir
11785         createmany -o $DIR/$tdir/$tfile-%d 1000
11786
11787         cancel_lru_locks mdc
11788         cancel_lru_locks osc
11789
11790 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11791         lctl set_param fail_loc=0x80000803
11792         ls -lR $DIR/$tdir > /dev/null
11793         log "ls done"
11794         lctl set_param fail_loc=0x0
11795         lctl get_param -n llite.*.statahead_stats
11796         rm -r $DIR/$tdir
11797         sync
11798
11799 }
11800 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11801
11802 test_123c() {
11803         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11804
11805         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11806         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11807         touch $DIR/$tdir.1/{1..3}
11808         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11809
11810         remount_client $MOUNT
11811
11812         $MULTIOP $DIR/$tdir.0 Q
11813
11814         # let statahead to complete
11815         ls -l $DIR/$tdir.0 > /dev/null
11816
11817         testid=$(echo $TESTNAME | tr '_' ' ')
11818         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11819                 error "statahead warning" || true
11820 }
11821 run_test 123c "Can not initialize inode warning on DNE statahead"
11822
11823 test_124a() {
11824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11825         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11826                 skip_env "no lru resize on server"
11827
11828         local NR=2000
11829
11830         test_mkdir $DIR/$tdir
11831
11832         log "create $NR files at $DIR/$tdir"
11833         createmany -o $DIR/$tdir/f $NR ||
11834                 error "failed to create $NR files in $DIR/$tdir"
11835
11836         cancel_lru_locks mdc
11837         ls -l $DIR/$tdir > /dev/null
11838
11839         local NSDIR=""
11840         local LRU_SIZE=0
11841         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11842                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11843                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11844                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11845                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11846                         log "NSDIR=$NSDIR"
11847                         log "NS=$(basename $NSDIR)"
11848                         break
11849                 fi
11850         done
11851
11852         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11853                 skip "Not enough cached locks created!"
11854         fi
11855         log "LRU=$LRU_SIZE"
11856
11857         local SLEEP=30
11858
11859         # We know that lru resize allows one client to hold $LIMIT locks
11860         # for 10h. After that locks begin to be killed by client.
11861         local MAX_HRS=10
11862         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11863         log "LIMIT=$LIMIT"
11864         if [ $LIMIT -lt $LRU_SIZE ]; then
11865                 skip "Limit is too small $LIMIT"
11866         fi
11867
11868         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11869         # killing locks. Some time was spent for creating locks. This means
11870         # that up to the moment of sleep finish we must have killed some of
11871         # them (10-100 locks). This depends on how fast ther were created.
11872         # Many of them were touched in almost the same moment and thus will
11873         # be killed in groups.
11874         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11875
11876         # Use $LRU_SIZE_B here to take into account real number of locks
11877         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11878         local LRU_SIZE_B=$LRU_SIZE
11879         log "LVF=$LVF"
11880         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11881         log "OLD_LVF=$OLD_LVF"
11882         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11883
11884         # Let's make sure that we really have some margin. Client checks
11885         # cached locks every 10 sec.
11886         SLEEP=$((SLEEP+20))
11887         log "Sleep ${SLEEP} sec"
11888         local SEC=0
11889         while ((SEC<$SLEEP)); do
11890                 echo -n "..."
11891                 sleep 5
11892                 SEC=$((SEC+5))
11893                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11894                 echo -n "$LRU_SIZE"
11895         done
11896         echo ""
11897         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11898         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11899
11900         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11901                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11902                 unlinkmany $DIR/$tdir/f $NR
11903                 return
11904         }
11905
11906         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11907         log "unlink $NR files at $DIR/$tdir"
11908         unlinkmany $DIR/$tdir/f $NR
11909 }
11910 run_test 124a "lru resize ======================================="
11911
11912 get_max_pool_limit()
11913 {
11914         local limit=$($LCTL get_param \
11915                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11916         local max=0
11917         for l in $limit; do
11918                 if [[ $l -gt $max ]]; then
11919                         max=$l
11920                 fi
11921         done
11922         echo $max
11923 }
11924
11925 test_124b() {
11926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11927         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11928                 skip_env "no lru resize on server"
11929
11930         LIMIT=$(get_max_pool_limit)
11931
11932         NR=$(($(default_lru_size)*20))
11933         if [[ $NR -gt $LIMIT ]]; then
11934                 log "Limit lock number by $LIMIT locks"
11935                 NR=$LIMIT
11936         fi
11937
11938         IFree=$(mdsrate_inodes_available)
11939         if [ $IFree -lt $NR ]; then
11940                 log "Limit lock number by $IFree inodes"
11941                 NR=$IFree
11942         fi
11943
11944         lru_resize_disable mdc
11945         test_mkdir -p $DIR/$tdir/disable_lru_resize
11946
11947         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11948         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11949         cancel_lru_locks mdc
11950         stime=`date +%s`
11951         PID=""
11952         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11953         PID="$PID $!"
11954         sleep 2
11955         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11956         PID="$PID $!"
11957         sleep 2
11958         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11959         PID="$PID $!"
11960         wait $PID
11961         etime=`date +%s`
11962         nolruresize_delta=$((etime-stime))
11963         log "ls -la time: $nolruresize_delta seconds"
11964         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11965         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11966
11967         lru_resize_enable mdc
11968         test_mkdir -p $DIR/$tdir/enable_lru_resize
11969
11970         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11971         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11972         cancel_lru_locks mdc
11973         stime=`date +%s`
11974         PID=""
11975         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11976         PID="$PID $!"
11977         sleep 2
11978         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11979         PID="$PID $!"
11980         sleep 2
11981         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11982         PID="$PID $!"
11983         wait $PID
11984         etime=`date +%s`
11985         lruresize_delta=$((etime-stime))
11986         log "ls -la time: $lruresize_delta seconds"
11987         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11988
11989         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11990                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11991         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11992                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11993         else
11994                 log "lru resize performs the same with no lru resize"
11995         fi
11996         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11997 }
11998 run_test 124b "lru resize (performance test) ======================="
11999
12000 test_124c() {
12001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12002         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12003                 skip_env "no lru resize on server"
12004
12005         # cache ununsed locks on client
12006         local nr=100
12007         cancel_lru_locks mdc
12008         test_mkdir $DIR/$tdir
12009         createmany -o $DIR/$tdir/f $nr ||
12010                 error "failed to create $nr files in $DIR/$tdir"
12011         ls -l $DIR/$tdir > /dev/null
12012
12013         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12014         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12015         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12016         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12017         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12018
12019         # set lru_max_age to 1 sec
12020         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12021         echo "sleep $((recalc_p * 2)) seconds..."
12022         sleep $((recalc_p * 2))
12023
12024         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12025         # restore lru_max_age
12026         $LCTL set_param -n $nsdir.lru_max_age $max_age
12027         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12028         unlinkmany $DIR/$tdir/f $nr
12029 }
12030 run_test 124c "LRUR cancel very aged locks"
12031
12032 test_124d() {
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12035                 skip_env "no lru resize on server"
12036
12037         # cache ununsed locks on client
12038         local nr=100
12039
12040         lru_resize_disable mdc
12041         stack_trap "lru_resize_enable mdc" EXIT
12042
12043         cancel_lru_locks mdc
12044
12045         # asynchronous object destroy at MDT could cause bl ast to client
12046         test_mkdir $DIR/$tdir
12047         createmany -o $DIR/$tdir/f $nr ||
12048                 error "failed to create $nr files in $DIR/$tdir"
12049         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12050
12051         ls -l $DIR/$tdir > /dev/null
12052
12053         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12054         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12055         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12056         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12057
12058         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12059
12060         # set lru_max_age to 1 sec
12061         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12062         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12063
12064         echo "sleep $((recalc_p * 2)) seconds..."
12065         sleep $((recalc_p * 2))
12066
12067         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12068
12069         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12070 }
12071 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12072
12073 test_125() { # 13358
12074         $LCTL get_param -n llite.*.client_type | grep -q local ||
12075                 skip "must run as local client"
12076         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12077                 skip_env "must have acl enabled"
12078         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12079
12080         test_mkdir $DIR/$tdir
12081         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12082         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12083         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12084 }
12085 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12086
12087 test_126() { # bug 12829/13455
12088         $GSS && skip_env "must run as gss disabled"
12089         $LCTL get_param -n llite.*.client_type | grep -q local ||
12090                 skip "must run as local client"
12091         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12092
12093         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12094         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12095         rm -f $DIR/$tfile
12096         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12097 }
12098 run_test 126 "check that the fsgid provided by the client is taken into account"
12099
12100 test_127a() { # bug 15521
12101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12102         local name count samp unit min max sum sumsq
12103
12104         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12105         echo "stats before reset"
12106         $LCTL get_param osc.*.stats
12107         $LCTL set_param osc.*.stats=0
12108         local fsize=$((2048 * 1024))
12109
12110         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12111         cancel_lru_locks osc
12112         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12113
12114         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12115         stack_trap "rm -f $TMP/$tfile.tmp"
12116         while read name count samp unit min max sum sumsq; do
12117                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12118                 [ ! $min ] && error "Missing min value for $name proc entry"
12119                 eval $name=$count || error "Wrong proc format"
12120
12121                 case $name in
12122                 read_bytes|write_bytes)
12123                         [[ "$unit" =~ "bytes" ]] ||
12124                                 error "unit is not 'bytes': $unit"
12125                         (( $min >= 4096 )) || error "min is too small: $min"
12126                         (( $min <= $fsize )) || error "min is too big: $min"
12127                         (( $max >= 4096 )) || error "max is too small: $max"
12128                         (( $max <= $fsize )) || error "max is too big: $max"
12129                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12130                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12131                                 error "sumsquare is too small: $sumsq"
12132                         (( $sumsq <= $fsize * $fsize )) ||
12133                                 error "sumsquare is too big: $sumsq"
12134                         ;;
12135                 ost_read|ost_write)
12136                         [[ "$unit" =~ "usec" ]] ||
12137                                 error "unit is not 'usec': $unit"
12138                         ;;
12139                 *)      ;;
12140                 esac
12141         done < $DIR/$tfile.tmp
12142
12143         #check that we actually got some stats
12144         [ "$read_bytes" ] || error "Missing read_bytes stats"
12145         [ "$write_bytes" ] || error "Missing write_bytes stats"
12146         [ "$read_bytes" != 0 ] || error "no read done"
12147         [ "$write_bytes" != 0 ] || error "no write done"
12148 }
12149 run_test 127a "verify the client stats are sane"
12150
12151 test_127b() { # bug LU-333
12152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12153         local name count samp unit min max sum sumsq
12154
12155         echo "stats before reset"
12156         $LCTL get_param llite.*.stats
12157         $LCTL set_param llite.*.stats=0
12158
12159         # perform 2 reads and writes so MAX is different from SUM.
12160         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12161         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12162         cancel_lru_locks osc
12163         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12164         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12165
12166         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12167         stack_trap "rm -f $TMP/$tfile.tmp"
12168         while read name count samp unit min max sum sumsq; do
12169                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12170                 eval $name=$count || error "Wrong proc format"
12171
12172                 case $name in
12173                 read_bytes|write_bytes)
12174                         [[ "$unit" =~ "bytes" ]] ||
12175                                 error "unit is not 'bytes': $unit"
12176                         (( $count == 2 )) || error "count is not 2: $count"
12177                         (( $min == $PAGE_SIZE )) ||
12178                                 error "min is not $PAGE_SIZE: $min"
12179                         (( $max == $PAGE_SIZE )) ||
12180                                 error "max is not $PAGE_SIZE: $max"
12181                         (( $sum == $PAGE_SIZE * 2 )) ||
12182                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12183                         ;;
12184                 read|write)
12185                         [[ "$unit" =~ "usec" ]] ||
12186                                 error "unit is not 'usec': $unit"
12187                         ;;
12188                 *)      ;;
12189                 esac
12190         done < $TMP/$tfile.tmp
12191
12192         #check that we actually got some stats
12193         [ "$read_bytes" ] || error "Missing read_bytes stats"
12194         [ "$write_bytes" ] || error "Missing write_bytes stats"
12195         [ "$read_bytes" != 0 ] || error "no read done"
12196         [ "$write_bytes" != 0 ] || error "no write done"
12197 }
12198 run_test 127b "verify the llite client stats are sane"
12199
12200 test_127c() { # LU-12394
12201         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12202         local size
12203         local bsize
12204         local reads
12205         local writes
12206         local count
12207
12208         $LCTL set_param llite.*.extents_stats=1
12209         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12210
12211         # Use two stripes so there is enough space in default config
12212         $LFS setstripe -c 2 $DIR/$tfile
12213
12214         # Extent stats start at 0-4K and go in power of two buckets
12215         # LL_HIST_START = 12 --> 2^12 = 4K
12216         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12217         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12218         # small configs
12219         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12220                 do
12221                 # Write and read, 2x each, second time at a non-zero offset
12222                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12223                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12224                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12225                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12226                 rm -f $DIR/$tfile
12227         done
12228
12229         $LCTL get_param llite.*.extents_stats
12230
12231         count=2
12232         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12233                 do
12234                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12235                                 grep -m 1 $bsize)
12236                 reads=$(echo $bucket | awk '{print $5}')
12237                 writes=$(echo $bucket | awk '{print $9}')
12238                 [ "$reads" -eq $count ] ||
12239                         error "$reads reads in < $bsize bucket, expect $count"
12240                 [ "$writes" -eq $count ] ||
12241                         error "$writes writes in < $bsize bucket, expect $count"
12242         done
12243
12244         # Test mmap write and read
12245         $LCTL set_param llite.*.extents_stats=c
12246         size=512
12247         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12248         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12249         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12250
12251         $LCTL get_param llite.*.extents_stats
12252
12253         count=$(((size*1024) / PAGE_SIZE))
12254
12255         bsize=$((2 * PAGE_SIZE / 1024))K
12256
12257         bucket=$($LCTL get_param -n llite.*.extents_stats |
12258                         grep -m 1 $bsize)
12259         reads=$(echo $bucket | awk '{print $5}')
12260         writes=$(echo $bucket | awk '{print $9}')
12261         # mmap writes fault in the page first, creating an additonal read
12262         [ "$reads" -eq $((2 * count)) ] ||
12263                 error "$reads reads in < $bsize bucket, expect $count"
12264         [ "$writes" -eq $count ] ||
12265                 error "$writes writes in < $bsize bucket, expect $count"
12266 }
12267 run_test 127c "test llite extent stats with regular & mmap i/o"
12268
12269 test_128() { # bug 15212
12270         touch $DIR/$tfile
12271         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12272                 find $DIR/$tfile
12273                 find $DIR/$tfile
12274         EOF
12275
12276         result=$(grep error $TMP/$tfile.log)
12277         rm -f $DIR/$tfile $TMP/$tfile.log
12278         [ -z "$result" ] ||
12279                 error "consecutive find's under interactive lfs failed"
12280 }
12281 run_test 128 "interactive lfs for 2 consecutive find's"
12282
12283 set_dir_limits () {
12284         local mntdev
12285         local canondev
12286         local node
12287
12288         local ldproc=/proc/fs/ldiskfs
12289         local facets=$(get_facets MDS)
12290
12291         for facet in ${facets//,/ }; do
12292                 canondev=$(ldiskfs_canon \
12293                            *.$(convert_facet2label $facet).mntdev $facet)
12294                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12295                         ldproc=/sys/fs/ldiskfs
12296                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12297                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12298         done
12299 }
12300
12301 check_mds_dmesg() {
12302         local facets=$(get_facets MDS)
12303         for facet in ${facets//,/ }; do
12304                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12305         done
12306         return 1
12307 }
12308
12309 test_129() {
12310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12311         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12312                 skip "Need MDS version with at least 2.5.56"
12313         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12314                 skip_env "ldiskfs only test"
12315         fi
12316         remote_mds_nodsh && skip "remote MDS with nodsh"
12317
12318         local ENOSPC=28
12319         local has_warning=false
12320
12321         rm -rf $DIR/$tdir
12322         mkdir -p $DIR/$tdir
12323
12324         # block size of mds1
12325         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12326         set_dir_limits $maxsize $((maxsize * 6 / 8))
12327         stack_trap "set_dir_limits 0 0"
12328         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12329         local dirsize=$(stat -c%s "$DIR/$tdir")
12330         local nfiles=0
12331         while (( $dirsize <= $maxsize )); do
12332                 $MCREATE $DIR/$tdir/file_base_$nfiles
12333                 rc=$?
12334                 # check two errors:
12335                 # ENOSPC for ext4 max_dir_size, which has been used since
12336                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12337                 if (( rc == ENOSPC )); then
12338                         set_dir_limits 0 0
12339                         echo "rc=$rc returned as expected after $nfiles files"
12340
12341                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12342                                 error "create failed w/o dir size limit"
12343
12344                         # messages may be rate limited if test is run repeatedly
12345                         check_mds_dmesg '"is approaching max"' ||
12346                                 echo "warning message should be output"
12347                         check_mds_dmesg '"has reached max"' ||
12348                                 echo "reached message should be output"
12349
12350                         dirsize=$(stat -c%s "$DIR/$tdir")
12351
12352                         [[ $dirsize -ge $maxsize ]] && return 0
12353                         error "dirsize $dirsize < $maxsize after $nfiles files"
12354                 elif (( rc != 0 )); then
12355                         break
12356                 fi
12357                 nfiles=$((nfiles + 1))
12358                 dirsize=$(stat -c%s "$DIR/$tdir")
12359         done
12360
12361         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12362 }
12363 run_test 129 "test directory size limit ========================"
12364
12365 OLDIFS="$IFS"
12366 cleanup_130() {
12367         trap 0
12368         IFS="$OLDIFS"
12369 }
12370
12371 test_130a() {
12372         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12373         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12374
12375         trap cleanup_130 EXIT RETURN
12376
12377         local fm_file=$DIR/$tfile
12378         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12379         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12380                 error "dd failed for $fm_file"
12381
12382         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12383         filefrag -ves $fm_file
12384         RC=$?
12385         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12386                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12387         [ $RC != 0 ] && error "filefrag $fm_file failed"
12388
12389         filefrag_op=$(filefrag -ve -k $fm_file |
12390                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12391         lun=$($LFS getstripe -i $fm_file)
12392
12393         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12394         IFS=$'\n'
12395         tot_len=0
12396         for line in $filefrag_op
12397         do
12398                 frag_lun=`echo $line | cut -d: -f5`
12399                 ext_len=`echo $line | cut -d: -f4`
12400                 if (( $frag_lun != $lun )); then
12401                         cleanup_130
12402                         error "FIEMAP on 1-stripe file($fm_file) failed"
12403                         return
12404                 fi
12405                 (( tot_len += ext_len ))
12406         done
12407
12408         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12409                 cleanup_130
12410                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12411                 return
12412         fi
12413
12414         cleanup_130
12415
12416         echo "FIEMAP on single striped file succeeded"
12417 }
12418 run_test 130a "FIEMAP (1-stripe file)"
12419
12420 test_130b() {
12421         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12422
12423         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12424         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12425
12426         trap cleanup_130 EXIT RETURN
12427
12428         local fm_file=$DIR/$tfile
12429         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12430                         error "setstripe on $fm_file"
12431         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12432                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12433
12434         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12435                 error "dd failed on $fm_file"
12436
12437         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12438         filefrag_op=$(filefrag -ve -k $fm_file |
12439                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12440
12441         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12442                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12443
12444         IFS=$'\n'
12445         tot_len=0
12446         num_luns=1
12447         for line in $filefrag_op
12448         do
12449                 frag_lun=$(echo $line | cut -d: -f5 |
12450                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12451                 ext_len=$(echo $line | cut -d: -f4)
12452                 if (( $frag_lun != $last_lun )); then
12453                         if (( tot_len != 1024 )); then
12454                                 cleanup_130
12455                                 error "FIEMAP on $fm_file failed; returned " \
12456                                 "len $tot_len for OST $last_lun instead of 1024"
12457                                 return
12458                         else
12459                                 (( num_luns += 1 ))
12460                                 tot_len=0
12461                         fi
12462                 fi
12463                 (( tot_len += ext_len ))
12464                 last_lun=$frag_lun
12465         done
12466         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12467                 cleanup_130
12468                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12469                         "luns or wrong len for OST $last_lun"
12470                 return
12471         fi
12472
12473         cleanup_130
12474
12475         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12476 }
12477 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12478
12479 test_130c() {
12480         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12481
12482         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12483         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12484
12485         trap cleanup_130 EXIT RETURN
12486
12487         local fm_file=$DIR/$tfile
12488         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12489         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12490                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12491
12492         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12493                         error "dd failed on $fm_file"
12494
12495         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12496         filefrag_op=$(filefrag -ve -k $fm_file |
12497                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12498
12499         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12500                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12501
12502         IFS=$'\n'
12503         tot_len=0
12504         num_luns=1
12505         for line in $filefrag_op
12506         do
12507                 frag_lun=$(echo $line | cut -d: -f5 |
12508                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12509                 ext_len=$(echo $line | cut -d: -f4)
12510                 if (( $frag_lun != $last_lun )); then
12511                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12512                         if (( logical != 512 )); then
12513                                 cleanup_130
12514                                 error "FIEMAP on $fm_file failed; returned " \
12515                                 "logical start for lun $logical instead of 512"
12516                                 return
12517                         fi
12518                         if (( tot_len != 512 )); then
12519                                 cleanup_130
12520                                 error "FIEMAP on $fm_file failed; returned " \
12521                                 "len $tot_len for OST $last_lun instead of 1024"
12522                                 return
12523                         else
12524                                 (( num_luns += 1 ))
12525                                 tot_len=0
12526                         fi
12527                 fi
12528                 (( tot_len += ext_len ))
12529                 last_lun=$frag_lun
12530         done
12531         if (( num_luns != 2 || tot_len != 512 )); then
12532                 cleanup_130
12533                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12534                         "luns or wrong len for OST $last_lun"
12535                 return
12536         fi
12537
12538         cleanup_130
12539
12540         echo "FIEMAP on 2-stripe file with hole succeeded"
12541 }
12542 run_test 130c "FIEMAP (2-stripe file with hole)"
12543
12544 test_130d() {
12545         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12546
12547         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12548         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12549
12550         trap cleanup_130 EXIT RETURN
12551
12552         local fm_file=$DIR/$tfile
12553         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12554                         error "setstripe on $fm_file"
12555         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12556                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12557
12558         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12559         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12560                 error "dd failed on $fm_file"
12561
12562         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12563         filefrag_op=$(filefrag -ve -k $fm_file |
12564                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12565
12566         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12567                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12568
12569         IFS=$'\n'
12570         tot_len=0
12571         num_luns=1
12572         for line in $filefrag_op
12573         do
12574                 frag_lun=$(echo $line | cut -d: -f5 |
12575                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12576                 ext_len=$(echo $line | cut -d: -f4)
12577                 if (( $frag_lun != $last_lun )); then
12578                         if (( tot_len != 1024 )); then
12579                                 cleanup_130
12580                                 error "FIEMAP on $fm_file failed; returned " \
12581                                 "len $tot_len for OST $last_lun instead of 1024"
12582                                 return
12583                         else
12584                                 (( num_luns += 1 ))
12585                                 tot_len=0
12586                         fi
12587                 fi
12588                 (( tot_len += ext_len ))
12589                 last_lun=$frag_lun
12590         done
12591         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12592                 cleanup_130
12593                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12594                         "luns or wrong len for OST $last_lun"
12595                 return
12596         fi
12597
12598         cleanup_130
12599
12600         echo "FIEMAP on N-stripe file succeeded"
12601 }
12602 run_test 130d "FIEMAP (N-stripe file)"
12603
12604 test_130e() {
12605         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12606
12607         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12608         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12609
12610         trap cleanup_130 EXIT RETURN
12611
12612         local fm_file=$DIR/$tfile
12613         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12614         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12615                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12616
12617         NUM_BLKS=512
12618         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12619         for ((i = 0; i < $NUM_BLKS; i++))
12620         do
12621                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12622         done
12623
12624         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12625         filefrag_op=$(filefrag -ve -k $fm_file |
12626                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12627
12628         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12629                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12630
12631         IFS=$'\n'
12632         tot_len=0
12633         num_luns=1
12634         for line in $filefrag_op
12635         do
12636                 frag_lun=$(echo $line | cut -d: -f5 |
12637                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12638                 ext_len=$(echo $line | cut -d: -f4)
12639                 if (( $frag_lun != $last_lun )); then
12640                         if (( tot_len != $EXPECTED_LEN )); then
12641                                 cleanup_130
12642                                 error "FIEMAP on $fm_file failed; returned " \
12643                                 "len $tot_len for OST $last_lun instead " \
12644                                 "of $EXPECTED_LEN"
12645                                 return
12646                         else
12647                                 (( num_luns += 1 ))
12648                                 tot_len=0
12649                         fi
12650                 fi
12651                 (( tot_len += ext_len ))
12652                 last_lun=$frag_lun
12653         done
12654         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12655                 cleanup_130
12656                 error "FIEMAP on $fm_file failed; returned wrong number " \
12657                         "of luns or wrong len for OST $last_lun"
12658                 return
12659         fi
12660
12661         cleanup_130
12662
12663         echo "FIEMAP with continuation calls succeeded"
12664 }
12665 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12666
12667 test_130f() {
12668         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12669         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12670
12671         local fm_file=$DIR/$tfile
12672         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12673                 error "multiop create with lov_delay_create on $fm_file"
12674
12675         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12676         filefrag_extents=$(filefrag -vek $fm_file |
12677                            awk '/extents? found/ { print $2 }')
12678         if [[ "$filefrag_extents" != "0" ]]; then
12679                 error "FIEMAP on $fm_file failed; " \
12680                       "returned $filefrag_extents expected 0"
12681         fi
12682
12683         rm -f $fm_file
12684 }
12685 run_test 130f "FIEMAP (unstriped file)"
12686
12687 # Test for writev/readv
12688 test_131a() {
12689         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12690                 error "writev test failed"
12691         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12692                 error "readv failed"
12693         rm -f $DIR/$tfile
12694 }
12695 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12696
12697 test_131b() {
12698         local fsize=$((524288 + 1048576 + 1572864))
12699         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12700                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12701                         error "append writev test failed"
12702
12703         ((fsize += 1572864 + 1048576))
12704         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12705                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12706                         error "append writev test failed"
12707         rm -f $DIR/$tfile
12708 }
12709 run_test 131b "test append writev"
12710
12711 test_131c() {
12712         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12713         error "NOT PASS"
12714 }
12715 run_test 131c "test read/write on file w/o objects"
12716
12717 test_131d() {
12718         rwv -f $DIR/$tfile -w -n 1 1572864
12719         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12720         if [ "$NOB" != 1572864 ]; then
12721                 error "Short read filed: read $NOB bytes instead of 1572864"
12722         fi
12723         rm -f $DIR/$tfile
12724 }
12725 run_test 131d "test short read"
12726
12727 test_131e() {
12728         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12729         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12730         error "read hitting hole failed"
12731         rm -f $DIR/$tfile
12732 }
12733 run_test 131e "test read hitting hole"
12734
12735 check_stats() {
12736         local facet=$1
12737         local op=$2
12738         local want=${3:-0}
12739         local res
12740
12741         case $facet in
12742         mds*) res=$(do_facet $facet \
12743                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12744                  ;;
12745         ost*) res=$(do_facet $facet \
12746                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12747                  ;;
12748         *) error "Wrong facet '$facet'" ;;
12749         esac
12750         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12751         # if the argument $3 is zero, it means any stat increment is ok.
12752         if [[ $want -gt 0 ]]; then
12753                 local count=$(echo $res | awk '{ print $2 }')
12754                 [[ $count -ne $want ]] &&
12755                         error "The $op counter on $facet is $count, not $want"
12756         fi
12757 }
12758
12759 test_133a() {
12760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12761         remote_ost_nodsh && skip "remote OST with nodsh"
12762         remote_mds_nodsh && skip "remote MDS with nodsh"
12763         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12764                 skip_env "MDS doesn't support rename stats"
12765
12766         local testdir=$DIR/${tdir}/stats_testdir
12767
12768         mkdir -p $DIR/${tdir}
12769
12770         # clear stats.
12771         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12772         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12773
12774         # verify mdt stats first.
12775         mkdir ${testdir} || error "mkdir failed"
12776         check_stats $SINGLEMDS "mkdir" 1
12777         touch ${testdir}/${tfile} || error "touch failed"
12778         check_stats $SINGLEMDS "open" 1
12779         check_stats $SINGLEMDS "close" 1
12780         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12781                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12782                 check_stats $SINGLEMDS "mknod" 2
12783         }
12784         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12785         check_stats $SINGLEMDS "unlink" 1
12786         rm -f ${testdir}/${tfile} || error "file remove failed"
12787         check_stats $SINGLEMDS "unlink" 2
12788
12789         # remove working dir and check mdt stats again.
12790         rmdir ${testdir} || error "rmdir failed"
12791         check_stats $SINGLEMDS "rmdir" 1
12792
12793         local testdir1=$DIR/${tdir}/stats_testdir1
12794         mkdir -p ${testdir}
12795         mkdir -p ${testdir1}
12796         touch ${testdir1}/test1
12797         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12798         check_stats $SINGLEMDS "crossdir_rename" 1
12799
12800         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12801         check_stats $SINGLEMDS "samedir_rename" 1
12802
12803         rm -rf $DIR/${tdir}
12804 }
12805 run_test 133a "Verifying MDT stats ========================================"
12806
12807 test_133b() {
12808         local res
12809
12810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12811         remote_ost_nodsh && skip "remote OST with nodsh"
12812         remote_mds_nodsh && skip "remote MDS with nodsh"
12813
12814         local testdir=$DIR/${tdir}/stats_testdir
12815
12816         mkdir -p ${testdir} || error "mkdir failed"
12817         touch ${testdir}/${tfile} || error "touch failed"
12818         cancel_lru_locks mdc
12819
12820         # clear stats.
12821         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12822         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12823
12824         # extra mdt stats verification.
12825         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12826         check_stats $SINGLEMDS "setattr" 1
12827         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12828         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12829         then            # LU-1740
12830                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12831                 check_stats $SINGLEMDS "getattr" 1
12832         fi
12833         rm -rf $DIR/${tdir}
12834
12835         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12836         # so the check below is not reliable
12837         [ $MDSCOUNT -eq 1 ] || return 0
12838
12839         # Sleep to avoid a cached response.
12840         #define OBD_STATFS_CACHE_SECONDS 1
12841         sleep 2
12842         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12843         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12844         $LFS df || error "lfs failed"
12845         check_stats $SINGLEMDS "statfs" 1
12846
12847         # check aggregated statfs (LU-10018)
12848         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12849                 return 0
12850         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12851                 return 0
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         df $DIR
12856         check_stats $SINGLEMDS "statfs" 1
12857
12858         # We want to check that the client didn't send OST_STATFS to
12859         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12860         # extra care is needed here.
12861         if remote_mds; then
12862                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12863                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12864
12865                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12866                 [ "$res" ] && error "OST got STATFS"
12867         fi
12868
12869         return 0
12870 }
12871 run_test 133b "Verifying extra MDT stats =================================="
12872
12873 test_133c() {
12874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12875         remote_ost_nodsh && skip "remote OST with nodsh"
12876         remote_mds_nodsh && skip "remote MDS with nodsh"
12877
12878         local testdir=$DIR/$tdir/stats_testdir
12879
12880         test_mkdir -p $testdir
12881
12882         # verify obdfilter stats.
12883         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12884         sync
12885         cancel_lru_locks osc
12886         wait_delete_completed
12887
12888         # clear stats.
12889         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12890         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12891
12892         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12893                 error "dd failed"
12894         sync
12895         cancel_lru_locks osc
12896         check_stats ost1 "write" 1
12897
12898         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12899         check_stats ost1 "read" 1
12900
12901         > $testdir/$tfile || error "truncate failed"
12902         check_stats ost1 "punch" 1
12903
12904         rm -f $testdir/$tfile || error "file remove failed"
12905         wait_delete_completed
12906         check_stats ost1 "destroy" 1
12907
12908         rm -rf $DIR/$tdir
12909 }
12910 run_test 133c "Verifying OST stats ========================================"
12911
12912 order_2() {
12913         local value=$1
12914         local orig=$value
12915         local order=1
12916
12917         while [ $value -ge 2 ]; do
12918                 order=$((order*2))
12919                 value=$((value/2))
12920         done
12921
12922         if [ $orig -gt $order ]; then
12923                 order=$((order*2))
12924         fi
12925         echo $order
12926 }
12927
12928 size_in_KMGT() {
12929     local value=$1
12930     local size=('K' 'M' 'G' 'T');
12931     local i=0
12932     local size_string=$value
12933
12934     while [ $value -ge 1024 ]; do
12935         if [ $i -gt 3 ]; then
12936             #T is the biggest unit we get here, if that is bigger,
12937             #just return XXXT
12938             size_string=${value}T
12939             break
12940         fi
12941         value=$((value >> 10))
12942         if [ $value -lt 1024 ]; then
12943             size_string=${value}${size[$i]}
12944             break
12945         fi
12946         i=$((i + 1))
12947     done
12948
12949     echo $size_string
12950 }
12951
12952 get_rename_size() {
12953         local size=$1
12954         local context=${2:-.}
12955         local sample=$(do_facet $SINGLEMDS $LCTL \
12956                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12957                 grep -A1 $context |
12958                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12959         echo $sample
12960 }
12961
12962 test_133d() {
12963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12964         remote_ost_nodsh && skip "remote OST with nodsh"
12965         remote_mds_nodsh && skip "remote MDS with nodsh"
12966         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12967                 skip_env "MDS doesn't support rename stats"
12968
12969         local testdir1=$DIR/${tdir}/stats_testdir1
12970         local testdir2=$DIR/${tdir}/stats_testdir2
12971         mkdir -p $DIR/${tdir}
12972
12973         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12974
12975         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12976         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12977
12978         createmany -o $testdir1/test 512 || error "createmany failed"
12979
12980         # check samedir rename size
12981         mv ${testdir1}/test0 ${testdir1}/test_0
12982
12983         local testdir1_size=$(ls -l $DIR/${tdir} |
12984                 awk '/stats_testdir1/ {print $5}')
12985         local testdir2_size=$(ls -l $DIR/${tdir} |
12986                 awk '/stats_testdir2/ {print $5}')
12987
12988         testdir1_size=$(order_2 $testdir1_size)
12989         testdir2_size=$(order_2 $testdir2_size)
12990
12991         testdir1_size=$(size_in_KMGT $testdir1_size)
12992         testdir2_size=$(size_in_KMGT $testdir2_size)
12993
12994         echo "source rename dir size: ${testdir1_size}"
12995         echo "target rename dir size: ${testdir2_size}"
12996
12997         local cmd="do_facet $SINGLEMDS $LCTL "
12998         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12999
13000         eval $cmd || error "$cmd failed"
13001         local samedir=$($cmd | grep 'same_dir')
13002         local same_sample=$(get_rename_size $testdir1_size)
13003         [ -z "$samedir" ] && error "samedir_rename_size count error"
13004         [[ $same_sample -eq 1 ]] ||
13005                 error "samedir_rename_size error $same_sample"
13006         echo "Check same dir rename stats success"
13007
13008         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13009
13010         # check crossdir rename size
13011         mv ${testdir1}/test_0 ${testdir2}/test_0
13012
13013         testdir1_size=$(ls -l $DIR/${tdir} |
13014                 awk '/stats_testdir1/ {print $5}')
13015         testdir2_size=$(ls -l $DIR/${tdir} |
13016                 awk '/stats_testdir2/ {print $5}')
13017
13018         testdir1_size=$(order_2 $testdir1_size)
13019         testdir2_size=$(order_2 $testdir2_size)
13020
13021         testdir1_size=$(size_in_KMGT $testdir1_size)
13022         testdir2_size=$(size_in_KMGT $testdir2_size)
13023
13024         echo "source rename dir size: ${testdir1_size}"
13025         echo "target rename dir size: ${testdir2_size}"
13026
13027         eval $cmd || error "$cmd failed"
13028         local crossdir=$($cmd | grep 'crossdir')
13029         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13030         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13031         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13032         [[ $src_sample -eq 1 ]] ||
13033                 error "crossdir_rename_size error $src_sample"
13034         [[ $tgt_sample -eq 1 ]] ||
13035                 error "crossdir_rename_size error $tgt_sample"
13036         echo "Check cross dir rename stats success"
13037         rm -rf $DIR/${tdir}
13038 }
13039 run_test 133d "Verifying rename_stats ========================================"
13040
13041 test_133e() {
13042         remote_mds_nodsh && skip "remote MDS with nodsh"
13043         remote_ost_nodsh && skip "remote OST with nodsh"
13044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13045
13046         local testdir=$DIR/${tdir}/stats_testdir
13047         local ctr f0 f1 bs=32768 count=42 sum
13048
13049         mkdir -p ${testdir} || error "mkdir failed"
13050
13051         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13052
13053         for ctr in {write,read}_bytes; do
13054                 sync
13055                 cancel_lru_locks osc
13056
13057                 do_facet ost1 $LCTL set_param -n \
13058                         "obdfilter.*.exports.clear=clear"
13059
13060                 if [ $ctr = write_bytes ]; then
13061                         f0=/dev/zero
13062                         f1=${testdir}/${tfile}
13063                 else
13064                         f0=${testdir}/${tfile}
13065                         f1=/dev/null
13066                 fi
13067
13068                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13069                         error "dd failed"
13070                 sync
13071                 cancel_lru_locks osc
13072
13073                 sum=$(do_facet ost1 $LCTL get_param \
13074                         "obdfilter.*.exports.*.stats" |
13075                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13076                                 $1 == ctr { sum += $7 }
13077                                 END { printf("%0.0f", sum) }')
13078
13079                 if ((sum != bs * count)); then
13080                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13081                 fi
13082         done
13083
13084         rm -rf $DIR/${tdir}
13085 }
13086 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13087
13088 test_133f() {
13089         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13090                 skip "too old lustre for get_param -R ($facet_ver)"
13091
13092         # verifying readability.
13093         $LCTL get_param -R '*' &> /dev/null
13094
13095         # Verifing writability with badarea_io.
13096         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13097                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13098                 error "client badarea_io failed"
13099
13100         # remount the FS in case writes/reads /proc break the FS
13101         cleanup || error "failed to unmount"
13102         setup || error "failed to setup"
13103 }
13104 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13105
13106 test_133g() {
13107         remote_mds_nodsh && skip "remote MDS with nodsh"
13108         remote_ost_nodsh && skip "remote OST with nodsh"
13109
13110         local facet
13111         for facet in mds1 ost1; do
13112                 local facet_ver=$(lustre_version_code $facet)
13113                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13114                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13115                 else
13116                         log "$facet: too old lustre for get_param -R"
13117                 fi
13118                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13119                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13120                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13121                                 xargs badarea_io" ||
13122                                         error "$facet badarea_io failed"
13123                 else
13124                         skip_noexit "$facet: too old lustre for get_param -R"
13125                 fi
13126         done
13127
13128         # remount the FS in case writes/reads /proc break the FS
13129         cleanup || error "failed to unmount"
13130         setup || error "failed to setup"
13131 }
13132 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13133
13134 test_133h() {
13135         remote_mds_nodsh && skip "remote MDS with nodsh"
13136         remote_ost_nodsh && skip "remote OST with nodsh"
13137         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13138                 skip "Need MDS version at least 2.9.54"
13139
13140         local facet
13141         for facet in client mds1 ost1; do
13142                 # Get the list of files that are missing the terminating newline
13143                 local plist=$(do_facet $facet
13144                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13145                 local ent
13146                 for ent in $plist; do
13147                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13148                                 awk -v FS='\v' -v RS='\v\v' \
13149                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13150                                         print FILENAME}'" 2>/dev/null)
13151                         [ -z $missing ] || {
13152                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13153                                 error "file does not end with newline: $facet-$ent"
13154                         }
13155                 done
13156         done
13157 }
13158 run_test 133h "Proc files should end with newlines"
13159
13160 test_134a() {
13161         remote_mds_nodsh && skip "remote MDS with nodsh"
13162         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13163                 skip "Need MDS version at least 2.7.54"
13164
13165         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13166         cancel_lru_locks mdc
13167
13168         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13169         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13170         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13171
13172         local nr=1000
13173         createmany -o $DIR/$tdir/f $nr ||
13174                 error "failed to create $nr files in $DIR/$tdir"
13175         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13176
13177         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13178         do_facet mds1 $LCTL set_param fail_loc=0x327
13179         do_facet mds1 $LCTL set_param fail_val=500
13180         touch $DIR/$tdir/m
13181
13182         echo "sleep 10 seconds ..."
13183         sleep 10
13184         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13185
13186         do_facet mds1 $LCTL set_param fail_loc=0
13187         do_facet mds1 $LCTL set_param fail_val=0
13188         [ $lck_cnt -lt $unused ] ||
13189                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13190
13191         rm $DIR/$tdir/m
13192         unlinkmany $DIR/$tdir/f $nr
13193 }
13194 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13195
13196 test_134b() {
13197         remote_mds_nodsh && skip "remote MDS with nodsh"
13198         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13199                 skip "Need MDS version at least 2.7.54"
13200
13201         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13202         cancel_lru_locks mdc
13203
13204         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13205                         ldlm.lock_reclaim_threshold_mb)
13206         # disable reclaim temporarily
13207         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13208
13209         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13210         do_facet mds1 $LCTL set_param fail_loc=0x328
13211         do_facet mds1 $LCTL set_param fail_val=500
13212
13213         $LCTL set_param debug=+trace
13214
13215         local nr=600
13216         createmany -o $DIR/$tdir/f $nr &
13217         local create_pid=$!
13218
13219         echo "Sleep $TIMEOUT seconds ..."
13220         sleep $TIMEOUT
13221         if ! ps -p $create_pid  > /dev/null 2>&1; then
13222                 do_facet mds1 $LCTL set_param fail_loc=0
13223                 do_facet mds1 $LCTL set_param fail_val=0
13224                 do_facet mds1 $LCTL set_param \
13225                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13226                 error "createmany finished incorrectly!"
13227         fi
13228         do_facet mds1 $LCTL set_param fail_loc=0
13229         do_facet mds1 $LCTL set_param fail_val=0
13230         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13231         wait $create_pid || return 1
13232
13233         unlinkmany $DIR/$tdir/f $nr
13234 }
13235 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13236
13237 test_135() {
13238         remote_mds_nodsh && skip "remote MDS with nodsh"
13239         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13240                 skip "Need MDS version at least 2.13.50"
13241         local fname
13242
13243         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13244
13245 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13246         #set only one record at plain llog
13247         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13248
13249         #fill already existed plain llog each 64767
13250         #wrapping whole catalog
13251         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13252
13253         createmany -o $DIR/$tdir/$tfile_ 64700
13254         for (( i = 0; i < 64700; i = i + 2 ))
13255         do
13256                 rm $DIR/$tdir/$tfile_$i &
13257                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13258                 local pid=$!
13259                 wait $pid
13260         done
13261
13262         #waiting osp synchronization
13263         wait_delete_completed
13264 }
13265 run_test 135 "Race catalog processing"
13266
13267 test_136() {
13268         remote_mds_nodsh && skip "remote MDS with nodsh"
13269         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13270                 skip "Need MDS version at least 2.13.50"
13271         local fname
13272
13273         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13274         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13275         #set only one record at plain llog
13276 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13277         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13278
13279         #fill already existed 2 plain llogs each 64767
13280         #wrapping whole catalog
13281         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13282         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13283         wait_delete_completed
13284
13285         createmany -o $DIR/$tdir/$tfile_ 10
13286         sleep 25
13287
13288         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13289         for (( i = 0; i < 10; i = i + 3 ))
13290         do
13291                 rm $DIR/$tdir/$tfile_$i &
13292                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13293                 local pid=$!
13294                 wait $pid
13295                 sleep 7
13296                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13297         done
13298
13299         #waiting osp synchronization
13300         wait_delete_completed
13301 }
13302 run_test 136 "Race catalog processing 2"
13303
13304 test_140() { #bug-17379
13305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13306
13307         test_mkdir $DIR/$tdir
13308         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13309         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13310
13311         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13312         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13313         local i=0
13314         while i=$((i + 1)); do
13315                 test_mkdir $i
13316                 cd $i || error "Changing to $i"
13317                 ln -s ../stat stat || error "Creating stat symlink"
13318                 # Read the symlink until ELOOP present,
13319                 # not LBUGing the system is considered success,
13320                 # we didn't overrun the stack.
13321                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13322                 if [ $ret -ne 0 ]; then
13323                         if [ $ret -eq 40 ]; then
13324                                 break  # -ELOOP
13325                         else
13326                                 error "Open stat symlink"
13327                                         return
13328                         fi
13329                 fi
13330         done
13331         i=$((i - 1))
13332         echo "The symlink depth = $i"
13333         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13334                 error "Invalid symlink depth"
13335
13336         # Test recursive symlink
13337         ln -s symlink_self symlink_self
13338         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13339         echo "open symlink_self returns $ret"
13340         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13341 }
13342 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13343
13344 test_150a() {
13345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13346
13347         local TF="$TMP/$tfile"
13348
13349         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13350         cp $TF $DIR/$tfile
13351         cancel_lru_locks $OSC
13352         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13353         remount_client $MOUNT
13354         df -P $MOUNT
13355         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13356
13357         $TRUNCATE $TF 6000
13358         $TRUNCATE $DIR/$tfile 6000
13359         cancel_lru_locks $OSC
13360         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13361
13362         echo "12345" >>$TF
13363         echo "12345" >>$DIR/$tfile
13364         cancel_lru_locks $OSC
13365         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13366
13367         echo "12345" >>$TF
13368         echo "12345" >>$DIR/$tfile
13369         cancel_lru_locks $OSC
13370         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13371
13372         rm -f $TF
13373         true
13374 }
13375 run_test 150a "truncate/append tests"
13376
13377 test_150b() {
13378         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13379         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13380                 skip "Need OST version at least 2.13.53"
13381         touch $DIR/$tfile
13382         check_fallocate $DIR/$tfile || error "fallocate failed"
13383 }
13384 run_test 150b "Verify fallocate (prealloc) functionality"
13385
13386 test_150c() {
13387         local bytes
13388         local want
13389
13390         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13391         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13392                 skip "Need OST version at least 2.13.53"
13393
13394         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13395         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13396         sync; sync_all_data
13397         cancel_lru_locks $OSC
13398         sleep 5
13399         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13400         want=$((OSTCOUNT * 1048576))
13401
13402         # Must allocate all requested space, not more than 5% extra
13403         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13404                 error "bytes $bytes is not $want"
13405 }
13406 run_test 150c "Verify fallocate Size and Blocks"
13407
13408 test_150d() {
13409         local bytes
13410         local want
13411
13412         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13413         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13414                 skip "Need OST version at least 2.13.53"
13415
13416         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13417         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13418         sync; sync_all_data
13419         cancel_lru_locks $OSC
13420         sleep 5
13421         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13422         want=$((OSTCOUNT * 1048576))
13423
13424         # Must allocate all requested space, not more than 5% extra
13425         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13426                 error "bytes $bytes is not $want"
13427 }
13428 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13429
13430 test_150e() {
13431         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13432         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13433                 skip "Need OST version at least 2.13.55"
13434
13435         echo "df before:"
13436         $LFS df
13437         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13438                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13439
13440         # Find OST with Minimum Size
13441         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13442                        sort -un | head -1)
13443
13444         # Get 90% of the available space
13445         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13446
13447         fallocate -l${space}k $DIR/$tfile ||
13448                 error "fallocate ${space}k $DIR/$tfile failed"
13449         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13450
13451         # get size immediately after fallocate. This should be correctly
13452         # updated
13453         local size=$(stat -c '%s' $DIR/$tfile)
13454         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13455
13456         # Sleep for a while for statfs to get updated. And not pull from cache.
13457         sleep 2
13458
13459         echo "df after fallocate:"
13460         $LFS df
13461
13462         (( size / 1024 == space )) || error "size $size != requested $space"
13463         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13464                 error "used $used < space $space"
13465
13466         rm $DIR/$tfile || error "rm failed"
13467         sync
13468         wait_delete_completed
13469
13470         echo "df after unlink:"
13471         $LFS df
13472 }
13473 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13474
13475 #LU-2902 roc_hit was not able to read all values from lproc
13476 function roc_hit_init() {
13477         local list=$(comma_list $(osts_nodes))
13478         local dir=$DIR/$tdir-check
13479         local file=$dir/$tfile
13480         local BEFORE
13481         local AFTER
13482         local idx
13483
13484         test_mkdir $dir
13485         #use setstripe to do a write to every ost
13486         for i in $(seq 0 $((OSTCOUNT-1))); do
13487                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13488                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13489                 idx=$(printf %04x $i)
13490                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13491                         awk '$1 == "cache_access" {sum += $7}
13492                                 END { printf("%0.0f", sum) }')
13493
13494                 cancel_lru_locks osc
13495                 cat $file >/dev/null
13496
13497                 AFTER=$(get_osd_param $list *OST*$idx stats |
13498                         awk '$1 == "cache_access" {sum += $7}
13499                                 END { printf("%0.0f", sum) }')
13500
13501                 echo BEFORE:$BEFORE AFTER:$AFTER
13502                 if ! let "AFTER - BEFORE == 4"; then
13503                         rm -rf $dir
13504                         error "roc_hit is not safe to use"
13505                 fi
13506                 rm $file
13507         done
13508
13509         rm -rf $dir
13510 }
13511
13512 function roc_hit() {
13513         local list=$(comma_list $(osts_nodes))
13514         echo $(get_osd_param $list '' stats |
13515                 awk '$1 == "cache_hit" {sum += $7}
13516                         END { printf("%0.0f", sum) }')
13517 }
13518
13519 function set_cache() {
13520         local on=1
13521
13522         if [ "$2" == "off" ]; then
13523                 on=0;
13524         fi
13525         local list=$(comma_list $(osts_nodes))
13526         set_osd_param $list '' $1_cache_enable $on
13527
13528         cancel_lru_locks osc
13529 }
13530
13531 test_151() {
13532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13533         remote_ost_nodsh && skip "remote OST with nodsh"
13534
13535         local CPAGES=3
13536         local list=$(comma_list $(osts_nodes))
13537
13538         # check whether obdfilter is cache capable at all
13539         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13540                 skip "not cache-capable obdfilter"
13541         fi
13542
13543         # check cache is enabled on all obdfilters
13544         if get_osd_param $list '' read_cache_enable | grep 0; then
13545                 skip "oss cache is disabled"
13546         fi
13547
13548         set_osd_param $list '' writethrough_cache_enable 1
13549
13550         # check write cache is enabled on all obdfilters
13551         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13552                 skip "oss write cache is NOT enabled"
13553         fi
13554
13555         roc_hit_init
13556
13557         #define OBD_FAIL_OBD_NO_LRU  0x609
13558         do_nodes $list $LCTL set_param fail_loc=0x609
13559
13560         # pages should be in the case right after write
13561         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13562                 error "dd failed"
13563
13564         local BEFORE=$(roc_hit)
13565         cancel_lru_locks osc
13566         cat $DIR/$tfile >/dev/null
13567         local AFTER=$(roc_hit)
13568
13569         do_nodes $list $LCTL set_param fail_loc=0
13570
13571         if ! let "AFTER - BEFORE == CPAGES"; then
13572                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13573         fi
13574
13575         cancel_lru_locks osc
13576         # invalidates OST cache
13577         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13578         set_osd_param $list '' read_cache_enable 0
13579         cat $DIR/$tfile >/dev/null
13580
13581         # now data shouldn't be found in the cache
13582         BEFORE=$(roc_hit)
13583         cancel_lru_locks osc
13584         cat $DIR/$tfile >/dev/null
13585         AFTER=$(roc_hit)
13586         if let "AFTER - BEFORE != 0"; then
13587                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13588         fi
13589
13590         set_osd_param $list '' read_cache_enable 1
13591         rm -f $DIR/$tfile
13592 }
13593 run_test 151 "test cache on oss and controls ==============================="
13594
13595 test_152() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597
13598         local TF="$TMP/$tfile"
13599
13600         # simulate ENOMEM during write
13601 #define OBD_FAIL_OST_NOMEM      0x226
13602         lctl set_param fail_loc=0x80000226
13603         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13604         cp $TF $DIR/$tfile
13605         sync || error "sync failed"
13606         lctl set_param fail_loc=0
13607
13608         # discard client's cache
13609         cancel_lru_locks osc
13610
13611         # simulate ENOMEM during read
13612         lctl set_param fail_loc=0x80000226
13613         cmp $TF $DIR/$tfile || error "cmp failed"
13614         lctl set_param fail_loc=0
13615
13616         rm -f $TF
13617 }
13618 run_test 152 "test read/write with enomem ============================"
13619
13620 test_153() {
13621         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13622 }
13623 run_test 153 "test if fdatasync does not crash ======================="
13624
13625 dot_lustre_fid_permission_check() {
13626         local fid=$1
13627         local ffid=$MOUNT/.lustre/fid/$fid
13628         local test_dir=$2
13629
13630         echo "stat fid $fid"
13631         stat $ffid > /dev/null || error "stat $ffid failed."
13632         echo "touch fid $fid"
13633         touch $ffid || error "touch $ffid failed."
13634         echo "write to fid $fid"
13635         cat /etc/hosts > $ffid || error "write $ffid failed."
13636         echo "read fid $fid"
13637         diff /etc/hosts $ffid || error "read $ffid failed."
13638         echo "append write to fid $fid"
13639         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13640         echo "rename fid $fid"
13641         mv $ffid $test_dir/$tfile.1 &&
13642                 error "rename $ffid to $tfile.1 should fail."
13643         touch $test_dir/$tfile.1
13644         mv $test_dir/$tfile.1 $ffid &&
13645                 error "rename $tfile.1 to $ffid should fail."
13646         rm -f $test_dir/$tfile.1
13647         echo "truncate fid $fid"
13648         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13649         echo "link fid $fid"
13650         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13651         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13652                 echo "setfacl fid $fid"
13653                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13654                 echo "getfacl fid $fid"
13655                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13656         fi
13657         echo "unlink fid $fid"
13658         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13659         echo "mknod fid $fid"
13660         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13661
13662         fid=[0xf00000400:0x1:0x0]
13663         ffid=$MOUNT/.lustre/fid/$fid
13664
13665         echo "stat non-exist fid $fid"
13666         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13667         echo "write to non-exist fid $fid"
13668         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13669         echo "link new fid $fid"
13670         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13671
13672         mkdir -p $test_dir/$tdir
13673         touch $test_dir/$tdir/$tfile
13674         fid=$($LFS path2fid $test_dir/$tdir)
13675         rc=$?
13676         [ $rc -ne 0 ] &&
13677                 error "error: could not get fid for $test_dir/$dir/$tfile."
13678
13679         ffid=$MOUNT/.lustre/fid/$fid
13680
13681         echo "ls $fid"
13682         ls $ffid > /dev/null || error "ls $ffid failed."
13683         echo "touch $fid/$tfile.1"
13684         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13685
13686         echo "touch $MOUNT/.lustre/fid/$tfile"
13687         touch $MOUNT/.lustre/fid/$tfile && \
13688                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13689
13690         echo "setxattr to $MOUNT/.lustre/fid"
13691         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13692
13693         echo "listxattr for $MOUNT/.lustre/fid"
13694         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13695
13696         echo "delxattr from $MOUNT/.lustre/fid"
13697         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13698
13699         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13700         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13701                 error "touch invalid fid should fail."
13702
13703         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13704         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13705                 error "touch non-normal fid should fail."
13706
13707         echo "rename $tdir to $MOUNT/.lustre/fid"
13708         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13709                 error "rename to $MOUNT/.lustre/fid should fail."
13710
13711         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13712         then            # LU-3547
13713                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13714                 local new_obf_mode=777
13715
13716                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13717                 chmod $new_obf_mode $DIR/.lustre/fid ||
13718                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13719
13720                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13721                 [ $obf_mode -eq $new_obf_mode ] ||
13722                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13723
13724                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13725                 chmod $old_obf_mode $DIR/.lustre/fid ||
13726                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13727         fi
13728
13729         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13730         fid=$($LFS path2fid $test_dir/$tfile-2)
13731
13732         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13733         then # LU-5424
13734                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13735                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13736                         error "create lov data thru .lustre failed"
13737         fi
13738         echo "cp /etc/passwd $test_dir/$tfile-2"
13739         cp /etc/passwd $test_dir/$tfile-2 ||
13740                 error "copy to $test_dir/$tfile-2 failed."
13741         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13742         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13743                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13744
13745         rm -rf $test_dir/tfile.lnk
13746         rm -rf $test_dir/$tfile-2
13747 }
13748
13749 test_154A() {
13750         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13751                 skip "Need MDS version at least 2.4.1"
13752
13753         local tf=$DIR/$tfile
13754         touch $tf
13755
13756         local fid=$($LFS path2fid $tf)
13757         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13758
13759         # check that we get the same pathname back
13760         local rootpath
13761         local found
13762         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13763                 echo "$rootpath $fid"
13764                 found=$($LFS fid2path $rootpath "$fid")
13765                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13766                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13767         done
13768
13769         # check wrong root path format
13770         rootpath=$MOUNT"_wrong"
13771         found=$($LFS fid2path $rootpath "$fid")
13772         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13773 }
13774 run_test 154A "lfs path2fid and fid2path basic checks"
13775
13776 test_154B() {
13777         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13778                 skip "Need MDS version at least 2.4.1"
13779
13780         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13781         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13782         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13783         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13784
13785         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13786         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13787
13788         # check that we get the same pathname
13789         echo "PFID: $PFID, name: $name"
13790         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13791         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13792         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13793                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13794
13795         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13796 }
13797 run_test 154B "verify the ll_decode_linkea tool"
13798
13799 test_154a() {
13800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13801         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13802         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13803                 skip "Need MDS version at least 2.2.51"
13804         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13805
13806         cp /etc/hosts $DIR/$tfile
13807
13808         fid=$($LFS path2fid $DIR/$tfile)
13809         rc=$?
13810         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13811
13812         dot_lustre_fid_permission_check "$fid" $DIR ||
13813                 error "dot lustre permission check $fid failed"
13814
13815         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13816
13817         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13818
13819         touch $MOUNT/.lustre/file &&
13820                 error "creation is not allowed under .lustre"
13821
13822         mkdir $MOUNT/.lustre/dir &&
13823                 error "mkdir is not allowed under .lustre"
13824
13825         rm -rf $DIR/$tfile
13826 }
13827 run_test 154a "Open-by-FID"
13828
13829 test_154b() {
13830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13831         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13833         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13834                 skip "Need MDS version at least 2.2.51"
13835
13836         local remote_dir=$DIR/$tdir/remote_dir
13837         local MDTIDX=1
13838         local rc=0
13839
13840         mkdir -p $DIR/$tdir
13841         $LFS mkdir -i $MDTIDX $remote_dir ||
13842                 error "create remote directory failed"
13843
13844         cp /etc/hosts $remote_dir/$tfile
13845
13846         fid=$($LFS path2fid $remote_dir/$tfile)
13847         rc=$?
13848         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13849
13850         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13851                 error "dot lustre permission check $fid failed"
13852         rm -rf $DIR/$tdir
13853 }
13854 run_test 154b "Open-by-FID for remote directory"
13855
13856 test_154c() {
13857         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13858                 skip "Need MDS version at least 2.4.1"
13859
13860         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13861         local FID1=$($LFS path2fid $DIR/$tfile.1)
13862         local FID2=$($LFS path2fid $DIR/$tfile.2)
13863         local FID3=$($LFS path2fid $DIR/$tfile.3)
13864
13865         local N=1
13866         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13867                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13868                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13869                 local want=FID$N
13870                 [ "$FID" = "${!want}" ] ||
13871                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13872                 N=$((N + 1))
13873         done
13874
13875         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13876         do
13877                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13878                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13879                 N=$((N + 1))
13880         done
13881 }
13882 run_test 154c "lfs path2fid and fid2path multiple arguments"
13883
13884 test_154d() {
13885         remote_mds_nodsh && skip "remote MDS with nodsh"
13886         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13887                 skip "Need MDS version at least 2.5.53"
13888
13889         if remote_mds; then
13890                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13891         else
13892                 nid="0@lo"
13893         fi
13894         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13895         local fd
13896         local cmd
13897
13898         rm -f $DIR/$tfile
13899         touch $DIR/$tfile
13900
13901         local fid=$($LFS path2fid $DIR/$tfile)
13902         # Open the file
13903         fd=$(free_fd)
13904         cmd="exec $fd<$DIR/$tfile"
13905         eval $cmd
13906         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13907         echo "$fid_list" | grep "$fid"
13908         rc=$?
13909
13910         cmd="exec $fd>/dev/null"
13911         eval $cmd
13912         if [ $rc -ne 0 ]; then
13913                 error "FID $fid not found in open files list $fid_list"
13914         fi
13915 }
13916 run_test 154d "Verify open file fid"
13917
13918 test_154e()
13919 {
13920         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13921                 skip "Need MDS version at least 2.6.50"
13922
13923         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13924                 error ".lustre returned by readdir"
13925         fi
13926 }
13927 run_test 154e ".lustre is not returned by readdir"
13928
13929 test_154f() {
13930         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13931
13932         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13933         test_mkdir -p -c1 $DIR/$tdir/d
13934         # test dirs inherit from its stripe
13935         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13936         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13937         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13938         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13939         touch $DIR/f
13940
13941         # get fid of parents
13942         local FID0=$($LFS path2fid $DIR/$tdir/d)
13943         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13944         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13945         local FID3=$($LFS path2fid $DIR)
13946
13947         # check that path2fid --parents returns expected <parent_fid>/name
13948         # 1) test for a directory (single parent)
13949         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13950         [ "$parent" == "$FID0/foo1" ] ||
13951                 error "expected parent: $FID0/foo1, got: $parent"
13952
13953         # 2) test for a file with nlink > 1 (multiple parents)
13954         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13955         echo "$parent" | grep -F "$FID1/$tfile" ||
13956                 error "$FID1/$tfile not returned in parent list"
13957         echo "$parent" | grep -F "$FID2/link" ||
13958                 error "$FID2/link not returned in parent list"
13959
13960         # 3) get parent by fid
13961         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13962         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13963         echo "$parent" | grep -F "$FID1/$tfile" ||
13964                 error "$FID1/$tfile not returned in parent list (by fid)"
13965         echo "$parent" | grep -F "$FID2/link" ||
13966                 error "$FID2/link not returned in parent list (by fid)"
13967
13968         # 4) test for entry in root directory
13969         parent=$($LFS path2fid --parents $DIR/f)
13970         echo "$parent" | grep -F "$FID3/f" ||
13971                 error "$FID3/f not returned in parent list"
13972
13973         # 5) test it on root directory
13974         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13975                 error "$MOUNT should not have parents"
13976
13977         # enable xattr caching and check that linkea is correctly updated
13978         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13979         save_lustre_params client "llite.*.xattr_cache" > $save
13980         lctl set_param llite.*.xattr_cache 1
13981
13982         # 6.1) linkea update on rename
13983         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13984
13985         # get parents by fid
13986         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13987         # foo1 should no longer be returned in parent list
13988         echo "$parent" | grep -F "$FID1" &&
13989                 error "$FID1 should no longer be in parent list"
13990         # the new path should appear
13991         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13992                 error "$FID2/$tfile.moved is not in parent list"
13993
13994         # 6.2) linkea update on unlink
13995         rm -f $DIR/$tdir/d/foo2/link
13996         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13997         # foo2/link should no longer be returned in parent list
13998         echo "$parent" | grep -F "$FID2/link" &&
13999                 error "$FID2/link should no longer be in parent list"
14000         true
14001
14002         rm -f $DIR/f
14003         restore_lustre_params < $save
14004         rm -f $save
14005 }
14006 run_test 154f "get parent fids by reading link ea"
14007
14008 test_154g()
14009 {
14010         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14011         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14012            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14013                 skip "Need MDS version at least 2.6.92"
14014
14015         mkdir -p $DIR/$tdir
14016         llapi_fid_test -d $DIR/$tdir
14017 }
14018 run_test 154g "various llapi FID tests"
14019
14020 test_155_small_load() {
14021     local temp=$TMP/$tfile
14022     local file=$DIR/$tfile
14023
14024     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14025         error "dd of=$temp bs=6096 count=1 failed"
14026     cp $temp $file
14027     cancel_lru_locks $OSC
14028     cmp $temp $file || error "$temp $file differ"
14029
14030     $TRUNCATE $temp 6000
14031     $TRUNCATE $file 6000
14032     cmp $temp $file || error "$temp $file differ (truncate1)"
14033
14034     echo "12345" >>$temp
14035     echo "12345" >>$file
14036     cmp $temp $file || error "$temp $file differ (append1)"
14037
14038     echo "12345" >>$temp
14039     echo "12345" >>$file
14040     cmp $temp $file || error "$temp $file differ (append2)"
14041
14042     rm -f $temp $file
14043     true
14044 }
14045
14046 test_155_big_load() {
14047         remote_ost_nodsh && skip "remote OST with nodsh"
14048
14049         local temp=$TMP/$tfile
14050         local file=$DIR/$tfile
14051
14052         free_min_max
14053         local cache_size=$(do_facet ost$((MAXI+1)) \
14054                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14055         local large_file_size=$((cache_size * 2))
14056
14057         echo "OSS cache size: $cache_size KB"
14058         echo "Large file size: $large_file_size KB"
14059
14060         [ $MAXV -le $large_file_size ] &&
14061                 skip_env "max available OST size needs > $large_file_size KB"
14062
14063         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14064
14065         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14066                 error "dd of=$temp bs=$large_file_size count=1k failed"
14067         cp $temp $file
14068         ls -lh $temp $file
14069         cancel_lru_locks osc
14070         cmp $temp $file || error "$temp $file differ"
14071
14072         rm -f $temp $file
14073         true
14074 }
14075
14076 save_writethrough() {
14077         local facets=$(get_facets OST)
14078
14079         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14080 }
14081
14082 test_155a() {
14083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14084
14085         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14086
14087         save_writethrough $p
14088
14089         set_cache read on
14090         set_cache writethrough on
14091         test_155_small_load
14092         restore_lustre_params < $p
14093         rm -f $p
14094 }
14095 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14096
14097 test_155b() {
14098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14099
14100         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14101
14102         save_writethrough $p
14103
14104         set_cache read on
14105         set_cache writethrough off
14106         test_155_small_load
14107         restore_lustre_params < $p
14108         rm -f $p
14109 }
14110 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14111
14112 test_155c() {
14113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14114
14115         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14116
14117         save_writethrough $p
14118
14119         set_cache read off
14120         set_cache writethrough on
14121         test_155_small_load
14122         restore_lustre_params < $p
14123         rm -f $p
14124 }
14125 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14126
14127 test_155d() {
14128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14129
14130         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14131
14132         save_writethrough $p
14133
14134         set_cache read off
14135         set_cache writethrough off
14136         test_155_small_load
14137         restore_lustre_params < $p
14138         rm -f $p
14139 }
14140 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14141
14142 test_155e() {
14143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14144
14145         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14146
14147         save_writethrough $p
14148
14149         set_cache read on
14150         set_cache writethrough on
14151         test_155_big_load
14152         restore_lustre_params < $p
14153         rm -f $p
14154 }
14155 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14156
14157 test_155f() {
14158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14159
14160         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14161
14162         save_writethrough $p
14163
14164         set_cache read on
14165         set_cache writethrough off
14166         test_155_big_load
14167         restore_lustre_params < $p
14168         rm -f $p
14169 }
14170 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14171
14172 test_155g() {
14173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14174
14175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14176
14177         save_writethrough $p
14178
14179         set_cache read off
14180         set_cache writethrough on
14181         test_155_big_load
14182         restore_lustre_params < $p
14183         rm -f $p
14184 }
14185 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14186
14187 test_155h() {
14188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14189
14190         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14191
14192         save_writethrough $p
14193
14194         set_cache read off
14195         set_cache writethrough off
14196         test_155_big_load
14197         restore_lustre_params < $p
14198         rm -f $p
14199 }
14200 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14201
14202 test_156() {
14203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14204         remote_ost_nodsh && skip "remote OST with nodsh"
14205         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14206                 skip "stats not implemented on old servers"
14207         [ "$ost1_FSTYPE" = "zfs" ] &&
14208                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14209
14210         local CPAGES=3
14211         local BEFORE
14212         local AFTER
14213         local file="$DIR/$tfile"
14214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14215
14216         save_writethrough $p
14217         roc_hit_init
14218
14219         log "Turn on read and write cache"
14220         set_cache read on
14221         set_cache writethrough on
14222
14223         log "Write data and read it back."
14224         log "Read should be satisfied from the cache."
14225         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14226         BEFORE=$(roc_hit)
14227         cancel_lru_locks osc
14228         cat $file >/dev/null
14229         AFTER=$(roc_hit)
14230         if ! let "AFTER - BEFORE == CPAGES"; then
14231                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14232         else
14233                 log "cache hits: before: $BEFORE, after: $AFTER"
14234         fi
14235
14236         log "Read again; it should be satisfied from the cache."
14237         BEFORE=$AFTER
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 (3): before: $BEFORE, after: $AFTER"
14243         else
14244                 log "cache hits:: before: $BEFORE, after: $AFTER"
14245         fi
14246
14247         log "Turn off the read cache and turn on the write cache"
14248         set_cache read off
14249         set_cache writethrough on
14250
14251         log "Read again; it should be satisfied from the cache."
14252         BEFORE=$(roc_hit)
14253         cancel_lru_locks osc
14254         cat $file >/dev/null
14255         AFTER=$(roc_hit)
14256         if ! let "AFTER - BEFORE == CPAGES"; then
14257                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14258         else
14259                 log "cache hits:: before: $BEFORE, after: $AFTER"
14260         fi
14261
14262         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14263                 # > 2.12.56 uses pagecache if cached
14264                 log "Read again; it should not be satisfied from the cache."
14265                 BEFORE=$AFTER
14266                 cancel_lru_locks osc
14267                 cat $file >/dev/null
14268                 AFTER=$(roc_hit)
14269                 if ! let "AFTER - BEFORE == 0"; then
14270                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14271                 else
14272                         log "cache hits:: before: $BEFORE, after: $AFTER"
14273                 fi
14274         fi
14275
14276         log "Write data and read it back."
14277         log "Read should be satisfied from the cache."
14278         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14279         BEFORE=$(roc_hit)
14280         cancel_lru_locks osc
14281         cat $file >/dev/null
14282         AFTER=$(roc_hit)
14283         if ! let "AFTER - BEFORE == CPAGES"; then
14284                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14285         else
14286                 log "cache hits:: before: $BEFORE, after: $AFTER"
14287         fi
14288
14289         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14290                 # > 2.12.56 uses pagecache if cached
14291                 log "Read again; it should not be satisfied from the cache."
14292                 BEFORE=$AFTER
14293                 cancel_lru_locks osc
14294                 cat $file >/dev/null
14295                 AFTER=$(roc_hit)
14296                 if ! let "AFTER - BEFORE == 0"; then
14297                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14298                 else
14299                         log "cache hits:: before: $BEFORE, after: $AFTER"
14300                 fi
14301         fi
14302
14303         log "Turn off read and write cache"
14304         set_cache read off
14305         set_cache writethrough off
14306
14307         log "Write data and read it back"
14308         log "It should not be satisfied from the cache."
14309         rm -f $file
14310         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14311         cancel_lru_locks osc
14312         BEFORE=$(roc_hit)
14313         cat $file >/dev/null
14314         AFTER=$(roc_hit)
14315         if ! let "AFTER - BEFORE == 0"; then
14316                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14317         else
14318                 log "cache hits:: before: $BEFORE, after: $AFTER"
14319         fi
14320
14321         log "Turn on the read cache and turn off the write cache"
14322         set_cache read on
14323         set_cache writethrough off
14324
14325         log "Write data and read it back"
14326         log "It should not be satisfied from the cache."
14327         rm -f $file
14328         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14329         BEFORE=$(roc_hit)
14330         cancel_lru_locks osc
14331         cat $file >/dev/null
14332         AFTER=$(roc_hit)
14333         if ! let "AFTER - BEFORE == 0"; then
14334                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14335         else
14336                 log "cache hits:: before: $BEFORE, after: $AFTER"
14337         fi
14338
14339         log "Read again; it should be satisfied from the cache."
14340         BEFORE=$(roc_hit)
14341         cancel_lru_locks osc
14342         cat $file >/dev/null
14343         AFTER=$(roc_hit)
14344         if ! let "AFTER - BEFORE == CPAGES"; then
14345                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14346         else
14347                 log "cache hits:: before: $BEFORE, after: $AFTER"
14348         fi
14349
14350         restore_lustre_params < $p
14351         rm -f $p $file
14352 }
14353 run_test 156 "Verification of tunables"
14354
14355 test_160a() {
14356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14357         remote_mds_nodsh && skip "remote MDS with nodsh"
14358         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14359                 skip "Need MDS version at least 2.2.0"
14360
14361         changelog_register || error "changelog_register failed"
14362         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14363         changelog_users $SINGLEMDS | grep -q $cl_user ||
14364                 error "User $cl_user not found in changelog_users"
14365
14366         # change something
14367         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14368         changelog_clear 0 || error "changelog_clear failed"
14369         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14370         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14371         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14372         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14373         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14374         rm $DIR/$tdir/pics/desktop.jpg
14375
14376         changelog_dump | tail -10
14377
14378         echo "verifying changelog mask"
14379         changelog_chmask "-MKDIR"
14380         changelog_chmask "-CLOSE"
14381
14382         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14383         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14384
14385         changelog_chmask "+MKDIR"
14386         changelog_chmask "+CLOSE"
14387
14388         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14389         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14390
14391         changelog_dump | tail -10
14392         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14393         CLOSES=$(changelog_dump | grep -c "CLOSE")
14394         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14395         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14396
14397         # verify contents
14398         echo "verifying target fid"
14399         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14400         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14401         [ "$fidc" == "$fidf" ] ||
14402                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14403         echo "verifying parent fid"
14404         # The FID returned from the Changelog may be the directory shard on
14405         # a different MDT, and not the FID returned by path2fid on the parent.
14406         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14407         # since this is what will matter when recreating this file in the tree.
14408         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14409         local pathp=$($LFS fid2path $MOUNT "$fidp")
14410         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14411                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14412
14413         echo "getting records for $cl_user"
14414         changelog_users $SINGLEMDS
14415         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14416         local nclr=3
14417         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14418                 error "changelog_clear failed"
14419         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14420         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14421         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14422                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14423
14424         local min0_rec=$(changelog_users $SINGLEMDS |
14425                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14426         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14427                           awk '{ print $1; exit; }')
14428
14429         changelog_dump | tail -n 5
14430         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14431         [ $first_rec == $((min0_rec + 1)) ] ||
14432                 error "first index should be $min0_rec + 1 not $first_rec"
14433
14434         # LU-3446 changelog index reset on MDT restart
14435         local cur_rec1=$(changelog_users $SINGLEMDS |
14436                          awk '/^current.index:/ { print $NF }')
14437         changelog_clear 0 ||
14438                 error "clear all changelog records for $cl_user failed"
14439         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14440         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14441                 error "Fail to start $SINGLEMDS"
14442         local cur_rec2=$(changelog_users $SINGLEMDS |
14443                          awk '/^current.index:/ { print $NF }')
14444         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14445         [ $cur_rec1 == $cur_rec2 ] ||
14446                 error "current index should be $cur_rec1 not $cur_rec2"
14447
14448         echo "verifying users from this test are deregistered"
14449         changelog_deregister || error "changelog_deregister failed"
14450         changelog_users $SINGLEMDS | grep -q $cl_user &&
14451                 error "User '$cl_user' still in changelog_users"
14452
14453         # lctl get_param -n mdd.*.changelog_users
14454         # current index: 144
14455         # ID    index (idle seconds)
14456         # cl3   144 (2)
14457         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14458                 # this is the normal case where all users were deregistered
14459                 # make sure no new records are added when no users are present
14460                 local last_rec1=$(changelog_users $SINGLEMDS |
14461                                   awk '/^current.index:/ { print $NF }')
14462                 touch $DIR/$tdir/chloe
14463                 local last_rec2=$(changelog_users $SINGLEMDS |
14464                                   awk '/^current.index:/ { print $NF }')
14465                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14466                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14467         else
14468                 # any changelog users must be leftovers from a previous test
14469                 changelog_users $SINGLEMDS
14470                 echo "other changelog users; can't verify off"
14471         fi
14472 }
14473 run_test 160a "changelog sanity"
14474
14475 test_160b() { # LU-3587
14476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14477         remote_mds_nodsh && skip "remote MDS with nodsh"
14478         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14479                 skip "Need MDS version at least 2.2.0"
14480
14481         changelog_register || error "changelog_register failed"
14482         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14483         changelog_users $SINGLEMDS | grep -q $cl_user ||
14484                 error "User '$cl_user' not found in changelog_users"
14485
14486         local longname1=$(str_repeat a 255)
14487         local longname2=$(str_repeat b 255)
14488
14489         cd $DIR
14490         echo "creating very long named file"
14491         touch $longname1 || error "create of '$longname1' failed"
14492         echo "renaming very long named file"
14493         mv $longname1 $longname2
14494
14495         changelog_dump | grep RENME | tail -n 5
14496         rm -f $longname2
14497 }
14498 run_test 160b "Verify that very long rename doesn't crash in changelog"
14499
14500 test_160c() {
14501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14502         remote_mds_nodsh && skip "remote MDS with nodsh"
14503
14504         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14505                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14506                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14507                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14508
14509         local rc=0
14510
14511         # Registration step
14512         changelog_register || error "changelog_register failed"
14513
14514         rm -rf $DIR/$tdir
14515         mkdir -p $DIR/$tdir
14516         $MCREATE $DIR/$tdir/foo_160c
14517         changelog_chmask "-TRUNC"
14518         $TRUNCATE $DIR/$tdir/foo_160c 200
14519         changelog_chmask "+TRUNC"
14520         $TRUNCATE $DIR/$tdir/foo_160c 199
14521         changelog_dump | tail -n 5
14522         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14523         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14524 }
14525 run_test 160c "verify that changelog log catch the truncate event"
14526
14527 test_160d() {
14528         remote_mds_nodsh && skip "remote MDS with nodsh"
14529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14531         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14532                 skip "Need MDS version at least 2.7.60"
14533
14534         # Registration step
14535         changelog_register || error "changelog_register failed"
14536
14537         mkdir -p $DIR/$tdir/migrate_dir
14538         changelog_clear 0 || error "changelog_clear failed"
14539
14540         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14541         changelog_dump | tail -n 5
14542         local migrates=$(changelog_dump | grep -c "MIGRT")
14543         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14544 }
14545 run_test 160d "verify that changelog log catch the migrate event"
14546
14547 test_160e() {
14548         remote_mds_nodsh && skip "remote MDS with nodsh"
14549
14550         # Create a user
14551         changelog_register || error "changelog_register failed"
14552
14553         # Delete a future user (expect fail)
14554         local MDT0=$(facet_svc $SINGLEMDS)
14555         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14556         local rc=$?
14557
14558         if [ $rc -eq 0 ]; then
14559                 error "Deleted non-existant user cl77"
14560         elif [ $rc -ne 2 ]; then
14561                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14562         fi
14563
14564         # Clear to a bad index (1 billion should be safe)
14565         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14566         rc=$?
14567
14568         if [ $rc -eq 0 ]; then
14569                 error "Successfully cleared to invalid CL index"
14570         elif [ $rc -ne 22 ]; then
14571                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14572         fi
14573 }
14574 run_test 160e "changelog negative testing (should return errors)"
14575
14576 test_160f() {
14577         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14578         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14579                 skip "Need MDS version at least 2.10.56"
14580
14581         local mdts=$(comma_list $(mdts_nodes))
14582
14583         # Create a user
14584         changelog_register || error "first changelog_register failed"
14585         changelog_register || error "second changelog_register failed"
14586         local cl_users
14587         declare -A cl_user1
14588         declare -A cl_user2
14589         local user_rec1
14590         local user_rec2
14591         local i
14592
14593         # generate some changelog records to accumulate on each MDT
14594         # use fnv1a because created files should be evenly distributed
14595         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14596                 error "test_mkdir $tdir failed"
14597         log "$(date +%s): creating first files"
14598         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14599                 error "create $DIR/$tdir/$tfile failed"
14600
14601         # check changelogs have been generated
14602         local start=$SECONDS
14603         local idle_time=$((MDSCOUNT * 5 + 5))
14604         local nbcl=$(changelog_dump | wc -l)
14605         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14606
14607         for param in "changelog_max_idle_time=$idle_time" \
14608                      "changelog_gc=1" \
14609                      "changelog_min_gc_interval=2" \
14610                      "changelog_min_free_cat_entries=3"; do
14611                 local MDT0=$(facet_svc $SINGLEMDS)
14612                 local var="${param%=*}"
14613                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14614
14615                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14616                 do_nodes $mdts $LCTL set_param mdd.*.$param
14617         done
14618
14619         # force cl_user2 to be idle (1st part), but also cancel the
14620         # cl_user1 records so that it is not evicted later in the test.
14621         local sleep1=$((idle_time / 2))
14622         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14623         sleep $sleep1
14624
14625         # simulate changelog catalog almost full
14626         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14627         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14628
14629         for i in $(seq $MDSCOUNT); do
14630                 cl_users=(${CL_USERS[mds$i]})
14631                 cl_user1[mds$i]="${cl_users[0]}"
14632                 cl_user2[mds$i]="${cl_users[1]}"
14633
14634                 [ -n "${cl_user1[mds$i]}" ] ||
14635                         error "mds$i: no user registered"
14636                 [ -n "${cl_user2[mds$i]}" ] ||
14637                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14638
14639                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14640                 [ -n "$user_rec1" ] ||
14641                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14642                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14643                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14644                 [ -n "$user_rec2" ] ||
14645                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14646                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14647                      "$user_rec1 + 2 == $user_rec2"
14648                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14649                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14650                               "$user_rec1 + 2, but is $user_rec2"
14651                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14652                 [ -n "$user_rec2" ] ||
14653                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14654                 [ $user_rec1 == $user_rec2 ] ||
14655                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14656                               "$user_rec1, but is $user_rec2"
14657         done
14658
14659         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14660         local sleep2=$((idle_time - (SECONDS - start) + 1))
14661         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14662         sleep $sleep2
14663
14664         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14665         # cl_user1 should be OK because it recently processed records.
14666         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14667         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14668                 error "create $DIR/$tdir/${tfile}b failed"
14669
14670         # ensure gc thread is done
14671         for i in $(mdts_nodes); do
14672                 wait_update $i \
14673                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14674                         error "$i: GC-thread not done"
14675         done
14676
14677         local first_rec
14678         for i in $(seq $MDSCOUNT); do
14679                 # check cl_user1 still registered
14680                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14681                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14682                 # check cl_user2 unregistered
14683                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14684                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14685
14686                 # check changelogs are present and starting at $user_rec1 + 1
14687                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14688                 [ -n "$user_rec1" ] ||
14689                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14690                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14691                             awk '{ print $1; exit; }')
14692
14693                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14694                 [ $((user_rec1 + 1)) == $first_rec ] ||
14695                         error "mds$i: first index should be $user_rec1 + 1, " \
14696                               "but is $first_rec"
14697         done
14698 }
14699 run_test 160f "changelog garbage collect (timestamped users)"
14700
14701 test_160g() {
14702         remote_mds_nodsh && skip "remote MDS with nodsh"
14703         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14704                 skip "Need MDS version at least 2.10.56"
14705
14706         local mdts=$(comma_list $(mdts_nodes))
14707
14708         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14709         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14710
14711         # Create a user
14712         changelog_register || error "first changelog_register failed"
14713         changelog_register || error "second changelog_register failed"
14714         local cl_users
14715         declare -A cl_user1
14716         declare -A cl_user2
14717         local user_rec1
14718         local user_rec2
14719         local i
14720
14721         # generate some changelog records to accumulate on each MDT
14722         # use fnv1a because created files should be evenly distributed
14723         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14724                 error "mkdir $tdir failed"
14725         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14726                 error "create $DIR/$tdir/$tfile failed"
14727
14728         # check changelogs have been generated
14729         local nbcl=$(changelog_dump | wc -l)
14730         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14731
14732         # reduce the max_idle_indexes value to make sure we exceed it
14733         max_ndx=$((nbcl / 2 - 1))
14734
14735         for param in "changelog_max_idle_indexes=$max_ndx" \
14736                      "changelog_gc=1" \
14737                      "changelog_min_gc_interval=2" \
14738                      "changelog_min_free_cat_entries=3"; do
14739                 local MDT0=$(facet_svc $SINGLEMDS)
14740                 local var="${param%=*}"
14741                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14742
14743                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14744                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14745                         error "unable to set mdd.*.$param"
14746         done
14747
14748         # simulate changelog catalog almost full
14749         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14750         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14751
14752         for i in $(seq $MDSCOUNT); do
14753                 cl_users=(${CL_USERS[mds$i]})
14754                 cl_user1[mds$i]="${cl_users[0]}"
14755                 cl_user2[mds$i]="${cl_users[1]}"
14756
14757                 [ -n "${cl_user1[mds$i]}" ] ||
14758                         error "mds$i: no user registered"
14759                 [ -n "${cl_user2[mds$i]}" ] ||
14760                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14761
14762                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14763                 [ -n "$user_rec1" ] ||
14764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14765                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14766                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14767                 [ -n "$user_rec2" ] ||
14768                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14769                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14770                      "$user_rec1 + 2 == $user_rec2"
14771                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14772                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14773                               "$user_rec1 + 2, but is $user_rec2"
14774                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14775                 [ -n "$user_rec2" ] ||
14776                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14777                 [ $user_rec1 == $user_rec2 ] ||
14778                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14779                               "$user_rec1, but is $user_rec2"
14780         done
14781
14782         # ensure we are past the previous changelog_min_gc_interval set above
14783         sleep 2
14784
14785         # generate one more changelog to trigger fail_loc
14786         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14787                 error "create $DIR/$tdir/${tfile}bis failed"
14788
14789         # ensure gc thread is done
14790         for i in $(mdts_nodes); do
14791                 wait_update $i \
14792                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14793                         error "$i: GC-thread not done"
14794         done
14795
14796         local first_rec
14797         for i in $(seq $MDSCOUNT); do
14798                 # check cl_user1 still registered
14799                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14800                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14801                 # check cl_user2 unregistered
14802                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14803                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14804
14805                 # check changelogs are present and starting at $user_rec1 + 1
14806                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14807                 [ -n "$user_rec1" ] ||
14808                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14809                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14810                             awk '{ print $1; exit; }')
14811
14812                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14813                 [ $((user_rec1 + 1)) == $first_rec ] ||
14814                         error "mds$i: first index should be $user_rec1 + 1, " \
14815                               "but is $first_rec"
14816         done
14817 }
14818 run_test 160g "changelog garbage collect (old users)"
14819
14820 test_160h() {
14821         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14822         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14823                 skip "Need MDS version at least 2.10.56"
14824
14825         local mdts=$(comma_list $(mdts_nodes))
14826
14827         # Create a user
14828         changelog_register || error "first changelog_register failed"
14829         changelog_register || error "second changelog_register failed"
14830         local cl_users
14831         declare -A cl_user1
14832         declare -A cl_user2
14833         local user_rec1
14834         local user_rec2
14835         local i
14836
14837         # generate some changelog records to accumulate on each MDT
14838         # use fnv1a because created files should be evenly distributed
14839         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14840                 error "test_mkdir $tdir failed"
14841         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14842                 error "create $DIR/$tdir/$tfile failed"
14843
14844         # check changelogs have been generated
14845         local nbcl=$(changelog_dump | wc -l)
14846         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14847
14848         for param in "changelog_max_idle_time=10" \
14849                      "changelog_gc=1" \
14850                      "changelog_min_gc_interval=2"; do
14851                 local MDT0=$(facet_svc $SINGLEMDS)
14852                 local var="${param%=*}"
14853                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14854
14855                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14856                 do_nodes $mdts $LCTL set_param mdd.*.$param
14857         done
14858
14859         # force cl_user2 to be idle (1st part)
14860         sleep 9
14861
14862         for i in $(seq $MDSCOUNT); do
14863                 cl_users=(${CL_USERS[mds$i]})
14864                 cl_user1[mds$i]="${cl_users[0]}"
14865                 cl_user2[mds$i]="${cl_users[1]}"
14866
14867                 [ -n "${cl_user1[mds$i]}" ] ||
14868                         error "mds$i: no user registered"
14869                 [ -n "${cl_user2[mds$i]}" ] ||
14870                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14871
14872                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14873                 [ -n "$user_rec1" ] ||
14874                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14875                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14876                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14877                 [ -n "$user_rec2" ] ||
14878                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14879                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14880                      "$user_rec1 + 2 == $user_rec2"
14881                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14882                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14883                               "$user_rec1 + 2, but is $user_rec2"
14884                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14885                 [ -n "$user_rec2" ] ||
14886                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14887                 [ $user_rec1 == $user_rec2 ] ||
14888                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14889                               "$user_rec1, but is $user_rec2"
14890         done
14891
14892         # force cl_user2 to be idle (2nd part) and to reach
14893         # changelog_max_idle_time
14894         sleep 2
14895
14896         # force each GC-thread start and block then
14897         # one per MDT/MDD, set fail_val accordingly
14898         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14899         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14900
14901         # generate more changelogs to trigger fail_loc
14902         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14903                 error "create $DIR/$tdir/${tfile}bis failed"
14904
14905         # stop MDT to stop GC-thread, should be done in back-ground as it will
14906         # block waiting for the thread to be released and exit
14907         declare -A stop_pids
14908         for i in $(seq $MDSCOUNT); do
14909                 stop mds$i &
14910                 stop_pids[mds$i]=$!
14911         done
14912
14913         for i in $(mdts_nodes); do
14914                 local facet
14915                 local nb=0
14916                 local facets=$(facets_up_on_host $i)
14917
14918                 for facet in ${facets//,/ }; do
14919                         if [[ $facet == mds* ]]; then
14920                                 nb=$((nb + 1))
14921                         fi
14922                 done
14923                 # ensure each MDS's gc threads are still present and all in "R"
14924                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14925                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14926                         error "$i: expected $nb GC-thread"
14927                 wait_update $i \
14928                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14929                         "R" 20 ||
14930                         error "$i: GC-thread not found in R-state"
14931                 # check umounts of each MDT on MDS have reached kthread_stop()
14932                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14933                         error "$i: expected $nb umount"
14934                 wait_update $i \
14935                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14936                         error "$i: umount not found in D-state"
14937         done
14938
14939         # release all GC-threads
14940         do_nodes $mdts $LCTL set_param fail_loc=0
14941
14942         # wait for MDT stop to complete
14943         for i in $(seq $MDSCOUNT); do
14944                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14945         done
14946
14947         # XXX
14948         # may try to check if any orphan changelog records are present
14949         # via ldiskfs/zfs and llog_reader...
14950
14951         # re-start/mount MDTs
14952         for i in $(seq $MDSCOUNT); do
14953                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14954                         error "Fail to start mds$i"
14955         done
14956
14957         local first_rec
14958         for i in $(seq $MDSCOUNT); do
14959                 # check cl_user1 still registered
14960                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14961                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14962                 # check cl_user2 unregistered
14963                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14964                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14965
14966                 # check changelogs are present and starting at $user_rec1 + 1
14967                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14968                 [ -n "$user_rec1" ] ||
14969                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14970                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14971                             awk '{ print $1; exit; }')
14972
14973                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14974                 [ $((user_rec1 + 1)) == $first_rec ] ||
14975                         error "mds$i: first index should be $user_rec1 + 1, " \
14976                               "but is $first_rec"
14977         done
14978 }
14979 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14980               "during mount"
14981
14982 test_160i() {
14983
14984         local mdts=$(comma_list $(mdts_nodes))
14985
14986         changelog_register || error "first changelog_register failed"
14987
14988         # generate some changelog records to accumulate on each MDT
14989         # use fnv1a because created files should be evenly distributed
14990         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14991                 error "mkdir $tdir failed"
14992         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14993                 error "create $DIR/$tdir/$tfile failed"
14994
14995         # check changelogs have been generated
14996         local nbcl=$(changelog_dump | wc -l)
14997         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14998
14999         # simulate race between register and unregister
15000         # XXX as fail_loc is set per-MDS, with DNE configs the race
15001         # simulation will only occur for one MDT per MDS and for the
15002         # others the normal race scenario will take place
15003         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15004         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15005         do_nodes $mdts $LCTL set_param fail_val=1
15006
15007         # unregister 1st user
15008         changelog_deregister &
15009         local pid1=$!
15010         # wait some time for deregister work to reach race rdv
15011         sleep 2
15012         # register 2nd user
15013         changelog_register || error "2nd user register failed"
15014
15015         wait $pid1 || error "1st user deregister failed"
15016
15017         local i
15018         local last_rec
15019         declare -A LAST_REC
15020         for i in $(seq $MDSCOUNT); do
15021                 if changelog_users mds$i | grep "^cl"; then
15022                         # make sure new records are added with one user present
15023                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15024                                           awk '/^current.index:/ { print $NF }')
15025                 else
15026                         error "mds$i has no user registered"
15027                 fi
15028         done
15029
15030         # generate more changelog records to accumulate on each MDT
15031         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15032                 error "create $DIR/$tdir/${tfile}bis failed"
15033
15034         for i in $(seq $MDSCOUNT); do
15035                 last_rec=$(changelog_users $SINGLEMDS |
15036                            awk '/^current.index:/ { print $NF }')
15037                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15038                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15039                         error "changelogs are off on mds$i"
15040         done
15041 }
15042 run_test 160i "changelog user register/unregister race"
15043
15044 test_160j() {
15045         remote_mds_nodsh && skip "remote MDS with nodsh"
15046         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15047                 skip "Need MDS version at least 2.12.56"
15048
15049         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15050         stack_trap "umount $MOUNT2" EXIT
15051
15052         changelog_register || error "first changelog_register failed"
15053         stack_trap "changelog_deregister" EXIT
15054
15055         # generate some changelog
15056         # use fnv1a because created files should be evenly distributed
15057         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15058                 error "mkdir $tdir failed"
15059         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15060                 error "create $DIR/$tdir/${tfile}bis failed"
15061
15062         # open the changelog device
15063         exec 3>/dev/changelog-$FSNAME-MDT0000
15064         stack_trap "exec 3>&-" EXIT
15065         exec 4</dev/changelog-$FSNAME-MDT0000
15066         stack_trap "exec 4<&-" EXIT
15067
15068         # umount the first lustre mount
15069         umount $MOUNT
15070         stack_trap "mount_client $MOUNT" EXIT
15071
15072         # read changelog
15073         cat <&4 >/dev/null || error "read changelog failed"
15074
15075         # clear changelog
15076         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15077         changelog_users $SINGLEMDS | grep -q $cl_user ||
15078                 error "User $cl_user not found in changelog_users"
15079
15080         printf 'clear:'$cl_user':0' >&3
15081 }
15082 run_test 160j "client can be umounted  while its chanangelog is being used"
15083
15084 test_160k() {
15085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15086         remote_mds_nodsh && skip "remote MDS with nodsh"
15087
15088         mkdir -p $DIR/$tdir/1/1
15089
15090         changelog_register || error "changelog_register failed"
15091         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15092
15093         changelog_users $SINGLEMDS | grep -q $cl_user ||
15094                 error "User '$cl_user' not found in changelog_users"
15095 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15096         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15097         rmdir $DIR/$tdir/1/1 & sleep 1
15098         mkdir $DIR/$tdir/2
15099         touch $DIR/$tdir/2/2
15100         rm -rf $DIR/$tdir/2
15101
15102         wait
15103         sleep 4
15104
15105         changelog_dump | grep rmdir || error "rmdir not recorded"
15106
15107         rm -rf $DIR/$tdir
15108         changelog_deregister
15109 }
15110 run_test 160k "Verify that changelog records are not lost"
15111
15112 # Verifies that a file passed as a parameter has recently had an operation
15113 # performed on it that has generated an MTIME changelog which contains the
15114 # correct parent FID. As files might reside on a different MDT from the
15115 # parent directory in DNE configurations, the FIDs are translated to paths
15116 # before being compared, which should be identical
15117 compare_mtime_changelog() {
15118         local file="${1}"
15119         local mdtidx
15120         local mtime
15121         local cl_fid
15122         local pdir
15123         local dir
15124
15125         mdtidx=$($LFS getstripe --mdt-index $file)
15126         mdtidx=$(printf "%04x" $mdtidx)
15127
15128         # Obtain the parent FID from the MTIME changelog
15129         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15130         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15131
15132         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15133         [ -z "$cl_fid" ] && error "parent FID not present"
15134
15135         # Verify that the path for the parent FID is the same as the path for
15136         # the test directory
15137         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15138
15139         dir=$(dirname $1)
15140
15141         [[ "${pdir%/}" == "$dir" ]] ||
15142                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15143 }
15144
15145 test_160l() {
15146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15147
15148         remote_mds_nodsh && skip "remote MDS with nodsh"
15149         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15150                 skip "Need MDS version at least 2.13.55"
15151
15152         local cl_user
15153
15154         changelog_register || error "changelog_register failed"
15155         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15156
15157         changelog_users $SINGLEMDS | grep -q $cl_user ||
15158                 error "User '$cl_user' not found in changelog_users"
15159
15160         # Clear some types so that MTIME changelogs are generated
15161         changelog_chmask "-CREAT"
15162         changelog_chmask "-CLOSE"
15163
15164         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15165
15166         # Test CL_MTIME during setattr
15167         touch $DIR/$tdir/$tfile
15168         compare_mtime_changelog $DIR/$tdir/$tfile
15169
15170         # Test CL_MTIME during close
15171         dd if=/dev/urandom of=$DIR/$tdir/${tfile}_2 bs=1M count=64 ||
15172                 error "cannot create file $DIR/$tdir/${tfile}_2"
15173         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15174 }
15175 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15176
15177 test_161a() {
15178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15179
15180         test_mkdir -c1 $DIR/$tdir
15181         cp /etc/hosts $DIR/$tdir/$tfile
15182         test_mkdir -c1 $DIR/$tdir/foo1
15183         test_mkdir -c1 $DIR/$tdir/foo2
15184         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15185         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15186         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15187         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15188         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15189         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15190                 $LFS fid2path $DIR $FID
15191                 error "bad link ea"
15192         fi
15193         # middle
15194         rm $DIR/$tdir/foo2/zachary
15195         # last
15196         rm $DIR/$tdir/foo2/thor
15197         # first
15198         rm $DIR/$tdir/$tfile
15199         # rename
15200         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15201         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15202                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15203         rm $DIR/$tdir/foo2/maggie
15204
15205         # overflow the EA
15206         local longname=$tfile.avg_len_is_thirty_two_
15207         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15208                 error_noexit 'failed to unlink many hardlinks'" EXIT
15209         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15210                 error "failed to hardlink many files"
15211         links=$($LFS fid2path $DIR $FID | wc -l)
15212         echo -n "${links}/1000 links in link EA"
15213         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15214 }
15215 run_test 161a "link ea sanity"
15216
15217 test_161b() {
15218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15219         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15220
15221         local MDTIDX=1
15222         local remote_dir=$DIR/$tdir/remote_dir
15223
15224         mkdir -p $DIR/$tdir
15225         $LFS mkdir -i $MDTIDX $remote_dir ||
15226                 error "create remote directory failed"
15227
15228         cp /etc/hosts $remote_dir/$tfile
15229         mkdir -p $remote_dir/foo1
15230         mkdir -p $remote_dir/foo2
15231         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15232         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15233         ln $remote_dir/$tfile $remote_dir/foo1/luna
15234         ln $remote_dir/$tfile $remote_dir/foo2/thor
15235
15236         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15237                      tr -d ']')
15238         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15239                 $LFS fid2path $DIR $FID
15240                 error "bad link ea"
15241         fi
15242         # middle
15243         rm $remote_dir/foo2/zachary
15244         # last
15245         rm $remote_dir/foo2/thor
15246         # first
15247         rm $remote_dir/$tfile
15248         # rename
15249         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15250         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15251         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15252                 $LFS fid2path $DIR $FID
15253                 error "bad link rename"
15254         fi
15255         rm $remote_dir/foo2/maggie
15256
15257         # overflow the EA
15258         local longname=filename_avg_len_is_thirty_two_
15259         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15260                 error "failed to hardlink many files"
15261         links=$($LFS fid2path $DIR $FID | wc -l)
15262         echo -n "${links}/1000 links in link EA"
15263         [[ ${links} -gt 60 ]] ||
15264                 error "expected at least 60 links in link EA"
15265         unlinkmany $remote_dir/foo2/$longname 1000 ||
15266         error "failed to unlink many hardlinks"
15267 }
15268 run_test 161b "link ea sanity under remote directory"
15269
15270 test_161c() {
15271         remote_mds_nodsh && skip "remote MDS with nodsh"
15272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15273         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15274                 skip "Need MDS version at least 2.1.5"
15275
15276         # define CLF_RENAME_LAST 0x0001
15277         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15278         changelog_register || error "changelog_register failed"
15279
15280         rm -rf $DIR/$tdir
15281         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15282         touch $DIR/$tdir/foo_161c
15283         touch $DIR/$tdir/bar_161c
15284         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15285         changelog_dump | grep RENME | tail -n 5
15286         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15287         changelog_clear 0 || error "changelog_clear failed"
15288         if [ x$flags != "x0x1" ]; then
15289                 error "flag $flags is not 0x1"
15290         fi
15291
15292         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15293         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15294         touch $DIR/$tdir/foo_161c
15295         touch $DIR/$tdir/bar_161c
15296         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15297         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15298         changelog_dump | grep RENME | tail -n 5
15299         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15300         changelog_clear 0 || error "changelog_clear failed"
15301         if [ x$flags != "x0x0" ]; then
15302                 error "flag $flags is not 0x0"
15303         fi
15304         echo "rename overwrite a target having nlink > 1," \
15305                 "changelog record has flags of $flags"
15306
15307         # rename doesn't overwrite a target (changelog flag 0x0)
15308         touch $DIR/$tdir/foo_161c
15309         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15310         changelog_dump | grep RENME | tail -n 5
15311         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15312         changelog_clear 0 || error "changelog_clear failed"
15313         if [ x$flags != "x0x0" ]; then
15314                 error "flag $flags is not 0x0"
15315         fi
15316         echo "rename doesn't overwrite a target," \
15317                 "changelog record has flags of $flags"
15318
15319         # define CLF_UNLINK_LAST 0x0001
15320         # unlink a file having nlink = 1 (changelog flag 0x1)
15321         rm -f $DIR/$tdir/foo2_161c
15322         changelog_dump | grep UNLNK | tail -n 5
15323         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15324         changelog_clear 0 || error "changelog_clear failed"
15325         if [ x$flags != "x0x1" ]; then
15326                 error "flag $flags is not 0x1"
15327         fi
15328         echo "unlink a file having nlink = 1," \
15329                 "changelog record has flags of $flags"
15330
15331         # unlink a file having nlink > 1 (changelog flag 0x0)
15332         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15333         rm -f $DIR/$tdir/foobar_161c
15334         changelog_dump | grep UNLNK | tail -n 5
15335         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15336         changelog_clear 0 || error "changelog_clear failed"
15337         if [ x$flags != "x0x0" ]; then
15338                 error "flag $flags is not 0x0"
15339         fi
15340         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15341 }
15342 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15343
15344 test_161d() {
15345         remote_mds_nodsh && skip "remote MDS with nodsh"
15346         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15347
15348         local pid
15349         local fid
15350
15351         changelog_register || error "changelog_register failed"
15352
15353         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15354         # interfer with $MOUNT/.lustre/fid/ access
15355         mkdir $DIR/$tdir
15356         [[ $? -eq 0 ]] || error "mkdir failed"
15357
15358         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15359         $LCTL set_param fail_loc=0x8000140c
15360         # 5s pause
15361         $LCTL set_param fail_val=5
15362
15363         # create file
15364         echo foofoo > $DIR/$tdir/$tfile &
15365         pid=$!
15366
15367         # wait for create to be delayed
15368         sleep 2
15369
15370         ps -p $pid
15371         [[ $? -eq 0 ]] || error "create should be blocked"
15372
15373         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15374         stack_trap "rm -f $tempfile"
15375         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15376         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15377         # some delay may occur during ChangeLog publishing and file read just
15378         # above, that could allow file write to happen finally
15379         [[ -s $tempfile ]] && echo "file should be empty"
15380
15381         $LCTL set_param fail_loc=0
15382
15383         wait $pid
15384         [[ $? -eq 0 ]] || error "create failed"
15385 }
15386 run_test 161d "create with concurrent .lustre/fid access"
15387
15388 check_path() {
15389         local expected="$1"
15390         shift
15391         local fid="$2"
15392
15393         local path
15394         path=$($LFS fid2path "$@")
15395         local rc=$?
15396
15397         if [ $rc -ne 0 ]; then
15398                 error "path looked up of '$expected' failed: rc=$rc"
15399         elif [ "$path" != "$expected" ]; then
15400                 error "path looked up '$path' instead of '$expected'"
15401         else
15402                 echo "FID '$fid' resolves to path '$path' as expected"
15403         fi
15404 }
15405
15406 test_162a() { # was test_162
15407         test_mkdir -p -c1 $DIR/$tdir/d2
15408         touch $DIR/$tdir/d2/$tfile
15409         touch $DIR/$tdir/d2/x1
15410         touch $DIR/$tdir/d2/x2
15411         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15412         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15413         # regular file
15414         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15415         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15416
15417         # softlink
15418         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15419         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15420         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15421
15422         # softlink to wrong file
15423         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15424         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15425         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15426
15427         # hardlink
15428         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15429         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15430         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15431         # fid2path dir/fsname should both work
15432         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15433         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15434
15435         # hardlink count: check that there are 2 links
15436         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15437         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15438
15439         # hardlink indexing: remove the first link
15440         rm $DIR/$tdir/d2/p/q/r/hlink
15441         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15442 }
15443 run_test 162a "path lookup sanity"
15444
15445 test_162b() {
15446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15448
15449         mkdir $DIR/$tdir
15450         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15451                                 error "create striped dir failed"
15452
15453         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15454                                         tail -n 1 | awk '{print $2}')
15455         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15456
15457         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15458         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15459
15460         # regular file
15461         for ((i=0;i<5;i++)); do
15462                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15463                         error "get fid for f$i failed"
15464                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15465
15466                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15467                         error "get fid for d$i failed"
15468                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15469         done
15470
15471         return 0
15472 }
15473 run_test 162b "striped directory path lookup sanity"
15474
15475 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15476 test_162c() {
15477         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15478                 skip "Need MDS version at least 2.7.51"
15479
15480         local lpath=$tdir.local
15481         local rpath=$tdir.remote
15482
15483         test_mkdir $DIR/$lpath
15484         test_mkdir $DIR/$rpath
15485
15486         for ((i = 0; i <= 101; i++)); do
15487                 lpath="$lpath/$i"
15488                 mkdir $DIR/$lpath
15489                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15490                         error "get fid for local directory $DIR/$lpath failed"
15491                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15492
15493                 rpath="$rpath/$i"
15494                 test_mkdir $DIR/$rpath
15495                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15496                         error "get fid for remote directory $DIR/$rpath failed"
15497                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15498         done
15499
15500         return 0
15501 }
15502 run_test 162c "fid2path works with paths 100 or more directories deep"
15503
15504 oalr_event_count() {
15505         local event="${1}"
15506         local trace="${2}"
15507
15508         awk -v name="${FSNAME}-OST0000" \
15509             -v event="${event}" \
15510             '$1 == "TRACE" && $2 == event && $3 == name' \
15511             "${trace}" |
15512         wc -l
15513 }
15514
15515 oalr_expect_event_count() {
15516         local event="${1}"
15517         local trace="${2}"
15518         local expect="${3}"
15519         local count
15520
15521         count=$(oalr_event_count "${event}" "${trace}")
15522         if ((count == expect)); then
15523                 return 0
15524         fi
15525
15526         error_noexit "${event} event count was '${count}', expected ${expect}"
15527         cat "${trace}" >&2
15528         exit 1
15529 }
15530
15531 cleanup_165() {
15532         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15533         stop ost1
15534         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15535 }
15536
15537 setup_165() {
15538         sync # Flush previous IOs so we can count log entries.
15539         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15540         stack_trap cleanup_165 EXIT
15541 }
15542
15543 test_165a() {
15544         local trace="/tmp/${tfile}.trace"
15545         local rc
15546         local count
15547
15548         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15549         setup_165
15550         sleep 5
15551
15552         do_facet ost1 ofd_access_log_reader --list
15553         stop ost1
15554
15555         do_facet ost1 killall -TERM ofd_access_log_reader
15556         wait
15557         rc=$?
15558
15559         if ((rc != 0)); then
15560                 error "ofd_access_log_reader exited with rc = '${rc}'"
15561         fi
15562
15563         # Parse trace file for discovery events:
15564         oalr_expect_event_count alr_log_add "${trace}" 1
15565         oalr_expect_event_count alr_log_eof "${trace}" 1
15566         oalr_expect_event_count alr_log_free "${trace}" 1
15567 }
15568 run_test 165a "ofd access log discovery"
15569
15570 test_165b() {
15571         local trace="/tmp/${tfile}.trace"
15572         local file="${DIR}/${tfile}"
15573         local pfid1
15574         local pfid2
15575         local -a entry
15576         local rc
15577         local count
15578         local size
15579         local flags
15580
15581         setup_165
15582
15583         lfs setstripe -c 1 -i 0 "${file}"
15584         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15585         do_facet ost1 ofd_access_log_reader --list
15586
15587         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15588         sleep 5
15589         do_facet ost1 killall -TERM ofd_access_log_reader
15590         wait
15591         rc=$?
15592
15593         if ((rc != 0)); then
15594                 error "ofd_access_log_reader exited with rc = '${rc}'"
15595         fi
15596
15597         oalr_expect_event_count alr_log_entry "${trace}" 1
15598
15599         pfid1=$($LFS path2fid "${file}")
15600
15601         # 1     2             3   4    5     6   7    8    9     10
15602         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15603         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15604
15605         echo "entry = '${entry[*]}'" >&2
15606
15607         pfid2=${entry[4]}
15608         if [[ "${pfid1}" != "${pfid2}" ]]; then
15609                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15610         fi
15611
15612         size=${entry[8]}
15613         if ((size != 1048576)); then
15614                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15615         fi
15616
15617         flags=${entry[10]}
15618         if [[ "${flags}" != "w" ]]; then
15619                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15620         fi
15621
15622         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15623         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15624         sleep 5
15625         do_facet ost1 killall -TERM ofd_access_log_reader
15626         wait
15627         rc=$?
15628
15629         if ((rc != 0)); then
15630                 error "ofd_access_log_reader exited with rc = '${rc}'"
15631         fi
15632
15633         oalr_expect_event_count alr_log_entry "${trace}" 1
15634
15635         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15636         echo "entry = '${entry[*]}'" >&2
15637
15638         pfid2=${entry[4]}
15639         if [[ "${pfid1}" != "${pfid2}" ]]; then
15640                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15641         fi
15642
15643         size=${entry[8]}
15644         if ((size != 524288)); then
15645                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15646         fi
15647
15648         flags=${entry[10]}
15649         if [[ "${flags}" != "r" ]]; then
15650                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15651         fi
15652 }
15653 run_test 165b "ofd access log entries are produced and consumed"
15654
15655 test_165c() {
15656         local file="${DIR}/${tdir}/${tfile}"
15657         test_mkdir "${DIR}/${tdir}"
15658
15659         setup_165
15660
15661         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15662
15663         # 4096 / 64 = 64. Create twice as many entries.
15664         for ((i = 0; i < 128; i++)); do
15665                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15666         done
15667
15668         sync
15669         do_facet ost1 ofd_access_log_reader --list
15670         unlinkmany  "${file}-%d" 128
15671 }
15672 run_test 165c "full ofd access logs do not block IOs"
15673
15674 oal_peek_entry_count() {
15675         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15676 }
15677
15678 oal_expect_entry_count() {
15679         local entry_count=$(oal_peek_entry_count)
15680         local expect="$1"
15681
15682         if ((entry_count == expect)); then
15683                 return 0
15684         fi
15685
15686         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15687         do_facet ost1 ofd_access_log_reader --list >&2
15688         exit 1
15689 }
15690
15691 test_165d() {
15692         local trace="/tmp/${tfile}.trace"
15693         local file="${DIR}/${tdir}/${tfile}"
15694         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15695         local entry_count
15696         test_mkdir "${DIR}/${tdir}"
15697
15698         setup_165
15699         lfs setstripe -c 1 -i 0 "${file}"
15700
15701         do_facet ost1 lctl set_param "${param}=rw"
15702         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15703         oal_expect_entry_count 1
15704
15705         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15706         oal_expect_entry_count 2
15707
15708         do_facet ost1 lctl set_param "${param}=r"
15709         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15710         oal_expect_entry_count 2
15711
15712         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15713         oal_expect_entry_count 3
15714
15715         do_facet ost1 lctl set_param "${param}=w"
15716         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15717         oal_expect_entry_count 4
15718
15719         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15720         oal_expect_entry_count 4
15721
15722         do_facet ost1 lctl set_param "${param}=0"
15723         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15724         oal_expect_entry_count 4
15725
15726         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15727         oal_expect_entry_count 4
15728 }
15729 run_test 165d "ofd_access_log mask works"
15730
15731 test_169() {
15732         # do directio so as not to populate the page cache
15733         log "creating a 10 Mb file"
15734         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15735         log "starting reads"
15736         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15737         log "truncating the file"
15738         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15739         log "killing dd"
15740         kill %+ || true # reads might have finished
15741         echo "wait until dd is finished"
15742         wait
15743         log "removing the temporary file"
15744         rm -rf $DIR/$tfile || error "tmp file removal failed"
15745 }
15746 run_test 169 "parallel read and truncate should not deadlock"
15747
15748 test_170() {
15749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15750
15751         $LCTL clear     # bug 18514
15752         $LCTL debug_daemon start $TMP/${tfile}_log_good
15753         touch $DIR/$tfile
15754         $LCTL debug_daemon stop
15755         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15756                 error "sed failed to read log_good"
15757
15758         $LCTL debug_daemon start $TMP/${tfile}_log_good
15759         rm -rf $DIR/$tfile
15760         $LCTL debug_daemon stop
15761
15762         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15763                error "lctl df log_bad failed"
15764
15765         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15766         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15767
15768         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15769         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15770
15771         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15772                 error "bad_line good_line1 good_line2 are empty"
15773
15774         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15775         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15776         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15777
15778         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15779         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15780         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15781
15782         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15783                 error "bad_line_new good_line_new are empty"
15784
15785         local expected_good=$((good_line1 + good_line2*2))
15786
15787         rm -f $TMP/${tfile}*
15788         # LU-231, short malformed line may not be counted into bad lines
15789         if [ $bad_line -ne $bad_line_new ] &&
15790                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15791                 error "expected $bad_line bad lines, but got $bad_line_new"
15792                 return 1
15793         fi
15794
15795         if [ $expected_good -ne $good_line_new ]; then
15796                 error "expected $expected_good good lines, but got $good_line_new"
15797                 return 2
15798         fi
15799         true
15800 }
15801 run_test 170 "test lctl df to handle corrupted log ====================="
15802
15803 test_171() { # bug20592
15804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15805
15806         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15807         $LCTL set_param fail_loc=0x50e
15808         $LCTL set_param fail_val=3000
15809         multiop_bg_pause $DIR/$tfile O_s || true
15810         local MULTIPID=$!
15811         kill -USR1 $MULTIPID
15812         # cause log dump
15813         sleep 3
15814         wait $MULTIPID
15815         if dmesg | grep "recursive fault"; then
15816                 error "caught a recursive fault"
15817         fi
15818         $LCTL set_param fail_loc=0
15819         true
15820 }
15821 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15822
15823 # it would be good to share it with obdfilter-survey/iokit-libecho code
15824 setup_obdecho_osc () {
15825         local rc=0
15826         local ost_nid=$1
15827         local obdfilter_name=$2
15828         echo "Creating new osc for $obdfilter_name on $ost_nid"
15829         # make sure we can find loopback nid
15830         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15831
15832         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15833                            ${obdfilter_name}_osc_UUID || rc=2; }
15834         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15835                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15836         return $rc
15837 }
15838
15839 cleanup_obdecho_osc () {
15840         local obdfilter_name=$1
15841         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15842         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15843         return 0
15844 }
15845
15846 obdecho_test() {
15847         local OBD=$1
15848         local node=$2
15849         local pages=${3:-64}
15850         local rc=0
15851         local id
15852
15853         local count=10
15854         local obd_size=$(get_obd_size $node $OBD)
15855         local page_size=$(get_page_size $node)
15856         if [[ -n "$obd_size" ]]; then
15857                 local new_count=$((obd_size / (pages * page_size / 1024)))
15858                 [[ $new_count -ge $count ]] || count=$new_count
15859         fi
15860
15861         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15862         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15863                            rc=2; }
15864         if [ $rc -eq 0 ]; then
15865             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15866             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15867         fi
15868         echo "New object id is $id"
15869         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15870                            rc=4; }
15871         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15872                            "test_brw $count w v $pages $id" || rc=4; }
15873         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15874                            rc=4; }
15875         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15876                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15877         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15878                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15879         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15880         return $rc
15881 }
15882
15883 test_180a() {
15884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15885
15886         if ! [ -d /sys/fs/lustre/echo_client ] &&
15887            ! module_loaded obdecho; then
15888                 load_module obdecho/obdecho &&
15889                         stack_trap "rmmod obdecho" EXIT ||
15890                         error "unable to load obdecho on client"
15891         fi
15892
15893         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15894         local host=$($LCTL get_param -n osc.$osc.import |
15895                      awk '/current_connection:/ { print $2 }' )
15896         local target=$($LCTL get_param -n osc.$osc.import |
15897                        awk '/target:/ { print $2 }' )
15898         target=${target%_UUID}
15899
15900         if [ -n "$target" ]; then
15901                 setup_obdecho_osc $host $target &&
15902                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15903                         { error "obdecho setup failed with $?"; return; }
15904
15905                 obdecho_test ${target}_osc client ||
15906                         error "obdecho_test failed on ${target}_osc"
15907         else
15908                 $LCTL get_param osc.$osc.import
15909                 error "there is no osc.$osc.import target"
15910         fi
15911 }
15912 run_test 180a "test obdecho on osc"
15913
15914 test_180b() {
15915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15916         remote_ost_nodsh && skip "remote OST with nodsh"
15917
15918         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15919                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15920                 error "failed to load module obdecho"
15921
15922         local target=$(do_facet ost1 $LCTL dl |
15923                        awk '/obdfilter/ { print $4; exit; }')
15924
15925         if [ -n "$target" ]; then
15926                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15927         else
15928                 do_facet ost1 $LCTL dl
15929                 error "there is no obdfilter target on ost1"
15930         fi
15931 }
15932 run_test 180b "test obdecho directly on obdfilter"
15933
15934 test_180c() { # LU-2598
15935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15936         remote_ost_nodsh && skip "remote OST with nodsh"
15937         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15938                 skip "Need MDS version at least 2.4.0"
15939
15940         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15941                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15942                 error "failed to load module obdecho"
15943
15944         local target=$(do_facet ost1 $LCTL dl |
15945                        awk '/obdfilter/ { print $4; exit; }')
15946
15947         if [ -n "$target" ]; then
15948                 local pages=16384 # 64MB bulk I/O RPC size
15949
15950                 obdecho_test "$target" ost1 "$pages" ||
15951                         error "obdecho_test with pages=$pages failed with $?"
15952         else
15953                 do_facet ost1 $LCTL dl
15954                 error "there is no obdfilter target on ost1"
15955         fi
15956 }
15957 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15958
15959 test_181() { # bug 22177
15960         test_mkdir $DIR/$tdir
15961         # create enough files to index the directory
15962         createmany -o $DIR/$tdir/foobar 4000
15963         # print attributes for debug purpose
15964         lsattr -d .
15965         # open dir
15966         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15967         MULTIPID=$!
15968         # remove the files & current working dir
15969         unlinkmany $DIR/$tdir/foobar 4000
15970         rmdir $DIR/$tdir
15971         kill -USR1 $MULTIPID
15972         wait $MULTIPID
15973         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15974         return 0
15975 }
15976 run_test 181 "Test open-unlinked dir ========================"
15977
15978 test_182() {
15979         local fcount=1000
15980         local tcount=10
15981
15982         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15983
15984         $LCTL set_param mdc.*.rpc_stats=clear
15985
15986         for (( i = 0; i < $tcount; i++ )) ; do
15987                 mkdir $DIR/$tdir/$i
15988         done
15989
15990         for (( i = 0; i < $tcount; i++ )) ; do
15991                 createmany -o $DIR/$tdir/$i/f- $fcount &
15992         done
15993         wait
15994
15995         for (( i = 0; i < $tcount; i++ )) ; do
15996                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15997         done
15998         wait
15999
16000         $LCTL get_param mdc.*.rpc_stats
16001
16002         rm -rf $DIR/$tdir
16003 }
16004 run_test 182 "Test parallel modify metadata operations ================"
16005
16006 test_183() { # LU-2275
16007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16008         remote_mds_nodsh && skip "remote MDS with nodsh"
16009         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16010                 skip "Need MDS version at least 2.3.56"
16011
16012         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16013         echo aaa > $DIR/$tdir/$tfile
16014
16015 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16016         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16017
16018         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16019         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16020
16021         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16022
16023         # Flush negative dentry cache
16024         touch $DIR/$tdir/$tfile
16025
16026         # We are not checking for any leaked references here, they'll
16027         # become evident next time we do cleanup with module unload.
16028         rm -rf $DIR/$tdir
16029 }
16030 run_test 183 "No crash or request leak in case of strange dispositions ========"
16031
16032 # test suite 184 is for LU-2016, LU-2017
16033 test_184a() {
16034         check_swap_layouts_support
16035
16036         dir0=$DIR/$tdir/$testnum
16037         test_mkdir -p -c1 $dir0
16038         ref1=/etc/passwd
16039         ref2=/etc/group
16040         file1=$dir0/f1
16041         file2=$dir0/f2
16042         $LFS setstripe -c1 $file1
16043         cp $ref1 $file1
16044         $LFS setstripe -c2 $file2
16045         cp $ref2 $file2
16046         gen1=$($LFS getstripe -g $file1)
16047         gen2=$($LFS getstripe -g $file2)
16048
16049         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16050         gen=$($LFS getstripe -g $file1)
16051         [[ $gen1 != $gen ]] ||
16052                 "Layout generation on $file1 does not change"
16053         gen=$($LFS getstripe -g $file2)
16054         [[ $gen2 != $gen ]] ||
16055                 "Layout generation on $file2 does not change"
16056
16057         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16058         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16059
16060         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16061 }
16062 run_test 184a "Basic layout swap"
16063
16064 test_184b() {
16065         check_swap_layouts_support
16066
16067         dir0=$DIR/$tdir/$testnum
16068         mkdir -p $dir0 || error "creating dir $dir0"
16069         file1=$dir0/f1
16070         file2=$dir0/f2
16071         file3=$dir0/f3
16072         dir1=$dir0/d1
16073         dir2=$dir0/d2
16074         mkdir $dir1 $dir2
16075         $LFS setstripe -c1 $file1
16076         $LFS setstripe -c2 $file2
16077         $LFS setstripe -c1 $file3
16078         chown $RUNAS_ID $file3
16079         gen1=$($LFS getstripe -g $file1)
16080         gen2=$($LFS getstripe -g $file2)
16081
16082         $LFS swap_layouts $dir1 $dir2 &&
16083                 error "swap of directories layouts should fail"
16084         $LFS swap_layouts $dir1 $file1 &&
16085                 error "swap of directory and file layouts should fail"
16086         $RUNAS $LFS swap_layouts $file1 $file2 &&
16087                 error "swap of file we cannot write should fail"
16088         $LFS swap_layouts $file1 $file3 &&
16089                 error "swap of file with different owner should fail"
16090         /bin/true # to clear error code
16091 }
16092 run_test 184b "Forbidden layout swap (will generate errors)"
16093
16094 test_184c() {
16095         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16096         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16097         check_swap_layouts_support
16098         check_swap_layout_no_dom $DIR
16099
16100         local dir0=$DIR/$tdir/$testnum
16101         mkdir -p $dir0 || error "creating dir $dir0"
16102
16103         local ref1=$dir0/ref1
16104         local ref2=$dir0/ref2
16105         local file1=$dir0/file1
16106         local file2=$dir0/file2
16107         # create a file large enough for the concurrent test
16108         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16109         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16110         echo "ref file size: ref1($(stat -c %s $ref1))," \
16111              "ref2($(stat -c %s $ref2))"
16112
16113         cp $ref2 $file2
16114         dd if=$ref1 of=$file1 bs=16k &
16115         local DD_PID=$!
16116
16117         # Make sure dd starts to copy file, but wait at most 5 seconds
16118         local loops=0
16119         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16120
16121         $LFS swap_layouts $file1 $file2
16122         local rc=$?
16123         wait $DD_PID
16124         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16125         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16126
16127         # how many bytes copied before swapping layout
16128         local copied=$(stat -c %s $file2)
16129         local remaining=$(stat -c %s $ref1)
16130         remaining=$((remaining - copied))
16131         echo "Copied $copied bytes before swapping layout..."
16132
16133         cmp -n $copied $file1 $ref2 | grep differ &&
16134                 error "Content mismatch [0, $copied) of ref2 and file1"
16135         cmp -n $copied $file2 $ref1 ||
16136                 error "Content mismatch [0, $copied) of ref1 and file2"
16137         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16138                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16139
16140         # clean up
16141         rm -f $ref1 $ref2 $file1 $file2
16142 }
16143 run_test 184c "Concurrent write and layout swap"
16144
16145 test_184d() {
16146         check_swap_layouts_support
16147         check_swap_layout_no_dom $DIR
16148         [ -z "$(which getfattr 2>/dev/null)" ] &&
16149                 skip_env "no getfattr command"
16150
16151         local file1=$DIR/$tdir/$tfile-1
16152         local file2=$DIR/$tdir/$tfile-2
16153         local file3=$DIR/$tdir/$tfile-3
16154         local lovea1
16155         local lovea2
16156
16157         mkdir -p $DIR/$tdir
16158         touch $file1 || error "create $file1 failed"
16159         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16160                 error "create $file2 failed"
16161         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16162                 error "create $file3 failed"
16163         lovea1=$(get_layout_param $file1)
16164
16165         $LFS swap_layouts $file2 $file3 ||
16166                 error "swap $file2 $file3 layouts failed"
16167         $LFS swap_layouts $file1 $file2 ||
16168                 error "swap $file1 $file2 layouts failed"
16169
16170         lovea2=$(get_layout_param $file2)
16171         echo "$lovea1"
16172         echo "$lovea2"
16173         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16174
16175         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16176         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16177 }
16178 run_test 184d "allow stripeless layouts swap"
16179
16180 test_184e() {
16181         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16182                 skip "Need MDS version at least 2.6.94"
16183         check_swap_layouts_support
16184         check_swap_layout_no_dom $DIR
16185         [ -z "$(which getfattr 2>/dev/null)" ] &&
16186                 skip_env "no getfattr command"
16187
16188         local file1=$DIR/$tdir/$tfile-1
16189         local file2=$DIR/$tdir/$tfile-2
16190         local file3=$DIR/$tdir/$tfile-3
16191         local lovea
16192
16193         mkdir -p $DIR/$tdir
16194         touch $file1 || error "create $file1 failed"
16195         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16196                 error "create $file2 failed"
16197         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16198                 error "create $file3 failed"
16199
16200         $LFS swap_layouts $file1 $file2 ||
16201                 error "swap $file1 $file2 layouts failed"
16202
16203         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16204         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16205
16206         echo 123 > $file1 || error "Should be able to write into $file1"
16207
16208         $LFS swap_layouts $file1 $file3 ||
16209                 error "swap $file1 $file3 layouts failed"
16210
16211         echo 123 > $file1 || error "Should be able to write into $file1"
16212
16213         rm -rf $file1 $file2 $file3
16214 }
16215 run_test 184e "Recreate layout after stripeless layout swaps"
16216
16217 test_184f() {
16218         # Create a file with name longer than sizeof(struct stat) ==
16219         # 144 to see if we can get chars from the file name to appear
16220         # in the returned striping. Note that 'f' == 0x66.
16221         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16222
16223         mkdir -p $DIR/$tdir
16224         mcreate $DIR/$tdir/$file
16225         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16226                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16227         fi
16228 }
16229 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16230
16231 test_185() { # LU-2441
16232         # LU-3553 - no volatile file support in old servers
16233         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16234                 skip "Need MDS version at least 2.3.60"
16235
16236         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16237         touch $DIR/$tdir/spoo
16238         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16239         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16240                 error "cannot create/write a volatile file"
16241         [ "$FILESET" == "" ] &&
16242         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16243                 error "FID is still valid after close"
16244
16245         multiop_bg_pause $DIR/$tdir vVw4096_c
16246         local multi_pid=$!
16247
16248         local OLD_IFS=$IFS
16249         IFS=":"
16250         local fidv=($fid)
16251         IFS=$OLD_IFS
16252         # assume that the next FID for this client is sequential, since stdout
16253         # is unfortunately eaten by multiop_bg_pause
16254         local n=$((${fidv[1]} + 1))
16255         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16256         if [ "$FILESET" == "" ]; then
16257                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16258                         error "FID is missing before close"
16259         fi
16260         kill -USR1 $multi_pid
16261         # 1 second delay, so if mtime change we will see it
16262         sleep 1
16263         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16264         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16265 }
16266 run_test 185 "Volatile file support"
16267
16268 function create_check_volatile() {
16269         local idx=$1
16270         local tgt
16271
16272         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16273         local PID=$!
16274         sleep 1
16275         local FID=$(cat /tmp/${tfile}.fid)
16276         [ "$FID" == "" ] && error "can't get FID for volatile"
16277         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16278         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16279         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16280         kill -USR1 $PID
16281         wait
16282         sleep 1
16283         cancel_lru_locks mdc # flush opencache
16284         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16285         return 0
16286 }
16287
16288 test_185a(){
16289         # LU-12516 - volatile creation via .lustre
16290         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16291                 skip "Need MDS version at least 2.3.55"
16292
16293         create_check_volatile 0
16294         [ $MDSCOUNT -lt 2 ] && return 0
16295
16296         # DNE case
16297         create_check_volatile 1
16298
16299         return 0
16300 }
16301 run_test 185a "Volatile file creation in .lustre/fid/"
16302
16303 test_187a() {
16304         remote_mds_nodsh && skip "remote MDS with nodsh"
16305         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16306                 skip "Need MDS version at least 2.3.0"
16307
16308         local dir0=$DIR/$tdir/$testnum
16309         mkdir -p $dir0 || error "creating dir $dir0"
16310
16311         local file=$dir0/file1
16312         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16313         local dv1=$($LFS data_version $file)
16314         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16315         local dv2=$($LFS data_version $file)
16316         [[ $dv1 != $dv2 ]] ||
16317                 error "data version did not change on write $dv1 == $dv2"
16318
16319         # clean up
16320         rm -f $file1
16321 }
16322 run_test 187a "Test data version change"
16323
16324 test_187b() {
16325         remote_mds_nodsh && skip "remote MDS with nodsh"
16326         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16327                 skip "Need MDS version at least 2.3.0"
16328
16329         local dir0=$DIR/$tdir/$testnum
16330         mkdir -p $dir0 || error "creating dir $dir0"
16331
16332         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16333         [[ ${DV[0]} != ${DV[1]} ]] ||
16334                 error "data version did not change on write"\
16335                       " ${DV[0]} == ${DV[1]}"
16336
16337         # clean up
16338         rm -f $file1
16339 }
16340 run_test 187b "Test data version change on volatile file"
16341
16342 test_200() {
16343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16344         remote_mgs_nodsh && skip "remote MGS with nodsh"
16345         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16346
16347         local POOL=${POOL:-cea1}
16348         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16349         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16350         # Pool OST targets
16351         local first_ost=0
16352         local last_ost=$(($OSTCOUNT - 1))
16353         local ost_step=2
16354         local ost_list=$(seq $first_ost $ost_step $last_ost)
16355         local ost_range="$first_ost $last_ost $ost_step"
16356         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16357         local file_dir=$POOL_ROOT/file_tst
16358         local subdir=$test_path/subdir
16359         local rc=0
16360
16361         while : ; do
16362                 # former test_200a test_200b
16363                 pool_add $POOL                          || { rc=$? ; break; }
16364                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16365                 # former test_200c test_200d
16366                 mkdir -p $test_path
16367                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16368                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16369                 mkdir -p $subdir
16370                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16371                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16372                                                         || { rc=$? ; break; }
16373                 # former test_200e test_200f
16374                 local files=$((OSTCOUNT*3))
16375                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16376                                                         || { rc=$? ; break; }
16377                 pool_create_files $POOL $file_dir $files "$ost_list" \
16378                                                         || { rc=$? ; break; }
16379                 # former test_200g test_200h
16380                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16381                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16382
16383                 # former test_201a test_201b test_201c
16384                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16385
16386                 local f=$test_path/$tfile
16387                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16388                 pool_remove $POOL $f                    || { rc=$? ; break; }
16389                 break
16390         done
16391
16392         destroy_test_pools
16393
16394         return $rc
16395 }
16396 run_test 200 "OST pools"
16397
16398 # usage: default_attr <count | size | offset>
16399 default_attr() {
16400         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16401 }
16402
16403 # usage: check_default_stripe_attr
16404 check_default_stripe_attr() {
16405         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16406         case $1 in
16407         --stripe-count|-c)
16408                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16409         --stripe-size|-S)
16410                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16411         --stripe-index|-i)
16412                 EXPECTED=-1;;
16413         *)
16414                 error "unknown getstripe attr '$1'"
16415         esac
16416
16417         [ $ACTUAL == $EXPECTED ] ||
16418                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16419 }
16420
16421 test_204a() {
16422         test_mkdir $DIR/$tdir
16423         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16424
16425         check_default_stripe_attr --stripe-count
16426         check_default_stripe_attr --stripe-size
16427         check_default_stripe_attr --stripe-index
16428 }
16429 run_test 204a "Print default stripe attributes"
16430
16431 test_204b() {
16432         test_mkdir $DIR/$tdir
16433         $LFS setstripe --stripe-count 1 $DIR/$tdir
16434
16435         check_default_stripe_attr --stripe-size
16436         check_default_stripe_attr --stripe-index
16437 }
16438 run_test 204b "Print default stripe size and offset"
16439
16440 test_204c() {
16441         test_mkdir $DIR/$tdir
16442         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16443
16444         check_default_stripe_attr --stripe-count
16445         check_default_stripe_attr --stripe-index
16446 }
16447 run_test 204c "Print default stripe count and offset"
16448
16449 test_204d() {
16450         test_mkdir $DIR/$tdir
16451         $LFS setstripe --stripe-index 0 $DIR/$tdir
16452
16453         check_default_stripe_attr --stripe-count
16454         check_default_stripe_attr --stripe-size
16455 }
16456 run_test 204d "Print default stripe count and size"
16457
16458 test_204e() {
16459         test_mkdir $DIR/$tdir
16460         $LFS setstripe -d $DIR/$tdir
16461
16462         check_default_stripe_attr --stripe-count --raw
16463         check_default_stripe_attr --stripe-size --raw
16464         check_default_stripe_attr --stripe-index --raw
16465 }
16466 run_test 204e "Print raw stripe attributes"
16467
16468 test_204f() {
16469         test_mkdir $DIR/$tdir
16470         $LFS setstripe --stripe-count 1 $DIR/$tdir
16471
16472         check_default_stripe_attr --stripe-size --raw
16473         check_default_stripe_attr --stripe-index --raw
16474 }
16475 run_test 204f "Print raw stripe size and offset"
16476
16477 test_204g() {
16478         test_mkdir $DIR/$tdir
16479         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16480
16481         check_default_stripe_attr --stripe-count --raw
16482         check_default_stripe_attr --stripe-index --raw
16483 }
16484 run_test 204g "Print raw stripe count and offset"
16485
16486 test_204h() {
16487         test_mkdir $DIR/$tdir
16488         $LFS setstripe --stripe-index 0 $DIR/$tdir
16489
16490         check_default_stripe_attr --stripe-count --raw
16491         check_default_stripe_attr --stripe-size --raw
16492 }
16493 run_test 204h "Print raw stripe count and size"
16494
16495 # Figure out which job scheduler is being used, if any,
16496 # or use a fake one
16497 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16498         JOBENV=SLURM_JOB_ID
16499 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16500         JOBENV=LSB_JOBID
16501 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16502         JOBENV=PBS_JOBID
16503 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16504         JOBENV=LOADL_STEP_ID
16505 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16506         JOBENV=JOB_ID
16507 else
16508         $LCTL list_param jobid_name > /dev/null 2>&1
16509         if [ $? -eq 0 ]; then
16510                 JOBENV=nodelocal
16511         else
16512                 JOBENV=FAKE_JOBID
16513         fi
16514 fi
16515 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16516
16517 verify_jobstats() {
16518         local cmd=($1)
16519         shift
16520         local facets="$@"
16521
16522 # we don't really need to clear the stats for this test to work, since each
16523 # command has a unique jobid, but it makes debugging easier if needed.
16524 #       for facet in $facets; do
16525 #               local dev=$(convert_facet2label $facet)
16526 #               # clear old jobstats
16527 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16528 #       done
16529
16530         # use a new JobID for each test, or we might see an old one
16531         [ "$JOBENV" = "FAKE_JOBID" ] &&
16532                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16533
16534         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16535
16536         [ "$JOBENV" = "nodelocal" ] && {
16537                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16538                 $LCTL set_param jobid_name=$FAKE_JOBID
16539                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16540         }
16541
16542         log "Test: ${cmd[*]}"
16543         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16544
16545         if [ $JOBENV = "FAKE_JOBID" ]; then
16546                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16547         else
16548                 ${cmd[*]}
16549         fi
16550
16551         # all files are created on OST0000
16552         for facet in $facets; do
16553                 local stats="*.$(convert_facet2label $facet).job_stats"
16554
16555                 # strip out libtool wrappers for in-tree executables
16556                 if [ $(do_facet $facet lctl get_param $stats |
16557                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16558                         do_facet $facet lctl get_param $stats
16559                         error "No jobstats for $JOBVAL found on $facet::$stats"
16560                 fi
16561         done
16562 }
16563
16564 jobstats_set() {
16565         local new_jobenv=$1
16566
16567         set_persistent_param_and_check client "jobid_var" \
16568                 "$FSNAME.sys.jobid_var" $new_jobenv
16569 }
16570
16571 test_205a() { # Job stats
16572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16573         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16574                 skip "Need MDS version with at least 2.7.1"
16575         remote_mgs_nodsh && skip "remote MGS with nodsh"
16576         remote_mds_nodsh && skip "remote MDS with nodsh"
16577         remote_ost_nodsh && skip "remote OST with nodsh"
16578         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16579                 skip "Server doesn't support jobstats"
16580         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16581
16582         local old_jobenv=$($LCTL get_param -n jobid_var)
16583         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16584
16585         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16586                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16587         else
16588                 stack_trap "do_facet mgs $PERM_CMD \
16589                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16590         fi
16591         changelog_register
16592
16593         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16594                                 mdt.*.job_cleanup_interval | head -n 1)
16595         local new_interval=5
16596         do_facet $SINGLEMDS \
16597                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16598         stack_trap "do_facet $SINGLEMDS \
16599                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16600         local start=$SECONDS
16601
16602         local cmd
16603         # mkdir
16604         cmd="mkdir $DIR/$tdir"
16605         verify_jobstats "$cmd" "$SINGLEMDS"
16606         # rmdir
16607         cmd="rmdir $DIR/$tdir"
16608         verify_jobstats "$cmd" "$SINGLEMDS"
16609         # mkdir on secondary MDT
16610         if [ $MDSCOUNT -gt 1 ]; then
16611                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16612                 verify_jobstats "$cmd" "mds2"
16613         fi
16614         # mknod
16615         cmd="mknod $DIR/$tfile c 1 3"
16616         verify_jobstats "$cmd" "$SINGLEMDS"
16617         # unlink
16618         cmd="rm -f $DIR/$tfile"
16619         verify_jobstats "$cmd" "$SINGLEMDS"
16620         # create all files on OST0000 so verify_jobstats can find OST stats
16621         # open & close
16622         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16623         verify_jobstats "$cmd" "$SINGLEMDS"
16624         # setattr
16625         cmd="touch $DIR/$tfile"
16626         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16627         # write
16628         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16629         verify_jobstats "$cmd" "ost1"
16630         # read
16631         cancel_lru_locks osc
16632         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16633         verify_jobstats "$cmd" "ost1"
16634         # truncate
16635         cmd="$TRUNCATE $DIR/$tfile 0"
16636         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16637         # rename
16638         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16639         verify_jobstats "$cmd" "$SINGLEMDS"
16640         # jobstats expiry - sleep until old stats should be expired
16641         local left=$((new_interval + 5 - (SECONDS - start)))
16642         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16643                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16644                         "0" $left
16645         cmd="mkdir $DIR/$tdir.expire"
16646         verify_jobstats "$cmd" "$SINGLEMDS"
16647         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16648             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16649
16650         # Ensure that jobid are present in changelog (if supported by MDS)
16651         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16652                 changelog_dump | tail -10
16653                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16654                 [ $jobids -eq 9 ] ||
16655                         error "Wrong changelog jobid count $jobids != 9"
16656
16657                 # LU-5862
16658                 JOBENV="disable"
16659                 jobstats_set $JOBENV
16660                 touch $DIR/$tfile
16661                 changelog_dump | grep $tfile
16662                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16663                 [ $jobids -eq 0 ] ||
16664                         error "Unexpected jobids when jobid_var=$JOBENV"
16665         fi
16666
16667         # test '%j' access to environment variable - if supported
16668         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16669                 JOBENV="JOBCOMPLEX"
16670                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16671
16672                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16673         fi
16674
16675         # test '%j' access to per-session jobid - if supported
16676         if lctl list_param jobid_this_session > /dev/null 2>&1
16677         then
16678                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16679                 lctl set_param jobid_this_session=$USER
16680
16681                 JOBENV="JOBCOMPLEX"
16682                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16683
16684                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16685         fi
16686 }
16687 run_test 205a "Verify job stats"
16688
16689 # LU-13117, LU-13597
16690 test_205b() {
16691         job_stats="mdt.*.job_stats"
16692         $LCTL set_param $job_stats=clear
16693         # Setting jobid_var to USER might not be supported
16694         $LCTL set_param jobid_var=USER || true
16695         $LCTL set_param jobid_name="%e.%u"
16696         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16697         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16698                 grep "job_id:.*foolish" &&
16699                         error "Unexpected jobid found"
16700         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16701                 grep "open:.*min.*max.*sum" ||
16702                         error "wrong job_stats format found"
16703 }
16704 run_test 205b "Verify job stats jobid and output format"
16705
16706 # LU-13733
16707 test_205c() {
16708         $LCTL set_param llite.*.stats=0
16709         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16710         $LCTL get_param llite.*.stats
16711         $LCTL get_param llite.*.stats | grep \
16712                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16713                         error "wrong client stats format found"
16714 }
16715 run_test 205c "Verify client stats format"
16716
16717 # LU-1480, LU-1773 and LU-1657
16718 test_206() {
16719         mkdir -p $DIR/$tdir
16720         $LFS setstripe -c -1 $DIR/$tdir
16721 #define OBD_FAIL_LOV_INIT 0x1403
16722         $LCTL set_param fail_loc=0xa0001403
16723         $LCTL set_param fail_val=1
16724         touch $DIR/$tdir/$tfile || true
16725 }
16726 run_test 206 "fail lov_init_raid0() doesn't lbug"
16727
16728 test_207a() {
16729         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16730         local fsz=`stat -c %s $DIR/$tfile`
16731         cancel_lru_locks mdc
16732
16733         # do not return layout in getattr intent
16734 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16735         $LCTL set_param fail_loc=0x170
16736         local sz=`stat -c %s $DIR/$tfile`
16737
16738         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16739
16740         rm -rf $DIR/$tfile
16741 }
16742 run_test 207a "can refresh layout at glimpse"
16743
16744 test_207b() {
16745         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16746         local cksum=`md5sum $DIR/$tfile`
16747         local fsz=`stat -c %s $DIR/$tfile`
16748         cancel_lru_locks mdc
16749         cancel_lru_locks osc
16750
16751         # do not return layout in getattr intent
16752 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16753         $LCTL set_param fail_loc=0x171
16754
16755         # it will refresh layout after the file is opened but before read issues
16756         echo checksum is "$cksum"
16757         echo "$cksum" |md5sum -c --quiet || error "file differs"
16758
16759         rm -rf $DIR/$tfile
16760 }
16761 run_test 207b "can refresh layout at open"
16762
16763 test_208() {
16764         # FIXME: in this test suite, only RD lease is used. This is okay
16765         # for now as only exclusive open is supported. After generic lease
16766         # is done, this test suite should be revised. - Jinshan
16767
16768         remote_mds_nodsh && skip "remote MDS with nodsh"
16769         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16770                 skip "Need MDS version at least 2.4.52"
16771
16772         echo "==== test 1: verify get lease work"
16773         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16774
16775         echo "==== test 2: verify lease can be broken by upcoming open"
16776         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16777         local PID=$!
16778         sleep 1
16779
16780         $MULTIOP $DIR/$tfile oO_RDONLY:c
16781         kill -USR1 $PID && wait $PID || error "break lease error"
16782
16783         echo "==== test 3: verify lease can't be granted if an open already exists"
16784         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16785         local PID=$!
16786         sleep 1
16787
16788         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16789         kill -USR1 $PID && wait $PID || error "open file error"
16790
16791         echo "==== test 4: lease can sustain over recovery"
16792         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16793         PID=$!
16794         sleep 1
16795
16796         fail mds1
16797
16798         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16799
16800         echo "==== test 5: lease broken can't be regained by replay"
16801         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16802         PID=$!
16803         sleep 1
16804
16805         # open file to break lease and then recovery
16806         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16807         fail mds1
16808
16809         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16810
16811         rm -f $DIR/$tfile
16812 }
16813 run_test 208 "Exclusive open"
16814
16815 test_209() {
16816         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16817                 skip_env "must have disp_stripe"
16818
16819         touch $DIR/$tfile
16820         sync; sleep 5; sync;
16821
16822         echo 3 > /proc/sys/vm/drop_caches
16823         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16824                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16825         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16826
16827         # open/close 500 times
16828         for i in $(seq 500); do
16829                 cat $DIR/$tfile
16830         done
16831
16832         echo 3 > /proc/sys/vm/drop_caches
16833         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16834                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16835         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16836
16837         echo "before: $req_before, after: $req_after"
16838         [ $((req_after - req_before)) -ge 300 ] &&
16839                 error "open/close requests are not freed"
16840         return 0
16841 }
16842 run_test 209 "read-only open/close requests should be freed promptly"
16843
16844 test_210() {
16845         local pid
16846
16847         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16848         pid=$!
16849         sleep 1
16850
16851         $LFS getstripe $DIR/$tfile
16852         kill -USR1 $pid
16853         wait $pid || error "multiop failed"
16854
16855         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16856         pid=$!
16857         sleep 1
16858
16859         $LFS getstripe $DIR/$tfile
16860         kill -USR1 $pid
16861         wait $pid || error "multiop failed"
16862 }
16863 run_test 210 "lfs getstripe does not break leases"
16864
16865 test_212() {
16866         size=`date +%s`
16867         size=$((size % 8192 + 1))
16868         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16869         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16870         rm -f $DIR/f212 $DIR/f212.xyz
16871 }
16872 run_test 212 "Sendfile test ============================================"
16873
16874 test_213() {
16875         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16876         cancel_lru_locks osc
16877         lctl set_param fail_loc=0x8000040f
16878         # generate a read lock
16879         cat $DIR/$tfile > /dev/null
16880         # write to the file, it will try to cancel the above read lock.
16881         cat /etc/hosts >> $DIR/$tfile
16882 }
16883 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16884
16885 test_214() { # for bug 20133
16886         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16887         for (( i=0; i < 340; i++ )) ; do
16888                 touch $DIR/$tdir/d214c/a$i
16889         done
16890
16891         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16892         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16893         ls $DIR/d214c || error "ls $DIR/d214c failed"
16894         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16895         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16896 }
16897 run_test 214 "hash-indexed directory test - bug 20133"
16898
16899 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16900 create_lnet_proc_files() {
16901         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16902 }
16903
16904 # counterpart of create_lnet_proc_files
16905 remove_lnet_proc_files() {
16906         rm -f $TMP/lnet_$1.sys
16907 }
16908
16909 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16910 # 3rd arg as regexp for body
16911 check_lnet_proc_stats() {
16912         local l=$(cat "$TMP/lnet_$1" |wc -l)
16913         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16914
16915         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16916 }
16917
16918 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16919 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16920 # optional and can be regexp for 2nd line (lnet.routes case)
16921 check_lnet_proc_entry() {
16922         local blp=2          # blp stands for 'position of 1st line of body'
16923         [ -z "$5" ] || blp=3 # lnet.routes case
16924
16925         local l=$(cat "$TMP/lnet_$1" |wc -l)
16926         # subtracting one from $blp because the body can be empty
16927         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16928
16929         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16930                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16931
16932         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16933                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16934
16935         # bail out if any unexpected line happened
16936         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16937         [ "$?" != 0 ] || error "$2 misformatted"
16938 }
16939
16940 test_215() { # for bugs 18102, 21079, 21517
16941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16942
16943         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16944         local P='[1-9][0-9]*'           # positive numeric
16945         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16946         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16947         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16948         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16949
16950         local L1 # regexp for 1st line
16951         local L2 # regexp for 2nd line (optional)
16952         local BR # regexp for the rest (body)
16953
16954         # lnet.stats should look as 11 space-separated non-negative numerics
16955         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16956         create_lnet_proc_files "stats"
16957         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16958         remove_lnet_proc_files "stats"
16959
16960         # lnet.routes should look like this:
16961         # Routing disabled/enabled
16962         # net hops priority state router
16963         # where net is a string like tcp0, hops > 0, priority >= 0,
16964         # state is up/down,
16965         # router is a string like 192.168.1.1@tcp2
16966         L1="^Routing (disabled|enabled)$"
16967         L2="^net +hops +priority +state +router$"
16968         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16969         create_lnet_proc_files "routes"
16970         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16971         remove_lnet_proc_files "routes"
16972
16973         # lnet.routers should look like this:
16974         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16975         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16976         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16977         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16978         L1="^ref +rtr_ref +alive +router$"
16979         BR="^$P +$P +(up|down) +$NID$"
16980         create_lnet_proc_files "routers"
16981         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16982         remove_lnet_proc_files "routers"
16983
16984         # lnet.peers should look like this:
16985         # nid refs state last max rtr min tx min queue
16986         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16987         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16988         # numeric (0 or >0 or <0), queue >= 0.
16989         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16990         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16991         create_lnet_proc_files "peers"
16992         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16993         remove_lnet_proc_files "peers"
16994
16995         # lnet.buffers  should look like this:
16996         # pages count credits min
16997         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16998         L1="^pages +count +credits +min$"
16999         BR="^ +$N +$N +$I +$I$"
17000         create_lnet_proc_files "buffers"
17001         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17002         remove_lnet_proc_files "buffers"
17003
17004         # lnet.nis should look like this:
17005         # nid status alive refs peer rtr max tx min
17006         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17007         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17008         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17009         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17010         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17011         create_lnet_proc_files "nis"
17012         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17013         remove_lnet_proc_files "nis"
17014
17015         # can we successfully write to lnet.stats?
17016         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17017 }
17018 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17019
17020 test_216() { # bug 20317
17021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17022         remote_ost_nodsh && skip "remote OST with nodsh"
17023
17024         local node
17025         local facets=$(get_facets OST)
17026         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17027
17028         save_lustre_params client "osc.*.contention_seconds" > $p
17029         save_lustre_params $facets \
17030                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17031         save_lustre_params $facets \
17032                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17033         save_lustre_params $facets \
17034                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17035         clear_stats osc.*.osc_stats
17036
17037         # agressive lockless i/o settings
17038         do_nodes $(comma_list $(osts_nodes)) \
17039                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17040                         ldlm.namespaces.filter-*.contended_locks=0 \
17041                         ldlm.namespaces.filter-*.contention_seconds=60"
17042         lctl set_param -n osc.*.contention_seconds=60
17043
17044         $DIRECTIO write $DIR/$tfile 0 10 4096
17045         $CHECKSTAT -s 40960 $DIR/$tfile
17046
17047         # disable lockless i/o
17048         do_nodes $(comma_list $(osts_nodes)) \
17049                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17050                         ldlm.namespaces.filter-*.contended_locks=32 \
17051                         ldlm.namespaces.filter-*.contention_seconds=0"
17052         lctl set_param -n osc.*.contention_seconds=0
17053         clear_stats osc.*.osc_stats
17054
17055         dd if=/dev/zero of=$DIR/$tfile count=0
17056         $CHECKSTAT -s 0 $DIR/$tfile
17057
17058         restore_lustre_params <$p
17059         rm -f $p
17060         rm $DIR/$tfile
17061 }
17062 run_test 216 "check lockless direct write updates file size and kms correctly"
17063
17064 test_217() { # bug 22430
17065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17066
17067         local node
17068         local nid
17069
17070         for node in $(nodes_list); do
17071                 nid=$(host_nids_address $node $NETTYPE)
17072                 if [[ $nid = *-* ]] ; then
17073                         echo "lctl ping $(h2nettype $nid)"
17074                         lctl ping $(h2nettype $nid)
17075                 else
17076                         echo "skipping $node (no hyphen detected)"
17077                 fi
17078         done
17079 }
17080 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17081
17082 test_218() {
17083        # do directio so as not to populate the page cache
17084        log "creating a 10 Mb file"
17085        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17086        log "starting reads"
17087        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17088        log "truncating the file"
17089        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17090        log "killing dd"
17091        kill %+ || true # reads might have finished
17092        echo "wait until dd is finished"
17093        wait
17094        log "removing the temporary file"
17095        rm -rf $DIR/$tfile || error "tmp file removal failed"
17096 }
17097 run_test 218 "parallel read and truncate should not deadlock"
17098
17099 test_219() {
17100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17101
17102         # write one partial page
17103         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17104         # set no grant so vvp_io_commit_write will do sync write
17105         $LCTL set_param fail_loc=0x411
17106         # write a full page at the end of file
17107         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17108
17109         $LCTL set_param fail_loc=0
17110         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17111         $LCTL set_param fail_loc=0x411
17112         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17113
17114         # LU-4201
17115         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17116         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17117 }
17118 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17119
17120 test_220() { #LU-325
17121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17122         remote_ost_nodsh && skip "remote OST with nodsh"
17123         remote_mds_nodsh && skip "remote MDS with nodsh"
17124         remote_mgs_nodsh && skip "remote MGS with nodsh"
17125
17126         local OSTIDX=0
17127
17128         # create on MDT0000 so the last_id and next_id are correct
17129         mkdir $DIR/$tdir
17130         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17131         OST=${OST%_UUID}
17132
17133         # on the mdt's osc
17134         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17135         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17136                         osp.$mdtosc_proc1.prealloc_last_id)
17137         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17138                         osp.$mdtosc_proc1.prealloc_next_id)
17139
17140         $LFS df -i
17141
17142         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17143         #define OBD_FAIL_OST_ENOINO              0x229
17144         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17145         create_pool $FSNAME.$TESTNAME || return 1
17146         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17147
17148         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17149
17150         MDSOBJS=$((last_id - next_id))
17151         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17152
17153         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17154         echo "OST still has $count kbytes free"
17155
17156         echo "create $MDSOBJS files @next_id..."
17157         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17158
17159         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17160                         osp.$mdtosc_proc1.prealloc_last_id)
17161         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17162                         osp.$mdtosc_proc1.prealloc_next_id)
17163
17164         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17165         $LFS df -i
17166
17167         echo "cleanup..."
17168
17169         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17170         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17171
17172         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17173                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17174         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17175                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17176         echo "unlink $MDSOBJS files @$next_id..."
17177         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17178 }
17179 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17180
17181 test_221() {
17182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17183
17184         dd if=`which date` of=$MOUNT/date oflag=sync
17185         chmod +x $MOUNT/date
17186
17187         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17188         $LCTL set_param fail_loc=0x80001401
17189
17190         $MOUNT/date > /dev/null
17191         rm -f $MOUNT/date
17192 }
17193 run_test 221 "make sure fault and truncate race to not cause OOM"
17194
17195 test_222a () {
17196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17197
17198         rm -rf $DIR/$tdir
17199         test_mkdir $DIR/$tdir
17200         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17201         createmany -o $DIR/$tdir/$tfile 10
17202         cancel_lru_locks mdc
17203         cancel_lru_locks osc
17204         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17205         $LCTL set_param fail_loc=0x31a
17206         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17207         $LCTL set_param fail_loc=0
17208         rm -r $DIR/$tdir
17209 }
17210 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17211
17212 test_222b () {
17213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17214
17215         rm -rf $DIR/$tdir
17216         test_mkdir $DIR/$tdir
17217         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17218         createmany -o $DIR/$tdir/$tfile 10
17219         cancel_lru_locks mdc
17220         cancel_lru_locks osc
17221         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17222         $LCTL set_param fail_loc=0x31a
17223         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17224         $LCTL set_param fail_loc=0
17225 }
17226 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17227
17228 test_223 () {
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230
17231         rm -rf $DIR/$tdir
17232         test_mkdir $DIR/$tdir
17233         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17234         createmany -o $DIR/$tdir/$tfile 10
17235         cancel_lru_locks mdc
17236         cancel_lru_locks osc
17237         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17238         $LCTL set_param fail_loc=0x31b
17239         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17240         $LCTL set_param fail_loc=0
17241         rm -r $DIR/$tdir
17242 }
17243 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17244
17245 test_224a() { # LU-1039, MRP-303
17246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17247
17248         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17249         $LCTL set_param fail_loc=0x508
17250         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17251         $LCTL set_param fail_loc=0
17252         df $DIR
17253 }
17254 run_test 224a "Don't panic on bulk IO failure"
17255
17256 test_224b() { # LU-1039, MRP-303
17257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17258
17259         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17260         cancel_lru_locks osc
17261         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17262         $LCTL set_param fail_loc=0x515
17263         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17264         $LCTL set_param fail_loc=0
17265         df $DIR
17266 }
17267 run_test 224b "Don't panic on bulk IO failure"
17268
17269 test_224c() { # LU-6441
17270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17271         remote_mds_nodsh && skip "remote MDS with nodsh"
17272
17273         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17274         save_writethrough $p
17275         set_cache writethrough on
17276
17277         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17278         local at_max=$($LCTL get_param -n at_max)
17279         local timeout=$($LCTL get_param -n timeout)
17280         local test_at="at_max"
17281         local param_at="$FSNAME.sys.at_max"
17282         local test_timeout="timeout"
17283         local param_timeout="$FSNAME.sys.timeout"
17284
17285         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17286
17287         set_persistent_param_and_check client "$test_at" "$param_at" 0
17288         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17289
17290         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17291         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17292         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17293         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17294         sync
17295         do_facet ost1 "$LCTL set_param fail_loc=0"
17296
17297         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17298         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17299                 $timeout
17300
17301         $LCTL set_param -n $pages_per_rpc
17302         restore_lustre_params < $p
17303         rm -f $p
17304 }
17305 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17306
17307 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17308 test_225a () {
17309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17310         if [ -z ${MDSSURVEY} ]; then
17311                 skip_env "mds-survey not found"
17312         fi
17313         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17314                 skip "Need MDS version at least 2.2.51"
17315
17316         local mds=$(facet_host $SINGLEMDS)
17317         local target=$(do_nodes $mds 'lctl dl' |
17318                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17319
17320         local cmd1="file_count=1000 thrhi=4"
17321         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17322         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17323         local cmd="$cmd1 $cmd2 $cmd3"
17324
17325         rm -f ${TMP}/mds_survey*
17326         echo + $cmd
17327         eval $cmd || error "mds-survey with zero-stripe failed"
17328         cat ${TMP}/mds_survey*
17329         rm -f ${TMP}/mds_survey*
17330 }
17331 run_test 225a "Metadata survey sanity with zero-stripe"
17332
17333 test_225b () {
17334         if [ -z ${MDSSURVEY} ]; then
17335                 skip_env "mds-survey not found"
17336         fi
17337         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17338                 skip "Need MDS version at least 2.2.51"
17339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17340         remote_mds_nodsh && skip "remote MDS with nodsh"
17341         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17342                 skip_env "Need to mount OST to test"
17343         fi
17344
17345         local mds=$(facet_host $SINGLEMDS)
17346         local target=$(do_nodes $mds 'lctl dl' |
17347                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17348
17349         local cmd1="file_count=1000 thrhi=4"
17350         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17351         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17352         local cmd="$cmd1 $cmd2 $cmd3"
17353
17354         rm -f ${TMP}/mds_survey*
17355         echo + $cmd
17356         eval $cmd || error "mds-survey with stripe_count failed"
17357         cat ${TMP}/mds_survey*
17358         rm -f ${TMP}/mds_survey*
17359 }
17360 run_test 225b "Metadata survey sanity with stripe_count = 1"
17361
17362 mcreate_path2fid () {
17363         local mode=$1
17364         local major=$2
17365         local minor=$3
17366         local name=$4
17367         local desc=$5
17368         local path=$DIR/$tdir/$name
17369         local fid
17370         local rc
17371         local fid_path
17372
17373         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17374                 error "cannot create $desc"
17375
17376         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17377         rc=$?
17378         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17379
17380         fid_path=$($LFS fid2path $MOUNT $fid)
17381         rc=$?
17382         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17383
17384         [ "$path" == "$fid_path" ] ||
17385                 error "fid2path returned $fid_path, expected $path"
17386
17387         echo "pass with $path and $fid"
17388 }
17389
17390 test_226a () {
17391         rm -rf $DIR/$tdir
17392         mkdir -p $DIR/$tdir
17393
17394         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17395         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17396         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17397         mcreate_path2fid 0040666 0 0 dir "directory"
17398         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17399         mcreate_path2fid 0100666 0 0 file "regular file"
17400         mcreate_path2fid 0120666 0 0 link "symbolic link"
17401         mcreate_path2fid 0140666 0 0 sock "socket"
17402 }
17403 run_test 226a "call path2fid and fid2path on files of all type"
17404
17405 test_226b () {
17406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17407
17408         local MDTIDX=1
17409
17410         rm -rf $DIR/$tdir
17411         mkdir -p $DIR/$tdir
17412         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17413                 error "create remote directory failed"
17414         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17415         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17416                                 "character special file (null)"
17417         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17418                                 "character special file (no device)"
17419         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17420         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17421                                 "block special file (loop)"
17422         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17423         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17424         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17425 }
17426 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17427
17428 test_226c () {
17429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17430         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17431                 skip "Need MDS version at least 2.13.55"
17432
17433         local submnt=/mnt/submnt
17434         local srcfile=/etc/passwd
17435         local dstfile=$submnt/passwd
17436         local path
17437         local fid
17438
17439         rm -rf $DIR/$tdir
17440         rm -rf $submnt
17441         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17442                 error "create remote directory failed"
17443         mkdir -p $submnt || error "create $submnt failed"
17444         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17445                 error "mount $submnt failed"
17446         stack_trap "umount $submnt" EXIT
17447
17448         cp $srcfile $dstfile
17449         fid=$($LFS path2fid $dstfile)
17450         path=$($LFS fid2path $submnt "$fid")
17451         [ "$path" = "$dstfile" ] ||
17452                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17453 }
17454 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17455
17456 # LU-1299 Executing or running ldd on a truncated executable does not
17457 # cause an out-of-memory condition.
17458 test_227() {
17459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17460         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17461
17462         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17463         chmod +x $MOUNT/date
17464
17465         $MOUNT/date > /dev/null
17466         ldd $MOUNT/date > /dev/null
17467         rm -f $MOUNT/date
17468 }
17469 run_test 227 "running truncated executable does not cause OOM"
17470
17471 # LU-1512 try to reuse idle OI blocks
17472 test_228a() {
17473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17474         remote_mds_nodsh && skip "remote MDS with nodsh"
17475         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17476
17477         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17478         local myDIR=$DIR/$tdir
17479
17480         mkdir -p $myDIR
17481         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17482         $LCTL set_param fail_loc=0x80001002
17483         createmany -o $myDIR/t- 10000
17484         $LCTL set_param fail_loc=0
17485         # The guard is current the largest FID holder
17486         touch $myDIR/guard
17487         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17488                     tr -d '[')
17489         local IDX=$(($SEQ % 64))
17490
17491         do_facet $SINGLEMDS sync
17492         # Make sure journal flushed.
17493         sleep 6
17494         local blk1=$(do_facet $SINGLEMDS \
17495                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17496                      grep Blockcount | awk '{print $4}')
17497
17498         # Remove old files, some OI blocks will become idle.
17499         unlinkmany $myDIR/t- 10000
17500         # Create new files, idle OI blocks should be reused.
17501         createmany -o $myDIR/t- 2000
17502         do_facet $SINGLEMDS sync
17503         # Make sure journal flushed.
17504         sleep 6
17505         local blk2=$(do_facet $SINGLEMDS \
17506                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17507                      grep Blockcount | awk '{print $4}')
17508
17509         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17510 }
17511 run_test 228a "try to reuse idle OI blocks"
17512
17513 test_228b() {
17514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17515         remote_mds_nodsh && skip "remote MDS with nodsh"
17516         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17517
17518         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17519         local myDIR=$DIR/$tdir
17520
17521         mkdir -p $myDIR
17522         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17523         $LCTL set_param fail_loc=0x80001002
17524         createmany -o $myDIR/t- 10000
17525         $LCTL set_param fail_loc=0
17526         # The guard is current the largest FID holder
17527         touch $myDIR/guard
17528         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17529                     tr -d '[')
17530         local IDX=$(($SEQ % 64))
17531
17532         do_facet $SINGLEMDS sync
17533         # Make sure journal flushed.
17534         sleep 6
17535         local blk1=$(do_facet $SINGLEMDS \
17536                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17537                      grep Blockcount | awk '{print $4}')
17538
17539         # Remove old files, some OI blocks will become idle.
17540         unlinkmany $myDIR/t- 10000
17541
17542         # stop the MDT
17543         stop $SINGLEMDS || error "Fail to stop MDT."
17544         # remount the MDT
17545         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17546
17547         df $MOUNT || error "Fail to df."
17548         # Create new files, idle OI blocks should be reused.
17549         createmany -o $myDIR/t- 2000
17550         do_facet $SINGLEMDS sync
17551         # Make sure journal flushed.
17552         sleep 6
17553         local blk2=$(do_facet $SINGLEMDS \
17554                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17555                      grep Blockcount | awk '{print $4}')
17556
17557         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17558 }
17559 run_test 228b "idle OI blocks can be reused after MDT restart"
17560
17561 #LU-1881
17562 test_228c() {
17563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17564         remote_mds_nodsh && skip "remote MDS with nodsh"
17565         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17566
17567         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17568         local myDIR=$DIR/$tdir
17569
17570         mkdir -p $myDIR
17571         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17572         $LCTL set_param fail_loc=0x80001002
17573         # 20000 files can guarantee there are index nodes in the OI file
17574         createmany -o $myDIR/t- 20000
17575         $LCTL set_param fail_loc=0
17576         # The guard is current the largest FID holder
17577         touch $myDIR/guard
17578         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17579                     tr -d '[')
17580         local IDX=$(($SEQ % 64))
17581
17582         do_facet $SINGLEMDS sync
17583         # Make sure journal flushed.
17584         sleep 6
17585         local blk1=$(do_facet $SINGLEMDS \
17586                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17587                      grep Blockcount | awk '{print $4}')
17588
17589         # Remove old files, some OI blocks will become idle.
17590         unlinkmany $myDIR/t- 20000
17591         rm -f $myDIR/guard
17592         # The OI file should become empty now
17593
17594         # Create new files, idle OI blocks should be reused.
17595         createmany -o $myDIR/t- 2000
17596         do_facet $SINGLEMDS sync
17597         # Make sure journal flushed.
17598         sleep 6
17599         local blk2=$(do_facet $SINGLEMDS \
17600                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17601                      grep Blockcount | awk '{print $4}')
17602
17603         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17604 }
17605 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17606
17607 test_229() { # LU-2482, LU-3448
17608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17609         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17610         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17611                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17612
17613         rm -f $DIR/$tfile
17614
17615         # Create a file with a released layout and stripe count 2.
17616         $MULTIOP $DIR/$tfile H2c ||
17617                 error "failed to create file with released layout"
17618
17619         $LFS getstripe -v $DIR/$tfile
17620
17621         local pattern=$($LFS getstripe -L $DIR/$tfile)
17622         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17623
17624         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17625                 error "getstripe"
17626         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17627         stat $DIR/$tfile || error "failed to stat released file"
17628
17629         chown $RUNAS_ID $DIR/$tfile ||
17630                 error "chown $RUNAS_ID $DIR/$tfile failed"
17631
17632         chgrp $RUNAS_ID $DIR/$tfile ||
17633                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17634
17635         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17636         rm $DIR/$tfile || error "failed to remove released file"
17637 }
17638 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17639
17640 test_230a() {
17641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17642         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17643         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17644                 skip "Need MDS version at least 2.11.52"
17645
17646         local MDTIDX=1
17647
17648         test_mkdir $DIR/$tdir
17649         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17650         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17651         [ $mdt_idx -ne 0 ] &&
17652                 error "create local directory on wrong MDT $mdt_idx"
17653
17654         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17655                         error "create remote directory failed"
17656         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17657         [ $mdt_idx -ne $MDTIDX ] &&
17658                 error "create remote directory on wrong MDT $mdt_idx"
17659
17660         createmany -o $DIR/$tdir/test_230/t- 10 ||
17661                 error "create files on remote directory failed"
17662         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17663         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17664         rm -r $DIR/$tdir || error "unlink remote directory failed"
17665 }
17666 run_test 230a "Create remote directory and files under the remote directory"
17667
17668 test_230b() {
17669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17671         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17672                 skip "Need MDS version at least 2.11.52"
17673
17674         local MDTIDX=1
17675         local mdt_index
17676         local i
17677         local file
17678         local pid
17679         local stripe_count
17680         local migrate_dir=$DIR/$tdir/migrate_dir
17681         local other_dir=$DIR/$tdir/other_dir
17682
17683         test_mkdir $DIR/$tdir
17684         test_mkdir -i0 -c1 $migrate_dir
17685         test_mkdir -i0 -c1 $other_dir
17686         for ((i=0; i<10; i++)); do
17687                 mkdir -p $migrate_dir/dir_${i}
17688                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17689                         error "create files under remote dir failed $i"
17690         done
17691
17692         cp /etc/passwd $migrate_dir/$tfile
17693         cp /etc/passwd $other_dir/$tfile
17694         chattr +SAD $migrate_dir
17695         chattr +SAD $migrate_dir/$tfile
17696
17697         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17698         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17699         local old_dir_mode=$(stat -c%f $migrate_dir)
17700         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17701
17702         mkdir -p $migrate_dir/dir_default_stripe2
17703         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17704         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17705
17706         mkdir -p $other_dir
17707         ln $migrate_dir/$tfile $other_dir/luna
17708         ln $migrate_dir/$tfile $migrate_dir/sofia
17709         ln $other_dir/$tfile $migrate_dir/david
17710         ln -s $migrate_dir/$tfile $other_dir/zachary
17711         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17712         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17713
17714         local len
17715         local lnktgt
17716
17717         # inline symlink
17718         for len in 58 59 60; do
17719                 lnktgt=$(str_repeat 'l' $len)
17720                 touch $migrate_dir/$lnktgt
17721                 ln -s $lnktgt $migrate_dir/${len}char_ln
17722         done
17723
17724         # PATH_MAX
17725         for len in 4094 4095; do
17726                 lnktgt=$(str_repeat 'l' $len)
17727                 ln -s $lnktgt $migrate_dir/${len}char_ln
17728         done
17729
17730         # NAME_MAX
17731         for len in 254 255; do
17732                 touch $migrate_dir/$(str_repeat 'l' $len)
17733         done
17734
17735         $LFS migrate -m $MDTIDX $migrate_dir ||
17736                 error "fails on migrating remote dir to MDT1"
17737
17738         echo "migratate to MDT1, then checking.."
17739         for ((i = 0; i < 10; i++)); do
17740                 for file in $(find $migrate_dir/dir_${i}); do
17741                         mdt_index=$($LFS getstripe -m $file)
17742                         # broken symlink getstripe will fail
17743                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17744                                 error "$file is not on MDT${MDTIDX}"
17745                 done
17746         done
17747
17748         # the multiple link file should still in MDT0
17749         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17750         [ $mdt_index == 0 ] ||
17751                 error "$file is not on MDT${MDTIDX}"
17752
17753         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17754         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17755                 error " expect $old_dir_flag get $new_dir_flag"
17756
17757         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17758         [ "$old_file_flag" = "$new_file_flag" ] ||
17759                 error " expect $old_file_flag get $new_file_flag"
17760
17761         local new_dir_mode=$(stat -c%f $migrate_dir)
17762         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17763                 error "expect mode $old_dir_mode get $new_dir_mode"
17764
17765         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17766         [ "$old_file_mode" = "$new_file_mode" ] ||
17767                 error "expect mode $old_file_mode get $new_file_mode"
17768
17769         diff /etc/passwd $migrate_dir/$tfile ||
17770                 error "$tfile different after migration"
17771
17772         diff /etc/passwd $other_dir/luna ||
17773                 error "luna different after migration"
17774
17775         diff /etc/passwd $migrate_dir/sofia ||
17776                 error "sofia different after migration"
17777
17778         diff /etc/passwd $migrate_dir/david ||
17779                 error "david different after migration"
17780
17781         diff /etc/passwd $other_dir/zachary ||
17782                 error "zachary different after migration"
17783
17784         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17785                 error "${tfile}_ln different after migration"
17786
17787         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17788                 error "${tfile}_ln_other different after migration"
17789
17790         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17791         [ $stripe_count = 2 ] ||
17792                 error "dir strpe_count $d != 2 after migration."
17793
17794         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17795         [ $stripe_count = 2 ] ||
17796                 error "file strpe_count $d != 2 after migration."
17797
17798         #migrate back to MDT0
17799         MDTIDX=0
17800
17801         $LFS migrate -m $MDTIDX $migrate_dir ||
17802                 error "fails on migrating remote dir to MDT0"
17803
17804         echo "migrate back to MDT0, checking.."
17805         for file in $(find $migrate_dir); do
17806                 mdt_index=$($LFS getstripe -m $file)
17807                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17808                         error "$file is not on MDT${MDTIDX}"
17809         done
17810
17811         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17812         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17813                 error " expect $old_dir_flag get $new_dir_flag"
17814
17815         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17816         [ "$old_file_flag" = "$new_file_flag" ] ||
17817                 error " expect $old_file_flag get $new_file_flag"
17818
17819         local new_dir_mode=$(stat -c%f $migrate_dir)
17820         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17821                 error "expect mode $old_dir_mode get $new_dir_mode"
17822
17823         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17824         [ "$old_file_mode" = "$new_file_mode" ] ||
17825                 error "expect mode $old_file_mode get $new_file_mode"
17826
17827         diff /etc/passwd ${migrate_dir}/$tfile ||
17828                 error "$tfile different after migration"
17829
17830         diff /etc/passwd ${other_dir}/luna ||
17831                 error "luna different after migration"
17832
17833         diff /etc/passwd ${migrate_dir}/sofia ||
17834                 error "sofia different after migration"
17835
17836         diff /etc/passwd ${other_dir}/zachary ||
17837                 error "zachary different after migration"
17838
17839         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17840                 error "${tfile}_ln different after migration"
17841
17842         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17843                 error "${tfile}_ln_other different after migration"
17844
17845         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17846         [ $stripe_count = 2 ] ||
17847                 error "dir strpe_count $d != 2 after migration."
17848
17849         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17850         [ $stripe_count = 2 ] ||
17851                 error "file strpe_count $d != 2 after migration."
17852
17853         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17854 }
17855 run_test 230b "migrate directory"
17856
17857 test_230c() {
17858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17860         remote_mds_nodsh && skip "remote MDS with nodsh"
17861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17862                 skip "Need MDS version at least 2.11.52"
17863
17864         local MDTIDX=1
17865         local total=3
17866         local mdt_index
17867         local file
17868         local migrate_dir=$DIR/$tdir/migrate_dir
17869
17870         #If migrating directory fails in the middle, all entries of
17871         #the directory is still accessiable.
17872         test_mkdir $DIR/$tdir
17873         test_mkdir -i0 -c1 $migrate_dir
17874         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17875         stat $migrate_dir
17876         createmany -o $migrate_dir/f $total ||
17877                 error "create files under ${migrate_dir} failed"
17878
17879         # fail after migrating top dir, and this will fail only once, so the
17880         # first sub file migration will fail (currently f3), others succeed.
17881         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17882         do_facet mds1 lctl set_param fail_loc=0x1801
17883         local t=$(ls $migrate_dir | wc -l)
17884         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17885                 error "migrate should fail"
17886         local u=$(ls $migrate_dir | wc -l)
17887         [ "$u" == "$t" ] || error "$u != $t during migration"
17888
17889         # add new dir/file should succeed
17890         mkdir $migrate_dir/dir ||
17891                 error "mkdir failed under migrating directory"
17892         touch $migrate_dir/file ||
17893                 error "create file failed under migrating directory"
17894
17895         # add file with existing name should fail
17896         for file in $migrate_dir/f*; do
17897                 stat $file > /dev/null || error "stat $file failed"
17898                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17899                         error "open(O_CREAT|O_EXCL) $file should fail"
17900                 $MULTIOP $file m && error "create $file should fail"
17901                 touch $DIR/$tdir/remote_dir/$tfile ||
17902                         error "touch $tfile failed"
17903                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17904                         error "link $file should fail"
17905                 mdt_index=$($LFS getstripe -m $file)
17906                 if [ $mdt_index == 0 ]; then
17907                         # file failed to migrate is not allowed to rename to
17908                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17909                                 error "rename to $file should fail"
17910                 else
17911                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17912                                 error "rename to $file failed"
17913                 fi
17914                 echo hello >> $file || error "write $file failed"
17915         done
17916
17917         # resume migration with different options should fail
17918         $LFS migrate -m 0 $migrate_dir &&
17919                 error "migrate -m 0 $migrate_dir should fail"
17920
17921         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17922                 error "migrate -c 2 $migrate_dir should fail"
17923
17924         # resume migration should succeed
17925         $LFS migrate -m $MDTIDX $migrate_dir ||
17926                 error "migrate $migrate_dir failed"
17927
17928         echo "Finish migration, then checking.."
17929         for file in $(find $migrate_dir); do
17930                 mdt_index=$($LFS getstripe -m $file)
17931                 [ $mdt_index == $MDTIDX ] ||
17932                         error "$file is not on MDT${MDTIDX}"
17933         done
17934
17935         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17936 }
17937 run_test 230c "check directory accessiblity if migration failed"
17938
17939 test_230d() {
17940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17942         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17943                 skip "Need MDS version at least 2.11.52"
17944         # LU-11235
17945         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17946
17947         local migrate_dir=$DIR/$tdir/migrate_dir
17948         local old_index
17949         local new_index
17950         local old_count
17951         local new_count
17952         local new_hash
17953         local mdt_index
17954         local i
17955         local j
17956
17957         old_index=$((RANDOM % MDSCOUNT))
17958         old_count=$((MDSCOUNT - old_index))
17959         new_index=$((RANDOM % MDSCOUNT))
17960         new_count=$((MDSCOUNT - new_index))
17961         new_hash=1 # for all_char
17962
17963         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17964         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17965
17966         test_mkdir $DIR/$tdir
17967         test_mkdir -i $old_index -c $old_count $migrate_dir
17968
17969         for ((i=0; i<100; i++)); do
17970                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17971                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17972                         error "create files under remote dir failed $i"
17973         done
17974
17975         echo -n "Migrate from MDT$old_index "
17976         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17977         echo -n "to MDT$new_index"
17978         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17979         echo
17980
17981         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17982         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17983                 error "migrate remote dir error"
17984
17985         echo "Finish migration, then checking.."
17986         for file in $(find $migrate_dir); do
17987                 mdt_index=$($LFS getstripe -m $file)
17988                 if [ $mdt_index -lt $new_index ] ||
17989                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17990                         error "$file is on MDT$mdt_index"
17991                 fi
17992         done
17993
17994         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17995 }
17996 run_test 230d "check migrate big directory"
17997
17998 test_230e() {
17999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18001         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18002                 skip "Need MDS version at least 2.11.52"
18003
18004         local i
18005         local j
18006         local a_fid
18007         local b_fid
18008
18009         mkdir -p $DIR/$tdir
18010         mkdir $DIR/$tdir/migrate_dir
18011         mkdir $DIR/$tdir/other_dir
18012         touch $DIR/$tdir/migrate_dir/a
18013         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18014         ls $DIR/$tdir/other_dir
18015
18016         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18017                 error "migrate dir fails"
18018
18019         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18020         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18021
18022         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18023         [ $mdt_index == 0 ] || error "a is not on MDT0"
18024
18025         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18026                 error "migrate dir fails"
18027
18028         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18029         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18030
18031         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18032         [ $mdt_index == 1 ] || error "a is not on MDT1"
18033
18034         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18035         [ $mdt_index == 1 ] || error "b is not on MDT1"
18036
18037         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18038         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18039
18040         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18041
18042         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18043 }
18044 run_test 230e "migrate mulitple local link files"
18045
18046 test_230f() {
18047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18049         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18050                 skip "Need MDS version at least 2.11.52"
18051
18052         local a_fid
18053         local ln_fid
18054
18055         mkdir -p $DIR/$tdir
18056         mkdir $DIR/$tdir/migrate_dir
18057         $LFS mkdir -i1 $DIR/$tdir/other_dir
18058         touch $DIR/$tdir/migrate_dir/a
18059         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18060         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18061         ls $DIR/$tdir/other_dir
18062
18063         # a should be migrated to MDT1, since no other links on MDT0
18064         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18065                 error "#1 migrate dir fails"
18066         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18067         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18068         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18069         [ $mdt_index == 1 ] || error "a is not on MDT1"
18070
18071         # a should stay on MDT1, because it is a mulitple link file
18072         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18073                 error "#2 migrate dir fails"
18074         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18075         [ $mdt_index == 1 ] || error "a is not on MDT1"
18076
18077         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18078                 error "#3 migrate dir fails"
18079
18080         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18081         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18082         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18083
18084         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18085         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18086
18087         # a should be migrated to MDT0, since no other links on MDT1
18088         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18089                 error "#4 migrate dir fails"
18090         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18091         [ $mdt_index == 0 ] || error "a is not on MDT0"
18092
18093         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18094 }
18095 run_test 230f "migrate mulitple remote link files"
18096
18097 test_230g() {
18098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18099         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18100         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18101                 skip "Need MDS version at least 2.11.52"
18102
18103         mkdir -p $DIR/$tdir/migrate_dir
18104
18105         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18106                 error "migrating dir to non-exist MDT succeeds"
18107         true
18108 }
18109 run_test 230g "migrate dir to non-exist MDT"
18110
18111 test_230h() {
18112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18113         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18114         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18115                 skip "Need MDS version at least 2.11.52"
18116
18117         local mdt_index
18118
18119         mkdir -p $DIR/$tdir/migrate_dir
18120
18121         $LFS migrate -m1 $DIR &&
18122                 error "migrating mountpoint1 should fail"
18123
18124         $LFS migrate -m1 $DIR/$tdir/.. &&
18125                 error "migrating mountpoint2 should fail"
18126
18127         # same as mv
18128         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18129                 error "migrating $tdir/migrate_dir/.. should fail"
18130
18131         true
18132 }
18133 run_test 230h "migrate .. and root"
18134
18135 test_230i() {
18136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18137         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18138         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18139                 skip "Need MDS version at least 2.11.52"
18140
18141         mkdir -p $DIR/$tdir/migrate_dir
18142
18143         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18144                 error "migration fails with a tailing slash"
18145
18146         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18147                 error "migration fails with two tailing slashes"
18148 }
18149 run_test 230i "lfs migrate -m tolerates trailing slashes"
18150
18151 test_230j() {
18152         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18153         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18154                 skip "Need MDS version at least 2.11.52"
18155
18156         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18157         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18158                 error "create $tfile failed"
18159         cat /etc/passwd > $DIR/$tdir/$tfile
18160
18161         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18162
18163         cmp /etc/passwd $DIR/$tdir/$tfile ||
18164                 error "DoM file mismatch after migration"
18165 }
18166 run_test 230j "DoM file data not changed after dir migration"
18167
18168 test_230k() {
18169         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18170         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18171                 skip "Need MDS version at least 2.11.56"
18172
18173         local total=20
18174         local files_on_starting_mdt=0
18175
18176         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18177         $LFS getdirstripe $DIR/$tdir
18178         for i in $(seq $total); do
18179                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18180                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18181                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18182         done
18183
18184         echo "$files_on_starting_mdt files on MDT0"
18185
18186         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18187         $LFS getdirstripe $DIR/$tdir
18188
18189         files_on_starting_mdt=0
18190         for i in $(seq $total); do
18191                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18192                         error "file $tfile.$i mismatch after migration"
18193                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18194                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18195         done
18196
18197         echo "$files_on_starting_mdt files on MDT1 after migration"
18198         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18199
18200         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18201         $LFS getdirstripe $DIR/$tdir
18202
18203         files_on_starting_mdt=0
18204         for i in $(seq $total); do
18205                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18206                         error "file $tfile.$i mismatch after 2nd migration"
18207                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18208                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18209         done
18210
18211         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18212         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18213
18214         true
18215 }
18216 run_test 230k "file data not changed after dir migration"
18217
18218 test_230l() {
18219         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18220         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18221                 skip "Need MDS version at least 2.11.56"
18222
18223         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18224         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18225                 error "create files under remote dir failed $i"
18226         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18227 }
18228 run_test 230l "readdir between MDTs won't crash"
18229
18230 test_230m() {
18231         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18232         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18233                 skip "Need MDS version at least 2.11.56"
18234
18235         local MDTIDX=1
18236         local mig_dir=$DIR/$tdir/migrate_dir
18237         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18238         local shortstr="b"
18239         local val
18240
18241         echo "Creating files and dirs with xattrs"
18242         test_mkdir $DIR/$tdir
18243         test_mkdir -i0 -c1 $mig_dir
18244         mkdir $mig_dir/dir
18245         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18246                 error "cannot set xattr attr1 on dir"
18247         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18248                 error "cannot set xattr attr2 on dir"
18249         touch $mig_dir/dir/f0
18250         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18251                 error "cannot set xattr attr1 on file"
18252         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18253                 error "cannot set xattr attr2 on file"
18254         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18255         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18256         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18257         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18258         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18259         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18260         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18261         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18262         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18263
18264         echo "Migrating to MDT1"
18265         $LFS migrate -m $MDTIDX $mig_dir ||
18266                 error "fails on migrating dir to MDT1"
18267
18268         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18269         echo "Checking xattrs"
18270         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18271         [ "$val" = $longstr ] ||
18272                 error "expecting xattr1 $longstr on dir, found $val"
18273         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18274         [ "$val" = $shortstr ] ||
18275                 error "expecting xattr2 $shortstr on dir, found $val"
18276         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18277         [ "$val" = $longstr ] ||
18278                 error "expecting xattr1 $longstr on file, found $val"
18279         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18280         [ "$val" = $shortstr ] ||
18281                 error "expecting xattr2 $shortstr on file, found $val"
18282 }
18283 run_test 230m "xattrs not changed after dir migration"
18284
18285 test_230n() {
18286         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18287         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18288                 skip "Need MDS version at least 2.13.53"
18289
18290         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18291         cat /etc/hosts > $DIR/$tdir/$tfile
18292         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18293         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18294
18295         cmp /etc/hosts $DIR/$tdir/$tfile ||
18296                 error "File data mismatch after migration"
18297 }
18298 run_test 230n "Dir migration with mirrored file"
18299
18300 test_230o() {
18301         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18302         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18303                 skip "Need MDS version at least 2.13.52"
18304
18305         local mdts=$(comma_list $(mdts_nodes))
18306         local timeout=100
18307
18308         local restripe_status
18309         local delta
18310         local i
18311         local j
18312
18313         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18314
18315         # in case "crush" hash type is not set
18316         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18317
18318         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18319                            mdt.*MDT0000.enable_dir_restripe)
18320         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18321         stack_trap "do_nodes $mdts $LCTL set_param \
18322                     mdt.*.enable_dir_restripe=$restripe_status"
18323
18324         mkdir $DIR/$tdir
18325         createmany -m $DIR/$tdir/f 100 ||
18326                 error "create files under remote dir failed $i"
18327         createmany -d $DIR/$tdir/d 100 ||
18328                 error "create dirs under remote dir failed $i"
18329
18330         for i in $(seq 2 $MDSCOUNT); do
18331                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18332                 $LFS setdirstripe -c $i $DIR/$tdir ||
18333                         error "split -c $i $tdir failed"
18334                 wait_update $HOSTNAME \
18335                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18336                         error "dir split not finished"
18337                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18338                         awk '/migrate/ {sum += $2} END { print sum }')
18339                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18340                 # delta is around total_files/stripe_count
18341                 [ $delta -lt $((200 /(i - 1))) ] ||
18342                         error "$delta files migrated"
18343         done
18344 }
18345 run_test 230o "dir split"
18346
18347 test_230p() {
18348         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18349         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18350                 skip "Need MDS version at least 2.13.52"
18351
18352         local mdts=$(comma_list $(mdts_nodes))
18353         local timeout=100
18354
18355         local restripe_status
18356         local delta
18357         local i
18358         local j
18359
18360         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18361
18362         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18363
18364         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18365                            mdt.*MDT0000.enable_dir_restripe)
18366         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18367         stack_trap "do_nodes $mdts $LCTL set_param \
18368                     mdt.*.enable_dir_restripe=$restripe_status"
18369
18370         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18371         createmany -m $DIR/$tdir/f 100 ||
18372                 error "create files under remote dir failed $i"
18373         createmany -d $DIR/$tdir/d 100 ||
18374                 error "create dirs under remote dir failed $i"
18375
18376         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18377                 local mdt_hash="crush"
18378
18379                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18380                 $LFS setdirstripe -c $i $DIR/$tdir ||
18381                         error "split -c $i $tdir failed"
18382                 [ $i -eq 1 ] && mdt_hash="none"
18383                 wait_update $HOSTNAME \
18384                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18385                         error "dir merge not finished"
18386                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18387                         awk '/migrate/ {sum += $2} END { print sum }')
18388                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18389                 # delta is around total_files/stripe_count
18390                 [ $delta -lt $((200 / i)) ] ||
18391                         error "$delta files migrated"
18392         done
18393 }
18394 run_test 230p "dir merge"
18395
18396 test_230q() {
18397         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18398         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18399                 skip "Need MDS version at least 2.13.52"
18400
18401         local mdts=$(comma_list $(mdts_nodes))
18402         local saved_threshold=$(do_facet mds1 \
18403                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18404         local saved_delta=$(do_facet mds1 \
18405                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18406         local threshold=100
18407         local delta=2
18408         local total=0
18409         local stripe_count=0
18410         local stripe_index
18411         local nr_files
18412
18413         # test with fewer files on ZFS
18414         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18415
18416         stack_trap "do_nodes $mdts $LCTL set_param \
18417                     mdt.*.dir_split_count=$saved_threshold"
18418         stack_trap "do_nodes $mdts $LCTL set_param \
18419                     mdt.*.dir_split_delta=$saved_delta"
18420         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18421         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18422         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18423         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18424         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18425         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18426
18427         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18428         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18429
18430         while [ $stripe_count -lt $MDSCOUNT ]; do
18431                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18432                         error "create sub files failed"
18433                 stat $DIR/$tdir > /dev/null
18434                 total=$((total + threshold * 3 / 2))
18435                 stripe_count=$((stripe_count + delta))
18436                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18437
18438                 wait_update $HOSTNAME \
18439                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18440                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18441
18442                 wait_update $HOSTNAME \
18443                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18444                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18445
18446                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18447                            grep -w $stripe_index | wc -l)
18448                 echo "$nr_files files on MDT$stripe_index after split"
18449                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18450                         error "$nr_files files on MDT$stripe_index after split"
18451
18452                 nr_files=$(ls $DIR/$tdir | wc -w)
18453                 [ $nr_files -eq $total ] ||
18454                         error "total sub files $nr_files != $total"
18455         done
18456 }
18457 run_test 230q "dir auto split"
18458
18459 test_230r() {
18460         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18461         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18462         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18463                 skip "Need MDS version at least 2.13.54"
18464
18465         # maximum amount of local locks:
18466         # parent striped dir - 2 locks
18467         # new stripe in parent to migrate to - 1 lock
18468         # source and target - 2 locks
18469         # Total 5 locks for regular file
18470         mkdir -p $DIR/$tdir
18471         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18472         touch $DIR/$tdir/dir1/eee
18473
18474         # create 4 hardlink for 4 more locks
18475         # Total: 9 locks > RS_MAX_LOCKS (8)
18476         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18477         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18478         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18479         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18480         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18481         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18482         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18483         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18484
18485         cancel_lru_locks mdc
18486
18487         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18488                 error "migrate dir fails"
18489
18490         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18491 }
18492 run_test 230r "migrate with too many local locks"
18493
18494 test_231a()
18495 {
18496         # For simplicity this test assumes that max_pages_per_rpc
18497         # is the same across all OSCs
18498         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18499         local bulk_size=$((max_pages * PAGE_SIZE))
18500         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18501                                        head -n 1)
18502
18503         mkdir -p $DIR/$tdir
18504         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18505                 error "failed to set stripe with -S ${brw_size}M option"
18506
18507         # clear the OSC stats
18508         $LCTL set_param osc.*.stats=0 &>/dev/null
18509         stop_writeback
18510
18511         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18512         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18513                 oflag=direct &>/dev/null || error "dd failed"
18514
18515         sync; sleep 1; sync # just to be safe
18516         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18517         if [ x$nrpcs != "x1" ]; then
18518                 $LCTL get_param osc.*.stats
18519                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18520         fi
18521
18522         start_writeback
18523         # Drop the OSC cache, otherwise we will read from it
18524         cancel_lru_locks osc
18525
18526         # clear the OSC stats
18527         $LCTL set_param osc.*.stats=0 &>/dev/null
18528
18529         # Client reads $bulk_size.
18530         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18531                 iflag=direct &>/dev/null || error "dd failed"
18532
18533         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18534         if [ x$nrpcs != "x1" ]; then
18535                 $LCTL get_param osc.*.stats
18536                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18537         fi
18538 }
18539 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18540
18541 test_231b() {
18542         mkdir -p $DIR/$tdir
18543         local i
18544         for i in {0..1023}; do
18545                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18546                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18547                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18548         done
18549         sync
18550 }
18551 run_test 231b "must not assert on fully utilized OST request buffer"
18552
18553 test_232a() {
18554         mkdir -p $DIR/$tdir
18555         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18556
18557         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18558         do_facet ost1 $LCTL set_param fail_loc=0x31c
18559
18560         # ignore dd failure
18561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18562
18563         do_facet ost1 $LCTL set_param fail_loc=0
18564         umount_client $MOUNT || error "umount failed"
18565         mount_client $MOUNT || error "mount failed"
18566         stop ost1 || error "cannot stop ost1"
18567         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18568 }
18569 run_test 232a "failed lock should not block umount"
18570
18571 test_232b() {
18572         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18573                 skip "Need MDS version at least 2.10.58"
18574
18575         mkdir -p $DIR/$tdir
18576         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18577         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18578         sync
18579         cancel_lru_locks osc
18580
18581         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18582         do_facet ost1 $LCTL set_param fail_loc=0x31c
18583
18584         # ignore failure
18585         $LFS data_version $DIR/$tdir/$tfile || true
18586
18587         do_facet ost1 $LCTL set_param fail_loc=0
18588         umount_client $MOUNT || error "umount failed"
18589         mount_client $MOUNT || error "mount failed"
18590         stop ost1 || error "cannot stop ost1"
18591         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18592 }
18593 run_test 232b "failed data version lock should not block umount"
18594
18595 test_233a() {
18596         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18597                 skip "Need MDS version at least 2.3.64"
18598         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18599
18600         local fid=$($LFS path2fid $MOUNT)
18601
18602         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18603                 error "cannot access $MOUNT using its FID '$fid'"
18604 }
18605 run_test 233a "checking that OBF of the FS root succeeds"
18606
18607 test_233b() {
18608         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18609                 skip "Need MDS version at least 2.5.90"
18610         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18611
18612         local fid=$($LFS path2fid $MOUNT/.lustre)
18613
18614         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18615                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18616
18617         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18618         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18619                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18620 }
18621 run_test 233b "checking that OBF of the FS .lustre succeeds"
18622
18623 test_234() {
18624         local p="$TMP/sanityN-$TESTNAME.parameters"
18625         save_lustre_params client "llite.*.xattr_cache" > $p
18626         lctl set_param llite.*.xattr_cache 1 ||
18627                 skip_env "xattr cache is not supported"
18628
18629         mkdir -p $DIR/$tdir || error "mkdir failed"
18630         touch $DIR/$tdir/$tfile || error "touch failed"
18631         # OBD_FAIL_LLITE_XATTR_ENOMEM
18632         $LCTL set_param fail_loc=0x1405
18633         getfattr -n user.attr $DIR/$tdir/$tfile &&
18634                 error "getfattr should have failed with ENOMEM"
18635         $LCTL set_param fail_loc=0x0
18636         rm -rf $DIR/$tdir
18637
18638         restore_lustre_params < $p
18639         rm -f $p
18640 }
18641 run_test 234 "xattr cache should not crash on ENOMEM"
18642
18643 test_235() {
18644         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18645                 skip "Need MDS version at least 2.4.52"
18646
18647         flock_deadlock $DIR/$tfile
18648         local RC=$?
18649         case $RC in
18650                 0)
18651                 ;;
18652                 124) error "process hangs on a deadlock"
18653                 ;;
18654                 *) error "error executing flock_deadlock $DIR/$tfile"
18655                 ;;
18656         esac
18657 }
18658 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18659
18660 #LU-2935
18661 test_236() {
18662         check_swap_layouts_support
18663
18664         local ref1=/etc/passwd
18665         local ref2=/etc/group
18666         local file1=$DIR/$tdir/f1
18667         local file2=$DIR/$tdir/f2
18668
18669         test_mkdir -c1 $DIR/$tdir
18670         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18671         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18672         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18673         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18674         local fd=$(free_fd)
18675         local cmd="exec $fd<>$file2"
18676         eval $cmd
18677         rm $file2
18678         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18679                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18680         cmd="exec $fd>&-"
18681         eval $cmd
18682         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18683
18684         #cleanup
18685         rm -rf $DIR/$tdir
18686 }
18687 run_test 236 "Layout swap on open unlinked file"
18688
18689 # LU-4659 linkea consistency
18690 test_238() {
18691         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18692                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18693                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18694                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18695
18696         touch $DIR/$tfile
18697         ln $DIR/$tfile $DIR/$tfile.lnk
18698         touch $DIR/$tfile.new
18699         mv $DIR/$tfile.new $DIR/$tfile
18700         local fid1=$($LFS path2fid $DIR/$tfile)
18701         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18702         local path1=$($LFS fid2path $FSNAME "$fid1")
18703         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18704         local path2=$($LFS fid2path $FSNAME "$fid2")
18705         [ $tfile.lnk == $path2 ] ||
18706                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18707         rm -f $DIR/$tfile*
18708 }
18709 run_test 238 "Verify linkea consistency"
18710
18711 test_239A() { # was test_239
18712         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18713                 skip "Need MDS version at least 2.5.60"
18714
18715         local list=$(comma_list $(mdts_nodes))
18716
18717         mkdir -p $DIR/$tdir
18718         createmany -o $DIR/$tdir/f- 5000
18719         unlinkmany $DIR/$tdir/f- 5000
18720         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18721                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18722         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18723                         osp.*MDT*.sync_in_flight" | calc_sum)
18724         [ "$changes" -eq 0 ] || error "$changes not synced"
18725 }
18726 run_test 239A "osp_sync test"
18727
18728 test_239a() { #LU-5297
18729         remote_mds_nodsh && skip "remote MDS with nodsh"
18730
18731         touch $DIR/$tfile
18732         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18733         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18734         chgrp $RUNAS_GID $DIR/$tfile
18735         wait_delete_completed
18736 }
18737 run_test 239a "process invalid osp sync record correctly"
18738
18739 test_239b() { #LU-5297
18740         remote_mds_nodsh && skip "remote MDS with nodsh"
18741
18742         touch $DIR/$tfile1
18743         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18744         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18745         chgrp $RUNAS_GID $DIR/$tfile1
18746         wait_delete_completed
18747         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18748         touch $DIR/$tfile2
18749         chgrp $RUNAS_GID $DIR/$tfile2
18750         wait_delete_completed
18751 }
18752 run_test 239b "process osp sync record with ENOMEM error correctly"
18753
18754 test_240() {
18755         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18756         remote_mds_nodsh && skip "remote MDS with nodsh"
18757
18758         mkdir -p $DIR/$tdir
18759
18760         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18761                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18762         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18763                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18764
18765         umount_client $MOUNT || error "umount failed"
18766         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18767         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18768         mount_client $MOUNT || error "failed to mount client"
18769
18770         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18771         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18772 }
18773 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18774
18775 test_241_bio() {
18776         local count=$1
18777         local bsize=$2
18778
18779         for LOOP in $(seq $count); do
18780                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18781                 cancel_lru_locks $OSC || true
18782         done
18783 }
18784
18785 test_241_dio() {
18786         local count=$1
18787         local bsize=$2
18788
18789         for LOOP in $(seq $1); do
18790                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18791                         2>/dev/null
18792         done
18793 }
18794
18795 test_241a() { # was test_241
18796         local bsize=$PAGE_SIZE
18797
18798         (( bsize < 40960 )) && bsize=40960
18799         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18800         ls -la $DIR/$tfile
18801         cancel_lru_locks $OSC
18802         test_241_bio 1000 $bsize &
18803         PID=$!
18804         test_241_dio 1000 $bsize
18805         wait $PID
18806 }
18807 run_test 241a "bio vs dio"
18808
18809 test_241b() {
18810         local bsize=$PAGE_SIZE
18811
18812         (( bsize < 40960 )) && bsize=40960
18813         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18814         ls -la $DIR/$tfile
18815         test_241_dio 1000 $bsize &
18816         PID=$!
18817         test_241_dio 1000 $bsize
18818         wait $PID
18819 }
18820 run_test 241b "dio vs dio"
18821
18822 test_242() {
18823         remote_mds_nodsh && skip "remote MDS with nodsh"
18824
18825         mkdir -p $DIR/$tdir
18826         touch $DIR/$tdir/$tfile
18827
18828         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18829         do_facet mds1 lctl set_param fail_loc=0x105
18830         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18831
18832         do_facet mds1 lctl set_param fail_loc=0
18833         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18834 }
18835 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18836
18837 test_243()
18838 {
18839         test_mkdir $DIR/$tdir
18840         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18841 }
18842 run_test 243 "various group lock tests"
18843
18844 test_244a()
18845 {
18846         test_mkdir $DIR/$tdir
18847         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18848         sendfile_grouplock $DIR/$tdir/$tfile || \
18849                 error "sendfile+grouplock failed"
18850         rm -rf $DIR/$tdir
18851 }
18852 run_test 244a "sendfile with group lock tests"
18853
18854 test_244b()
18855 {
18856         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18857
18858         local threads=50
18859         local size=$((1024*1024))
18860
18861         test_mkdir $DIR/$tdir
18862         for i in $(seq 1 $threads); do
18863                 local file=$DIR/$tdir/file_$((i / 10))
18864                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18865                 local pids[$i]=$!
18866         done
18867         for i in $(seq 1 $threads); do
18868                 wait ${pids[$i]}
18869         done
18870 }
18871 run_test 244b "multi-threaded write with group lock"
18872
18873 test_245() {
18874         local flagname="multi_mod_rpcs"
18875         local connect_data_name="max_mod_rpcs"
18876         local out
18877
18878         # check if multiple modify RPCs flag is set
18879         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18880                 grep "connect_flags:")
18881         echo "$out"
18882
18883         echo "$out" | grep -qw $flagname
18884         if [ $? -ne 0 ]; then
18885                 echo "connect flag $flagname is not set"
18886                 return
18887         fi
18888
18889         # check if multiple modify RPCs data is set
18890         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18891         echo "$out"
18892
18893         echo "$out" | grep -qw $connect_data_name ||
18894                 error "import should have connect data $connect_data_name"
18895 }
18896 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18897
18898 cleanup_247() {
18899         local submount=$1
18900
18901         trap 0
18902         umount_client $submount
18903         rmdir $submount
18904 }
18905
18906 test_247a() {
18907         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18908                 grep -q subtree ||
18909                 skip_env "Fileset feature is not supported"
18910
18911         local submount=${MOUNT}_$tdir
18912
18913         mkdir $MOUNT/$tdir
18914         mkdir -p $submount || error "mkdir $submount failed"
18915         FILESET="$FILESET/$tdir" mount_client $submount ||
18916                 error "mount $submount failed"
18917         trap "cleanup_247 $submount" EXIT
18918         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18919         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18920                 error "read $MOUNT/$tdir/$tfile failed"
18921         cleanup_247 $submount
18922 }
18923 run_test 247a "mount subdir as fileset"
18924
18925 test_247b() {
18926         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18927                 skip_env "Fileset feature is not supported"
18928
18929         local submount=${MOUNT}_$tdir
18930
18931         rm -rf $MOUNT/$tdir
18932         mkdir -p $submount || error "mkdir $submount failed"
18933         SKIP_FILESET=1
18934         FILESET="$FILESET/$tdir" mount_client $submount &&
18935                 error "mount $submount should fail"
18936         rmdir $submount
18937 }
18938 run_test 247b "mount subdir that dose not exist"
18939
18940 test_247c() {
18941         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18942                 skip_env "Fileset feature is not supported"
18943
18944         local submount=${MOUNT}_$tdir
18945
18946         mkdir -p $MOUNT/$tdir/dir1
18947         mkdir -p $submount || error "mkdir $submount failed"
18948         trap "cleanup_247 $submount" EXIT
18949         FILESET="$FILESET/$tdir" mount_client $submount ||
18950                 error "mount $submount failed"
18951         local fid=$($LFS path2fid $MOUNT/)
18952         $LFS fid2path $submount $fid && error "fid2path should fail"
18953         cleanup_247 $submount
18954 }
18955 run_test 247c "running fid2path outside subdirectory root"
18956
18957 test_247d() {
18958         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18959                 skip "Fileset feature is not supported"
18960
18961         local submount=${MOUNT}_$tdir
18962
18963         mkdir -p $MOUNT/$tdir/dir1
18964         mkdir -p $submount || error "mkdir $submount failed"
18965         FILESET="$FILESET/$tdir" mount_client $submount ||
18966                 error "mount $submount failed"
18967         trap "cleanup_247 $submount" EXIT
18968
18969         local td=$submount/dir1
18970         local fid=$($LFS path2fid $td)
18971         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18972
18973         # check that we get the same pathname back
18974         local rootpath
18975         local found
18976         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18977                 echo "$rootpath $fid"
18978                 found=$($LFS fid2path $rootpath "$fid")
18979                 [ -n "found" ] || error "fid2path should succeed"
18980                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18981         done
18982         # check wrong root path format
18983         rootpath=$submount"_wrong"
18984         found=$($LFS fid2path $rootpath "$fid")
18985         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18986
18987         cleanup_247 $submount
18988 }
18989 run_test 247d "running fid2path inside subdirectory root"
18990
18991 # LU-8037
18992 test_247e() {
18993         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18994                 grep -q subtree ||
18995                 skip "Fileset feature is not supported"
18996
18997         local submount=${MOUNT}_$tdir
18998
18999         mkdir $MOUNT/$tdir
19000         mkdir -p $submount || error "mkdir $submount failed"
19001         FILESET="$FILESET/.." mount_client $submount &&
19002                 error "mount $submount should fail"
19003         rmdir $submount
19004 }
19005 run_test 247e "mount .. as fileset"
19006
19007 test_247f() {
19008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19009         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19010                 skip "Need at least version 2.13.52"
19011         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19012                 grep -q subtree ||
19013                 skip "Fileset feature is not supported"
19014
19015         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19016         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19017                 error "mkdir remote failed"
19018         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19019         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19020                 error "mkdir striped failed"
19021         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19022
19023         local submount=${MOUNT}_$tdir
19024
19025         mkdir -p $submount || error "mkdir $submount failed"
19026
19027         local dir
19028         local fileset=$FILESET
19029
19030         for dir in $tdir/remote $tdir/remote/subdir \
19031                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19032                 FILESET="$fileset/$dir" mount_client $submount ||
19033                         error "mount $dir failed"
19034                 umount_client $submount
19035         done
19036 }
19037 run_test 247f "mount striped or remote directory as fileset"
19038
19039 test_248a() {
19040         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19041         [ -z "$fast_read_sav" ] && skip "no fast read support"
19042
19043         # create a large file for fast read verification
19044         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19045
19046         # make sure the file is created correctly
19047         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19048                 { rm -f $DIR/$tfile; skip "file creation error"; }
19049
19050         echo "Test 1: verify that fast read is 4 times faster on cache read"
19051
19052         # small read with fast read enabled
19053         $LCTL set_param -n llite.*.fast_read=1
19054         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19055                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19056                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19057         # small read with fast read disabled
19058         $LCTL set_param -n llite.*.fast_read=0
19059         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19060                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19061                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19062
19063         # verify that fast read is 4 times faster for cache read
19064         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19065                 error_not_in_vm "fast read was not 4 times faster: " \
19066                            "$t_fast vs $t_slow"
19067
19068         echo "Test 2: verify the performance between big and small read"
19069         $LCTL set_param -n llite.*.fast_read=1
19070
19071         # 1k non-cache read
19072         cancel_lru_locks osc
19073         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19074                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19075                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19076
19077         # 1M non-cache read
19078         cancel_lru_locks osc
19079         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19080                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19081                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19082
19083         # verify that big IO is not 4 times faster than small IO
19084         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19085                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19086
19087         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19088         rm -f $DIR/$tfile
19089 }
19090 run_test 248a "fast read verification"
19091
19092 test_248b() {
19093         # Default short_io_bytes=16384, try both smaller and larger sizes.
19094         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19095         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19096         echo "bs=53248 count=113 normal buffered write"
19097         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19098                 error "dd of initial data file failed"
19099         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19100
19101         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19102         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19103                 error "dd with sync normal writes failed"
19104         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19105
19106         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19107         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19108                 error "dd with sync small writes failed"
19109         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19110
19111         cancel_lru_locks osc
19112
19113         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19114         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19115         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19116         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19117                 iflag=direct || error "dd with O_DIRECT small read failed"
19118         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19119         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19120                 error "compare $TMP/$tfile.1 failed"
19121
19122         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19123         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19124
19125         # just to see what the maximum tunable value is, and test parsing
19126         echo "test invalid parameter 2MB"
19127         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19128                 error "too-large short_io_bytes allowed"
19129         echo "test maximum parameter 512KB"
19130         # if we can set a larger short_io_bytes, run test regardless of version
19131         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19132                 # older clients may not allow setting it this large, that's OK
19133                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19134                         skip "Need at least client version 2.13.50"
19135                 error "medium short_io_bytes failed"
19136         fi
19137         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19138         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19139
19140         echo "test large parameter 64KB"
19141         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19142         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19143
19144         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19145         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19146                 error "dd with sync large writes failed"
19147         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19148
19149         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19150         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19151         num=$((113 * 4096 / PAGE_SIZE))
19152         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19153         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19154                 error "dd with O_DIRECT large writes failed"
19155         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19156                 error "compare $DIR/$tfile.3 failed"
19157
19158         cancel_lru_locks osc
19159
19160         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19161         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19162                 error "dd with O_DIRECT large read failed"
19163         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19164                 error "compare $TMP/$tfile.2 failed"
19165
19166         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19167         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19168                 error "dd with O_DIRECT large read failed"
19169         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19170                 error "compare $TMP/$tfile.3 failed"
19171 }
19172 run_test 248b "test short_io read and write for both small and large sizes"
19173
19174 test_249() { # LU-7890
19175         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19176                 skip "Need at least version 2.8.54"
19177
19178         rm -f $DIR/$tfile
19179         $LFS setstripe -c 1 $DIR/$tfile
19180         # Offset 2T == 4k * 512M
19181         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19182                 error "dd to 2T offset failed"
19183 }
19184 run_test 249 "Write above 2T file size"
19185
19186 test_250() {
19187         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19188          && skip "no 16TB file size limit on ZFS"
19189
19190         $LFS setstripe -c 1 $DIR/$tfile
19191         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19192         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19193         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19194         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19195                 conv=notrunc,fsync && error "append succeeded"
19196         return 0
19197 }
19198 run_test 250 "Write above 16T limit"
19199
19200 test_251() {
19201         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19202
19203         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19204         #Skip once - writing the first stripe will succeed
19205         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19206         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19207                 error "short write happened"
19208
19209         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19210         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19211                 error "short read happened"
19212
19213         rm -f $DIR/$tfile
19214 }
19215 run_test 251 "Handling short read and write correctly"
19216
19217 test_252() {
19218         remote_mds_nodsh && skip "remote MDS with nodsh"
19219         remote_ost_nodsh && skip "remote OST with nodsh"
19220         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19221                 skip_env "ldiskfs only test"
19222         fi
19223
19224         local tgt
19225         local dev
19226         local out
19227         local uuid
19228         local num
19229         local gen
19230
19231         # check lr_reader on OST0000
19232         tgt=ost1
19233         dev=$(facet_device $tgt)
19234         out=$(do_facet $tgt $LR_READER $dev)
19235         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19236         echo "$out"
19237         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19238         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19239                 error "Invalid uuid returned by $LR_READER on target $tgt"
19240         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19241
19242         # check lr_reader -c on MDT0000
19243         tgt=mds1
19244         dev=$(facet_device $tgt)
19245         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19246                 skip "$LR_READER does not support additional options"
19247         fi
19248         out=$(do_facet $tgt $LR_READER -c $dev)
19249         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19250         echo "$out"
19251         num=$(echo "$out" | grep -c "mdtlov")
19252         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19253                 error "Invalid number of mdtlov clients returned by $LR_READER"
19254         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19255
19256         # check lr_reader -cr on MDT0000
19257         out=$(do_facet $tgt $LR_READER -cr $dev)
19258         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19259         echo "$out"
19260         echo "$out" | grep -q "^reply_data:$" ||
19261                 error "$LR_READER should have returned 'reply_data' section"
19262         num=$(echo "$out" | grep -c "client_generation")
19263         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19264 }
19265 run_test 252 "check lr_reader tool"
19266
19267 test_253() {
19268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19269         remote_mds_nodsh && skip "remote MDS with nodsh"
19270         remote_mgs_nodsh && skip "remote MGS with nodsh"
19271
19272         local ostidx=0
19273         local rc=0
19274         local ost_name=$(ostname_from_index $ostidx)
19275
19276         # on the mdt's osc
19277         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19278         do_facet $SINGLEMDS $LCTL get_param -n \
19279                 osp.$mdtosc_proc1.reserved_mb_high ||
19280                 skip  "remote MDS does not support reserved_mb_high"
19281
19282         rm -rf $DIR/$tdir
19283         wait_mds_ost_sync
19284         wait_delete_completed
19285         mkdir $DIR/$tdir
19286
19287         pool_add $TESTNAME || error "Pool creation failed"
19288         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19289
19290         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19291                 error "Setstripe failed"
19292
19293         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19294
19295         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19296                     grep "watermarks")
19297         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19298
19299         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19300                         osp.$mdtosc_proc1.prealloc_status)
19301         echo "prealloc_status $oa_status"
19302
19303         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19304                 error "File creation should fail"
19305
19306         #object allocation was stopped, but we still able to append files
19307         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19308                 oflag=append || error "Append failed"
19309
19310         rm -f $DIR/$tdir/$tfile.0
19311
19312         # For this test, we want to delete the files we created to go out of
19313         # space but leave the watermark, so we remain nearly out of space
19314         ost_watermarks_enospc_delete_files $tfile $ostidx
19315
19316         wait_delete_completed
19317
19318         sleep_maxage
19319
19320         for i in $(seq 10 12); do
19321                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19322                         2>/dev/null || error "File creation failed after rm"
19323         done
19324
19325         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19326                         osp.$mdtosc_proc1.prealloc_status)
19327         echo "prealloc_status $oa_status"
19328
19329         if (( oa_status != 0 )); then
19330                 error "Object allocation still disable after rm"
19331         fi
19332 }
19333 run_test 253 "Check object allocation limit"
19334
19335 test_254() {
19336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19337         remote_mds_nodsh && skip "remote MDS with nodsh"
19338         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19339                 skip "MDS does not support changelog_size"
19340
19341         local cl_user
19342         local MDT0=$(facet_svc $SINGLEMDS)
19343
19344         changelog_register || error "changelog_register failed"
19345
19346         changelog_clear 0 || error "changelog_clear failed"
19347
19348         local size1=$(do_facet $SINGLEMDS \
19349                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19350         echo "Changelog size $size1"
19351
19352         rm -rf $DIR/$tdir
19353         $LFS mkdir -i 0 $DIR/$tdir
19354         # change something
19355         mkdir -p $DIR/$tdir/pics/2008/zachy
19356         touch $DIR/$tdir/pics/2008/zachy/timestamp
19357         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19358         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19359         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19360         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19361         rm $DIR/$tdir/pics/desktop.jpg
19362
19363         local size2=$(do_facet $SINGLEMDS \
19364                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19365         echo "Changelog size after work $size2"
19366
19367         (( $size2 > $size1 )) ||
19368                 error "new Changelog size=$size2 less than old size=$size1"
19369 }
19370 run_test 254 "Check changelog size"
19371
19372 ladvise_no_type()
19373 {
19374         local type=$1
19375         local file=$2
19376
19377         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19378                 awk -F: '{print $2}' | grep $type > /dev/null
19379         if [ $? -ne 0 ]; then
19380                 return 0
19381         fi
19382         return 1
19383 }
19384
19385 ladvise_no_ioctl()
19386 {
19387         local file=$1
19388
19389         lfs ladvise -a willread $file > /dev/null 2>&1
19390         if [ $? -eq 0 ]; then
19391                 return 1
19392         fi
19393
19394         lfs ladvise -a willread $file 2>&1 |
19395                 grep "Inappropriate ioctl for device" > /dev/null
19396         if [ $? -eq 0 ]; then
19397                 return 0
19398         fi
19399         return 1
19400 }
19401
19402 percent() {
19403         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19404 }
19405
19406 # run a random read IO workload
19407 # usage: random_read_iops <filename> <filesize> <iosize>
19408 random_read_iops() {
19409         local file=$1
19410         local fsize=$2
19411         local iosize=${3:-4096}
19412
19413         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19414                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19415 }
19416
19417 drop_file_oss_cache() {
19418         local file="$1"
19419         local nodes="$2"
19420
19421         $LFS ladvise -a dontneed $file 2>/dev/null ||
19422                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19423 }
19424
19425 ladvise_willread_performance()
19426 {
19427         local repeat=10
19428         local average_origin=0
19429         local average_cache=0
19430         local average_ladvise=0
19431
19432         for ((i = 1; i <= $repeat; i++)); do
19433                 echo "Iter $i/$repeat: reading without willread hint"
19434                 cancel_lru_locks osc
19435                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19436                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19437                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19438                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19439
19440                 cancel_lru_locks osc
19441                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19442                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19443                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19444
19445                 cancel_lru_locks osc
19446                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19447                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19448                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19449                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19450                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19451         done
19452         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19453         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19454         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19455
19456         speedup_cache=$(percent $average_cache $average_origin)
19457         speedup_ladvise=$(percent $average_ladvise $average_origin)
19458
19459         echo "Average uncached read: $average_origin"
19460         echo "Average speedup with OSS cached read: " \
19461                 "$average_cache = +$speedup_cache%"
19462         echo "Average speedup with ladvise willread: " \
19463                 "$average_ladvise = +$speedup_ladvise%"
19464
19465         local lowest_speedup=20
19466         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19467                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19468                         "got $average_cache%. Skipping ladvise willread check."
19469                 return 0
19470         fi
19471
19472         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19473         # it is still good to run until then to exercise 'ladvise willread'
19474         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19475                 [ "$ost1_FSTYPE" = "zfs" ] &&
19476                 echo "osd-zfs does not support dontneed or drop_caches" &&
19477                 return 0
19478
19479         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19480         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19481                 error_not_in_vm "Speedup with willread is less than " \
19482                         "$lowest_speedup%, got $average_ladvise%"
19483 }
19484
19485 test_255a() {
19486         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19487                 skip "lustre < 2.8.54 does not support ladvise "
19488         remote_ost_nodsh && skip "remote OST with nodsh"
19489
19490         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19491
19492         ladvise_no_type willread $DIR/$tfile &&
19493                 skip "willread ladvise is not supported"
19494
19495         ladvise_no_ioctl $DIR/$tfile &&
19496                 skip "ladvise ioctl is not supported"
19497
19498         local size_mb=100
19499         local size=$((size_mb * 1048576))
19500         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19501                 error "dd to $DIR/$tfile failed"
19502
19503         lfs ladvise -a willread $DIR/$tfile ||
19504                 error "Ladvise failed with no range argument"
19505
19506         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19507                 error "Ladvise failed with no -l or -e argument"
19508
19509         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19510                 error "Ladvise failed with only -e argument"
19511
19512         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19513                 error "Ladvise failed with only -l argument"
19514
19515         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19516                 error "End offset should not be smaller than start offset"
19517
19518         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19519                 error "End offset should not be equal to start offset"
19520
19521         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19522                 error "Ladvise failed with overflowing -s argument"
19523
19524         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19525                 error "Ladvise failed with overflowing -e argument"
19526
19527         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19528                 error "Ladvise failed with overflowing -l argument"
19529
19530         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19531                 error "Ladvise succeeded with conflicting -l and -e arguments"
19532
19533         echo "Synchronous ladvise should wait"
19534         local delay=4
19535 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19536         do_nodes $(comma_list $(osts_nodes)) \
19537                 $LCTL set_param fail_val=$delay fail_loc=0x237
19538
19539         local start_ts=$SECONDS
19540         lfs ladvise -a willread $DIR/$tfile ||
19541                 error "Ladvise failed with no range argument"
19542         local end_ts=$SECONDS
19543         local inteval_ts=$((end_ts - start_ts))
19544
19545         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19546                 error "Synchronous advice didn't wait reply"
19547         fi
19548
19549         echo "Asynchronous ladvise shouldn't wait"
19550         local start_ts=$SECONDS
19551         lfs ladvise -a willread -b $DIR/$tfile ||
19552                 error "Ladvise failed with no range argument"
19553         local end_ts=$SECONDS
19554         local inteval_ts=$((end_ts - start_ts))
19555
19556         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19557                 error "Asynchronous advice blocked"
19558         fi
19559
19560         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19561         ladvise_willread_performance
19562 }
19563 run_test 255a "check 'lfs ladvise -a willread'"
19564
19565 facet_meminfo() {
19566         local facet=$1
19567         local info=$2
19568
19569         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19570 }
19571
19572 test_255b() {
19573         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19574                 skip "lustre < 2.8.54 does not support ladvise "
19575         remote_ost_nodsh && skip "remote OST with nodsh"
19576
19577         lfs setstripe -c 1 -i 0 $DIR/$tfile
19578
19579         ladvise_no_type dontneed $DIR/$tfile &&
19580                 skip "dontneed ladvise is not supported"
19581
19582         ladvise_no_ioctl $DIR/$tfile &&
19583                 skip "ladvise ioctl is not supported"
19584
19585         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19586                 [ "$ost1_FSTYPE" = "zfs" ] &&
19587                 skip "zfs-osd does not support 'ladvise dontneed'"
19588
19589         local size_mb=100
19590         local size=$((size_mb * 1048576))
19591         # In order to prevent disturbance of other processes, only check 3/4
19592         # of the memory usage
19593         local kibibytes=$((size_mb * 1024 * 3 / 4))
19594
19595         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19596                 error "dd to $DIR/$tfile failed"
19597
19598         #force write to complete before dropping OST cache & checking memory
19599         sync
19600
19601         local total=$(facet_meminfo ost1 MemTotal)
19602         echo "Total memory: $total KiB"
19603
19604         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19605         local before_read=$(facet_meminfo ost1 Cached)
19606         echo "Cache used before read: $before_read KiB"
19607
19608         lfs ladvise -a willread $DIR/$tfile ||
19609                 error "Ladvise willread failed"
19610         local after_read=$(facet_meminfo ost1 Cached)
19611         echo "Cache used after read: $after_read KiB"
19612
19613         lfs ladvise -a dontneed $DIR/$tfile ||
19614                 error "Ladvise dontneed again failed"
19615         local no_read=$(facet_meminfo ost1 Cached)
19616         echo "Cache used after dontneed ladvise: $no_read KiB"
19617
19618         if [ $total -lt $((before_read + kibibytes)) ]; then
19619                 echo "Memory is too small, abort checking"
19620                 return 0
19621         fi
19622
19623         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19624                 error "Ladvise willread should use more memory" \
19625                         "than $kibibytes KiB"
19626         fi
19627
19628         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19629                 error "Ladvise dontneed should release more memory" \
19630                         "than $kibibytes KiB"
19631         fi
19632 }
19633 run_test 255b "check 'lfs ladvise -a dontneed'"
19634
19635 test_255c() {
19636         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19637                 skip "lustre < 2.10.50 does not support lockahead"
19638
19639         local count
19640         local new_count
19641         local difference
19642         local i
19643         local rc
19644
19645         test_mkdir -p $DIR/$tdir
19646         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19647
19648         #test 10 returns only success/failure
19649         i=10
19650         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19651         rc=$?
19652         if [ $rc -eq 255 ]; then
19653                 error "Ladvise test${i} failed, ${rc}"
19654         fi
19655
19656         #test 11 counts lock enqueue requests, all others count new locks
19657         i=11
19658         count=$(do_facet ost1 \
19659                 $LCTL get_param -n ost.OSS.ost.stats)
19660         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19661
19662         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19663         rc=$?
19664         if [ $rc -eq 255 ]; then
19665                 error "Ladvise test${i} failed, ${rc}"
19666         fi
19667
19668         new_count=$(do_facet ost1 \
19669                 $LCTL get_param -n ost.OSS.ost.stats)
19670         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19671                    awk '{ print $2 }')
19672
19673         difference="$((new_count - count))"
19674         if [ $difference -ne $rc ]; then
19675                 error "Ladvise test${i}, bad enqueue count, returned " \
19676                       "${rc}, actual ${difference}"
19677         fi
19678
19679         for i in $(seq 12 21); do
19680                 # If we do not do this, we run the risk of having too many
19681                 # locks and starting lock cancellation while we are checking
19682                 # lock counts.
19683                 cancel_lru_locks osc
19684
19685                 count=$($LCTL get_param -n \
19686                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19687
19688                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19689                 rc=$?
19690                 if [ $rc -eq 255 ]; then
19691                         error "Ladvise test ${i} failed, ${rc}"
19692                 fi
19693
19694                 new_count=$($LCTL get_param -n \
19695                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19696                 difference="$((new_count - count))"
19697
19698                 # Test 15 output is divided by 100 to map down to valid return
19699                 if [ $i -eq 15 ]; then
19700                         rc="$((rc * 100))"
19701                 fi
19702
19703                 if [ $difference -ne $rc ]; then
19704                         error "Ladvise test ${i}, bad lock count, returned " \
19705                               "${rc}, actual ${difference}"
19706                 fi
19707         done
19708
19709         #test 22 returns only success/failure
19710         i=22
19711         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19712         rc=$?
19713         if [ $rc -eq 255 ]; then
19714                 error "Ladvise test${i} failed, ${rc}"
19715         fi
19716 }
19717 run_test 255c "suite of ladvise lockahead tests"
19718
19719 test_256() {
19720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19721         remote_mds_nodsh && skip "remote MDS with nodsh"
19722         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19723         changelog_users $SINGLEMDS | grep "^cl" &&
19724                 skip "active changelog user"
19725
19726         local cl_user
19727         local cat_sl
19728         local mdt_dev
19729
19730         mdt_dev=$(mdsdevname 1)
19731         echo $mdt_dev
19732
19733         changelog_register || error "changelog_register failed"
19734
19735         rm -rf $DIR/$tdir
19736         mkdir -p $DIR/$tdir
19737
19738         changelog_clear 0 || error "changelog_clear failed"
19739
19740         # change something
19741         touch $DIR/$tdir/{1..10}
19742
19743         # stop the MDT
19744         stop $SINGLEMDS || error "Fail to stop MDT"
19745
19746         # remount the MDT
19747
19748         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19749
19750         #after mount new plainllog is used
19751         touch $DIR/$tdir/{11..19}
19752         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19753         stack_trap "rm -f $tmpfile"
19754         cat_sl=$(do_facet $SINGLEMDS "sync; \
19755                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19756                  llog_reader $tmpfile | grep -c type=1064553b")
19757         do_facet $SINGLEMDS llog_reader $tmpfile
19758
19759         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19760
19761         changelog_clear 0 || error "changelog_clear failed"
19762
19763         cat_sl=$(do_facet $SINGLEMDS "sync; \
19764                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19765                  llog_reader $tmpfile | grep -c type=1064553b")
19766
19767         if (( cat_sl == 2 )); then
19768                 error "Empty plain llog was not deleted from changelog catalog"
19769         elif (( cat_sl != 1 )); then
19770                 error "Active plain llog shouldn't be deleted from catalog"
19771         fi
19772 }
19773 run_test 256 "Check llog delete for empty and not full state"
19774
19775 test_257() {
19776         remote_mds_nodsh && skip "remote MDS with nodsh"
19777         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19778                 skip "Need MDS version at least 2.8.55"
19779
19780         test_mkdir $DIR/$tdir
19781
19782         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19783                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19784         stat $DIR/$tdir
19785
19786 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19787         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19788         local facet=mds$((mdtidx + 1))
19789         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19790         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19791
19792         stop $facet || error "stop MDS failed"
19793         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19794                 error "start MDS fail"
19795         wait_recovery_complete $facet
19796 }
19797 run_test 257 "xattr locks are not lost"
19798
19799 # Verify we take the i_mutex when security requires it
19800 test_258a() {
19801 #define OBD_FAIL_IMUTEX_SEC 0x141c
19802         $LCTL set_param fail_loc=0x141c
19803         touch $DIR/$tfile
19804         chmod u+s $DIR/$tfile
19805         chmod a+rwx $DIR/$tfile
19806         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19807         RC=$?
19808         if [ $RC -ne 0 ]; then
19809                 error "error, failed to take i_mutex, rc=$?"
19810         fi
19811         rm -f $DIR/$tfile
19812 }
19813 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19814
19815 # Verify we do NOT take the i_mutex in the normal case
19816 test_258b() {
19817 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19818         $LCTL set_param fail_loc=0x141d
19819         touch $DIR/$tfile
19820         chmod a+rwx $DIR
19821         chmod a+rw $DIR/$tfile
19822         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19823         RC=$?
19824         if [ $RC -ne 0 ]; then
19825                 error "error, took i_mutex unnecessarily, rc=$?"
19826         fi
19827         rm -f $DIR/$tfile
19828
19829 }
19830 run_test 258b "verify i_mutex security behavior"
19831
19832 test_259() {
19833         local file=$DIR/$tfile
19834         local before
19835         local after
19836
19837         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19838
19839         stack_trap "rm -f $file" EXIT
19840
19841         wait_delete_completed
19842         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19843         echo "before: $before"
19844
19845         $LFS setstripe -i 0 -c 1 $file
19846         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19847         sync_all_data
19848         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19849         echo "after write: $after"
19850
19851 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19852         do_facet ost1 $LCTL set_param fail_loc=0x2301
19853         $TRUNCATE $file 0
19854         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19855         echo "after truncate: $after"
19856
19857         stop ost1
19858         do_facet ost1 $LCTL set_param fail_loc=0
19859         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19860         sleep 2
19861         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19862         echo "after restart: $after"
19863         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19864                 error "missing truncate?"
19865
19866         return 0
19867 }
19868 run_test 259 "crash at delayed truncate"
19869
19870 test_260() {
19871 #define OBD_FAIL_MDC_CLOSE               0x806
19872         $LCTL set_param fail_loc=0x80000806
19873         touch $DIR/$tfile
19874
19875 }
19876 run_test 260 "Check mdc_close fail"
19877
19878 ### Data-on-MDT sanity tests ###
19879 test_270a() {
19880         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19881                 skip "Need MDS version at least 2.10.55 for DoM"
19882
19883         # create DoM file
19884         local dom=$DIR/$tdir/dom_file
19885         local tmp=$DIR/$tdir/tmp_file
19886
19887         mkdir -p $DIR/$tdir
19888
19889         # basic checks for DoM component creation
19890         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19891                 error "Can set MDT layout to non-first entry"
19892
19893         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19894                 error "Can define multiple entries as MDT layout"
19895
19896         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19897
19898         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19899         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19900         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19901
19902         local mdtidx=$($LFS getstripe -m $dom)
19903         local mdtname=MDT$(printf %04x $mdtidx)
19904         local facet=mds$((mdtidx + 1))
19905         local space_check=1
19906
19907         # Skip free space checks with ZFS
19908         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19909
19910         # write
19911         sync
19912         local size_tmp=$((65536 * 3))
19913         local mdtfree1=$(do_facet $facet \
19914                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19915
19916         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19917         # check also direct IO along write
19918         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19919         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19920         sync
19921         cmp $tmp $dom || error "file data is different"
19922         [ $(stat -c%s $dom) == $size_tmp ] ||
19923                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19924         if [ $space_check == 1 ]; then
19925                 local mdtfree2=$(do_facet $facet \
19926                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19927
19928                 # increase in usage from by $size_tmp
19929                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19930                         error "MDT free space wrong after write: " \
19931                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19932         fi
19933
19934         # truncate
19935         local size_dom=10000
19936
19937         $TRUNCATE $dom $size_dom
19938         [ $(stat -c%s $dom) == $size_dom ] ||
19939                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19940         if [ $space_check == 1 ]; then
19941                 mdtfree1=$(do_facet $facet \
19942                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19943                 # decrease in usage from $size_tmp to new $size_dom
19944                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19945                   $(((size_tmp - size_dom) / 1024)) ] ||
19946                         error "MDT free space is wrong after truncate: " \
19947                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19948         fi
19949
19950         # append
19951         cat $tmp >> $dom
19952         sync
19953         size_dom=$((size_dom + size_tmp))
19954         [ $(stat -c%s $dom) == $size_dom ] ||
19955                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19956         if [ $space_check == 1 ]; then
19957                 mdtfree2=$(do_facet $facet \
19958                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19959                 # increase in usage by $size_tmp from previous
19960                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19961                         error "MDT free space is wrong after append: " \
19962                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19963         fi
19964
19965         # delete
19966         rm $dom
19967         if [ $space_check == 1 ]; then
19968                 mdtfree1=$(do_facet $facet \
19969                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19970                 # decrease in usage by $size_dom from previous
19971                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19972                         error "MDT free space is wrong after removal: " \
19973                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19974         fi
19975
19976         # combined striping
19977         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19978                 error "Can't create DoM + OST striping"
19979
19980         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19981         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19982         # check also direct IO along write
19983         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19984         sync
19985         cmp $tmp $dom || error "file data is different"
19986         [ $(stat -c%s $dom) == $size_tmp ] ||
19987                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19988         rm $dom $tmp
19989
19990         return 0
19991 }
19992 run_test 270a "DoM: basic functionality tests"
19993
19994 test_270b() {
19995         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19996                 skip "Need MDS version at least 2.10.55"
19997
19998         local dom=$DIR/$tdir/dom_file
19999         local max_size=1048576
20000
20001         mkdir -p $DIR/$tdir
20002         $LFS setstripe -E $max_size -L mdt $dom
20003
20004         # truncate over the limit
20005         $TRUNCATE $dom $(($max_size + 1)) &&
20006                 error "successful truncate over the maximum size"
20007         # write over the limit
20008         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20009                 error "successful write over the maximum size"
20010         # append over the limit
20011         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20012         echo "12345" >> $dom && error "successful append over the maximum size"
20013         rm $dom
20014
20015         return 0
20016 }
20017 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20018
20019 test_270c() {
20020         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20021                 skip "Need MDS version at least 2.10.55"
20022
20023         mkdir -p $DIR/$tdir
20024         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20025
20026         # check files inherit DoM EA
20027         touch $DIR/$tdir/first
20028         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20029                 error "bad pattern"
20030         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20031                 error "bad stripe count"
20032         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20033                 error "bad stripe size"
20034
20035         # check directory inherits DoM EA and uses it as default
20036         mkdir $DIR/$tdir/subdir
20037         touch $DIR/$tdir/subdir/second
20038         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20039                 error "bad pattern in sub-directory"
20040         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20041                 error "bad stripe count in sub-directory"
20042         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20043                 error "bad stripe size in sub-directory"
20044         return 0
20045 }
20046 run_test 270c "DoM: DoM EA inheritance tests"
20047
20048 test_270d() {
20049         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20050                 skip "Need MDS version at least 2.10.55"
20051
20052         mkdir -p $DIR/$tdir
20053         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20054
20055         # inherit default DoM striping
20056         mkdir $DIR/$tdir/subdir
20057         touch $DIR/$tdir/subdir/f1
20058
20059         # change default directory striping
20060         $LFS setstripe -c 1 $DIR/$tdir/subdir
20061         touch $DIR/$tdir/subdir/f2
20062         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20063                 error "wrong default striping in file 2"
20064         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20065                 error "bad pattern in file 2"
20066         return 0
20067 }
20068 run_test 270d "DoM: change striping from DoM to RAID0"
20069
20070 test_270e() {
20071         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20072                 skip "Need MDS version at least 2.10.55"
20073
20074         mkdir -p $DIR/$tdir/dom
20075         mkdir -p $DIR/$tdir/norm
20076         DOMFILES=20
20077         NORMFILES=10
20078         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20079         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20080
20081         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20082         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20083
20084         # find DoM files by layout
20085         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20086         [ $NUM -eq  $DOMFILES ] ||
20087                 error "lfs find -L: found $NUM, expected $DOMFILES"
20088         echo "Test 1: lfs find 20 DOM files by layout: OK"
20089
20090         # there should be 1 dir with default DOM striping
20091         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20092         [ $NUM -eq  1 ] ||
20093                 error "lfs find -L: found $NUM, expected 1 dir"
20094         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20095
20096         # find DoM files by stripe size
20097         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20098         [ $NUM -eq  $DOMFILES ] ||
20099                 error "lfs find -S: found $NUM, expected $DOMFILES"
20100         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20101
20102         # find files by stripe offset except DoM files
20103         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20104         [ $NUM -eq  $NORMFILES ] ||
20105                 error "lfs find -i: found $NUM, expected $NORMFILES"
20106         echo "Test 5: lfs find no DOM files by stripe index: OK"
20107         return 0
20108 }
20109 run_test 270e "DoM: lfs find with DoM files test"
20110
20111 test_270f() {
20112         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20113                 skip "Need MDS version at least 2.10.55"
20114
20115         local mdtname=${FSNAME}-MDT0000-mdtlov
20116         local dom=$DIR/$tdir/dom_file
20117         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20118                                                 lod.$mdtname.dom_stripesize)
20119         local dom_limit=131072
20120
20121         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20122         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20123                                                 lod.$mdtname.dom_stripesize)
20124         [ ${dom_limit} -eq ${dom_current} ] ||
20125                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20126
20127         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20128         $LFS setstripe -d $DIR/$tdir
20129         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20130                 error "Can't set directory default striping"
20131
20132         # exceed maximum stripe size
20133         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20134                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20135         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20136                 error "Able to create DoM component size more than LOD limit"
20137
20138         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20139         dom_current=$(do_facet mds1 $LCTL get_param -n \
20140                                                 lod.$mdtname.dom_stripesize)
20141         [ 0 -eq ${dom_current} ] ||
20142                 error "Can't set zero DoM stripe limit"
20143         rm $dom
20144
20145         # attempt to create DoM file on server with disabled DoM should
20146         # remove DoM entry from layout and be succeed
20147         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20148                 error "Can't create DoM file (DoM is disabled)"
20149         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20150                 error "File has DoM component while DoM is disabled"
20151         rm $dom
20152
20153         # attempt to create DoM file with only DoM stripe should return error
20154         $LFS setstripe -E $dom_limit -L mdt $dom &&
20155                 error "Able to create DoM-only file while DoM is disabled"
20156
20157         # too low values to be aligned with smallest stripe size 64K
20158         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20159         dom_current=$(do_facet mds1 $LCTL get_param -n \
20160                                                 lod.$mdtname.dom_stripesize)
20161         [ 30000 -eq ${dom_current} ] &&
20162                 error "Can set too small DoM stripe limit"
20163
20164         # 64K is a minimal stripe size in Lustre, expect limit of that size
20165         [ 65536 -eq ${dom_current} ] ||
20166                 error "Limit is not set to 64K but ${dom_current}"
20167
20168         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20169         dom_current=$(do_facet mds1 $LCTL get_param -n \
20170                                                 lod.$mdtname.dom_stripesize)
20171         echo $dom_current
20172         [ 2147483648 -eq ${dom_current} ] &&
20173                 error "Can set too large DoM stripe limit"
20174
20175         do_facet mds1 $LCTL set_param -n \
20176                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20177         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20178                 error "Can't create DoM component size after limit change"
20179         do_facet mds1 $LCTL set_param -n \
20180                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20181         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20182                 error "Can't create DoM file after limit decrease"
20183         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20184                 error "Can create big DoM component after limit decrease"
20185         touch ${dom}_def ||
20186                 error "Can't create file with old default layout"
20187
20188         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20189         return 0
20190 }
20191 run_test 270f "DoM: maximum DoM stripe size checks"
20192
20193 test_270g() {
20194         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20195                 skip "Need MDS version at least 2.13.52"
20196         local dom=$DIR/$tdir/$tfile
20197
20198         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20199         local lodname=${FSNAME}-MDT0000-mdtlov
20200
20201         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20202         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20203         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20204         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20205
20206         local dom_limit=1024
20207         local dom_threshold="50%"
20208
20209         $LFS setstripe -d $DIR/$tdir
20210         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20211                 error "Can't set directory default striping"
20212
20213         do_facet mds1 $LCTL set_param -n \
20214                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20215         # set 0 threshold and create DOM file to change tunable stripesize
20216         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20217         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20218                 error "Failed to create $dom file"
20219         # now tunable dom_cur_stripesize should reach maximum
20220         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20221                                         lod.${lodname}.dom_stripesize_cur_kb)
20222         [[ $dom_current == $dom_limit ]] ||
20223                 error "Current DOM stripesize is not maximum"
20224         rm $dom
20225
20226         # set threshold for further tests
20227         do_facet mds1 $LCTL set_param -n \
20228                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20229         echo "DOM threshold is $dom_threshold free space"
20230         local dom_def
20231         local dom_set
20232         # Spoof bfree to exceed threshold
20233         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20234         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20235         for spfree in 40 20 0 15 30 55; do
20236                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20237                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20238                         error "Failed to create $dom file"
20239                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20240                                         lod.${lodname}.dom_stripesize_cur_kb)
20241                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20242                 [[ $dom_def != $dom_current ]] ||
20243                         error "Default stripe size was not changed"
20244                 if [[ $spfree > 0 ]] ; then
20245                         dom_set=$($LFS getstripe -S $dom)
20246                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20247                                 error "DOM component size is still old"
20248                 else
20249                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20250                                 error "DoM component is set with no free space"
20251                 fi
20252                 rm $dom
20253                 dom_current=$dom_def
20254         done
20255 }
20256 run_test 270g "DoM: default DoM stripe size depends on free space"
20257
20258 test_270h() {
20259         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20260                 skip "Need MDS version at least 2.13.53"
20261
20262         local mdtname=${FSNAME}-MDT0000-mdtlov
20263         local dom=$DIR/$tdir/$tfile
20264         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20265
20266         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20267         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20268
20269         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20270         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20271                 error "can't create OST file"
20272         # mirrored file with DOM entry in the second mirror
20273         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20274                 error "can't create mirror with DoM component"
20275
20276         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20277
20278         # DOM component in the middle and has other enries in the same mirror,
20279         # should succeed but lost DoM component
20280         $LFS setstripe --copy=${dom}_1 $dom ||
20281                 error "Can't create file from OST|DOM mirror layout"
20282         # check new file has no DoM layout after all
20283         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20284                 error "File has DoM component while DoM is disabled"
20285 }
20286 run_test 270h "DoM: DoM stripe removal when disabled on server"
20287
20288 test_271a() {
20289         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20290                 skip "Need MDS version at least 2.10.55"
20291
20292         local dom=$DIR/$tdir/dom
20293
20294         mkdir -p $DIR/$tdir
20295
20296         $LFS setstripe -E 1024K -L mdt $dom
20297
20298         lctl set_param -n mdc.*.stats=clear
20299         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20300         cat $dom > /dev/null
20301         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20302         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20303         ls $dom
20304         rm -f $dom
20305 }
20306 run_test 271a "DoM: data is cached for read after write"
20307
20308 test_271b() {
20309         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20310                 skip "Need MDS version at least 2.10.55"
20311
20312         local dom=$DIR/$tdir/dom
20313
20314         mkdir -p $DIR/$tdir
20315
20316         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20317
20318         lctl set_param -n mdc.*.stats=clear
20319         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20320         cancel_lru_locks mdc
20321         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20322         # second stat to check size is cached on client
20323         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20324         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20325         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20326         rm -f $dom
20327 }
20328 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20329
20330 test_271ba() {
20331         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20332                 skip "Need MDS version at least 2.10.55"
20333
20334         local dom=$DIR/$tdir/dom
20335
20336         mkdir -p $DIR/$tdir
20337
20338         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20339
20340         lctl set_param -n mdc.*.stats=clear
20341         lctl set_param -n osc.*.stats=clear
20342         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20343         cancel_lru_locks mdc
20344         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20345         # second stat to check size is cached on client
20346         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20347         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20348         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20349         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20350         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20351         rm -f $dom
20352 }
20353 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20354
20355
20356 get_mdc_stats() {
20357         local mdtidx=$1
20358         local param=$2
20359         local mdt=MDT$(printf %04x $mdtidx)
20360
20361         if [ -z $param ]; then
20362                 lctl get_param -n mdc.*$mdt*.stats
20363         else
20364                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20365         fi
20366 }
20367
20368 test_271c() {
20369         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20370                 skip "Need MDS version at least 2.10.55"
20371
20372         local dom=$DIR/$tdir/dom
20373
20374         mkdir -p $DIR/$tdir
20375
20376         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20377
20378         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20379         local facet=mds$((mdtidx + 1))
20380
20381         cancel_lru_locks mdc
20382         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20383         createmany -o $dom 1000
20384         lctl set_param -n mdc.*.stats=clear
20385         smalliomany -w $dom 1000 200
20386         get_mdc_stats $mdtidx
20387         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20388         # Each file has 1 open, 1 IO enqueues, total 2000
20389         # but now we have also +1 getxattr for security.capability, total 3000
20390         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20391         unlinkmany $dom 1000
20392
20393         cancel_lru_locks mdc
20394         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20395         createmany -o $dom 1000
20396         lctl set_param -n mdc.*.stats=clear
20397         smalliomany -w $dom 1000 200
20398         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20399         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20400         # for OPEN and IO lock.
20401         [ $((enq - enq_2)) -ge 1000 ] ||
20402                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20403         unlinkmany $dom 1000
20404         return 0
20405 }
20406 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20407
20408 cleanup_271def_tests() {
20409         trap 0
20410         rm -f $1
20411 }
20412
20413 test_271d() {
20414         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20415                 skip "Need MDS version at least 2.10.57"
20416
20417         local dom=$DIR/$tdir/dom
20418         local tmp=$TMP/$tfile
20419         trap "cleanup_271def_tests $tmp" EXIT
20420
20421         mkdir -p $DIR/$tdir
20422
20423         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20424
20425         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20426
20427         cancel_lru_locks mdc
20428         dd if=/dev/urandom of=$tmp bs=1000 count=1
20429         dd if=$tmp of=$dom bs=1000 count=1
20430         cancel_lru_locks mdc
20431
20432         cat /etc/hosts >> $tmp
20433         lctl set_param -n mdc.*.stats=clear
20434
20435         # append data to the same file it should update local page
20436         echo "Append to the same page"
20437         cat /etc/hosts >> $dom
20438         local num=$(get_mdc_stats $mdtidx ost_read)
20439         local ra=$(get_mdc_stats $mdtidx req_active)
20440         local rw=$(get_mdc_stats $mdtidx req_waittime)
20441
20442         [ -z $num ] || error "$num READ RPC occured"
20443         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20444         echo "... DONE"
20445
20446         # compare content
20447         cmp $tmp $dom || error "file miscompare"
20448
20449         cancel_lru_locks mdc
20450         lctl set_param -n mdc.*.stats=clear
20451
20452         echo "Open and read file"
20453         cat $dom > /dev/null
20454         local num=$(get_mdc_stats $mdtidx ost_read)
20455         local ra=$(get_mdc_stats $mdtidx req_active)
20456         local rw=$(get_mdc_stats $mdtidx req_waittime)
20457
20458         [ -z $num ] || error "$num READ RPC occured"
20459         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20460         echo "... DONE"
20461
20462         # compare content
20463         cmp $tmp $dom || error "file miscompare"
20464
20465         return 0
20466 }
20467 run_test 271d "DoM: read on open (1K file in reply buffer)"
20468
20469 test_271f() {
20470         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20471                 skip "Need MDS version at least 2.10.57"
20472
20473         local dom=$DIR/$tdir/dom
20474         local tmp=$TMP/$tfile
20475         trap "cleanup_271def_tests $tmp" EXIT
20476
20477         mkdir -p $DIR/$tdir
20478
20479         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20480
20481         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20482
20483         cancel_lru_locks mdc
20484         dd if=/dev/urandom of=$tmp bs=265000 count=1
20485         dd if=$tmp of=$dom bs=265000 count=1
20486         cancel_lru_locks mdc
20487         cat /etc/hosts >> $tmp
20488         lctl set_param -n mdc.*.stats=clear
20489
20490         echo "Append to the same page"
20491         cat /etc/hosts >> $dom
20492         local num=$(get_mdc_stats $mdtidx ost_read)
20493         local ra=$(get_mdc_stats $mdtidx req_active)
20494         local rw=$(get_mdc_stats $mdtidx req_waittime)
20495
20496         [ -z $num ] || error "$num READ RPC occured"
20497         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20498         echo "... DONE"
20499
20500         # compare content
20501         cmp $tmp $dom || error "file miscompare"
20502
20503         cancel_lru_locks mdc
20504         lctl set_param -n mdc.*.stats=clear
20505
20506         echo "Open and read file"
20507         cat $dom > /dev/null
20508         local num=$(get_mdc_stats $mdtidx ost_read)
20509         local ra=$(get_mdc_stats $mdtidx req_active)
20510         local rw=$(get_mdc_stats $mdtidx req_waittime)
20511
20512         [ -z $num ] && num=0
20513         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20514         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20515         echo "... DONE"
20516
20517         # compare content
20518         cmp $tmp $dom || error "file miscompare"
20519
20520         return 0
20521 }
20522 run_test 271f "DoM: read on open (200K file and read tail)"
20523
20524 test_271g() {
20525         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20526                 skip "Skipping due to old client or server version"
20527
20528         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20529         # to get layout
20530         $CHECKSTAT -t file $DIR1/$tfile
20531
20532         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20533         MULTIOP_PID=$!
20534         sleep 1
20535         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20536         $LCTL set_param fail_loc=0x80000314
20537         rm $DIR1/$tfile || error "Unlink fails"
20538         RC=$?
20539         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20540         [ $RC -eq 0 ] || error "Failed write to stale object"
20541 }
20542 run_test 271g "Discard DoM data vs client flush race"
20543
20544 test_272a() {
20545         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20546                 skip "Need MDS version at least 2.11.50"
20547
20548         local dom=$DIR/$tdir/dom
20549         mkdir -p $DIR/$tdir
20550
20551         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20552         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20553                 error "failed to write data into $dom"
20554         local old_md5=$(md5sum $dom)
20555
20556         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20557                 error "failed to migrate to the same DoM component"
20558
20559         local new_md5=$(md5sum $dom)
20560
20561         [ "$old_md5" == "$new_md5" ] ||
20562                 error "md5sum differ: $old_md5, $new_md5"
20563
20564         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20565                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20566 }
20567 run_test 272a "DoM migration: new layout with the same DOM component"
20568
20569 test_272b() {
20570         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20571                 skip "Need MDS version at least 2.11.50"
20572
20573         local dom=$DIR/$tdir/dom
20574         mkdir -p $DIR/$tdir
20575         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20576
20577         local mdtidx=$($LFS getstripe -m $dom)
20578         local mdtname=MDT$(printf %04x $mdtidx)
20579         local facet=mds$((mdtidx + 1))
20580
20581         local mdtfree1=$(do_facet $facet \
20582                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20583         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20584                 error "failed to write data into $dom"
20585         local old_md5=$(md5sum $dom)
20586         cancel_lru_locks mdc
20587         local mdtfree1=$(do_facet $facet \
20588                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20589
20590         $LFS migrate -c2 $dom ||
20591                 error "failed to migrate to the new composite layout"
20592         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20593                 error "MDT stripe was not removed"
20594
20595         cancel_lru_locks mdc
20596         local new_md5=$(md5sum $dom)
20597         [ "$old_md5" == "$new_md5" ] ||
20598                 error "$old_md5 != $new_md5"
20599
20600         # Skip free space checks with ZFS
20601         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20602                 local mdtfree2=$(do_facet $facet \
20603                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20604                 [ $mdtfree2 -gt $mdtfree1 ] ||
20605                         error "MDT space is not freed after migration"
20606         fi
20607         return 0
20608 }
20609 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20610
20611 test_272c() {
20612         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20613                 skip "Need MDS version at least 2.11.50"
20614
20615         local dom=$DIR/$tdir/$tfile
20616         mkdir -p $DIR/$tdir
20617         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20618
20619         local mdtidx=$($LFS getstripe -m $dom)
20620         local mdtname=MDT$(printf %04x $mdtidx)
20621         local facet=mds$((mdtidx + 1))
20622
20623         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20624                 error "failed to write data into $dom"
20625         local old_md5=$(md5sum $dom)
20626         cancel_lru_locks mdc
20627         local mdtfree1=$(do_facet $facet \
20628                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20629
20630         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20631                 error "failed to migrate to the new composite layout"
20632         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20633                 error "MDT stripe was not removed"
20634
20635         cancel_lru_locks mdc
20636         local new_md5=$(md5sum $dom)
20637         [ "$old_md5" == "$new_md5" ] ||
20638                 error "$old_md5 != $new_md5"
20639
20640         # Skip free space checks with ZFS
20641         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20642                 local mdtfree2=$(do_facet $facet \
20643                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20644                 [ $mdtfree2 -gt $mdtfree1 ] ||
20645                         error "MDS space is not freed after migration"
20646         fi
20647         return 0
20648 }
20649 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20650
20651 test_272d() {
20652         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20653                 skip "Need MDS version at least 2.12.55"
20654
20655         local dom=$DIR/$tdir/$tfile
20656         mkdir -p $DIR/$tdir
20657         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20658
20659         local mdtidx=$($LFS getstripe -m $dom)
20660         local mdtname=MDT$(printf %04x $mdtidx)
20661         local facet=mds$((mdtidx + 1))
20662
20663         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20664                 error "failed to write data into $dom"
20665         local old_md5=$(md5sum $dom)
20666         cancel_lru_locks mdc
20667         local mdtfree1=$(do_facet $facet \
20668                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20669
20670         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20671                 error "failed mirroring to the new composite layout"
20672         $LFS mirror resync $dom ||
20673                 error "failed mirror resync"
20674         $LFS mirror split --mirror-id 1 -d $dom ||
20675                 error "failed mirror split"
20676
20677         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20678                 error "MDT stripe was not removed"
20679
20680         cancel_lru_locks mdc
20681         local new_md5=$(md5sum $dom)
20682         [ "$old_md5" == "$new_md5" ] ||
20683                 error "$old_md5 != $new_md5"
20684
20685         # Skip free space checks with ZFS
20686         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20687                 local mdtfree2=$(do_facet $facet \
20688                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20689                 [ $mdtfree2 -gt $mdtfree1 ] ||
20690                         error "MDS space is not freed after DOM mirror deletion"
20691         fi
20692         return 0
20693 }
20694 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20695
20696 test_272e() {
20697         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20698                 skip "Need MDS version at least 2.12.55"
20699
20700         local dom=$DIR/$tdir/$tfile
20701         mkdir -p $DIR/$tdir
20702         $LFS setstripe -c 2 $dom
20703
20704         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20705                 error "failed to write data into $dom"
20706         local old_md5=$(md5sum $dom)
20707         cancel_lru_locks mdc
20708
20709         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20710                 error "failed mirroring to the DOM 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         return 0
20725 }
20726 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20727
20728 test_272f() {
20729         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20730                 skip "Need MDS version at least 2.12.55"
20731
20732         local dom=$DIR/$tdir/$tfile
20733         mkdir -p $DIR/$tdir
20734         $LFS setstripe -c 2 $dom
20735
20736         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20737                 error "failed to write data into $dom"
20738         local old_md5=$(md5sum $dom)
20739         cancel_lru_locks mdc
20740
20741         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20742                 error "failed migrating to the DOM file"
20743
20744         cancel_lru_locks mdc
20745         local new_md5=$(md5sum $dom)
20746         [ "$old_md5" != "$new_md5" ] &&
20747                 error "$old_md5 != $new_md5"
20748
20749         return 0
20750 }
20751 run_test 272f "DoM migration: OST-striped file to DOM file"
20752
20753 test_273a() {
20754         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20755                 skip "Need MDS version at least 2.11.50"
20756
20757         # Layout swap cannot be done if either file has DOM component,
20758         # this will never be supported, migration should be used instead
20759
20760         local dom=$DIR/$tdir/$tfile
20761         mkdir -p $DIR/$tdir
20762
20763         $LFS setstripe -c2 ${dom}_plain
20764         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20765         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20766                 error "can swap layout with DoM component"
20767         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20768                 error "can swap layout with DoM component"
20769
20770         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20771         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20772                 error "can swap layout with DoM component"
20773         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20774                 error "can swap layout with DoM component"
20775         return 0
20776 }
20777 run_test 273a "DoM: layout swapping should fail with DOM"
20778
20779 test_275() {
20780         remote_ost_nodsh && skip "remote OST with nodsh"
20781         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20782                 skip "Need OST version >= 2.10.57"
20783
20784         local file=$DIR/$tfile
20785         local oss
20786
20787         oss=$(comma_list $(osts_nodes))
20788
20789         dd if=/dev/urandom of=$file bs=1M count=2 ||
20790                 error "failed to create a file"
20791         cancel_lru_locks osc
20792
20793         #lock 1
20794         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20795                 error "failed to read a file"
20796
20797 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20798         $LCTL set_param fail_loc=0x8000031f
20799
20800         cancel_lru_locks osc &
20801         sleep 1
20802
20803 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20804         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20805         #IO takes another lock, but matches the PENDING one
20806         #and places it to the IO RPC
20807         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20808                 error "failed to read a file with PENDING lock"
20809 }
20810 run_test 275 "Read on a canceled duplicate lock"
20811
20812 test_276() {
20813         remote_ost_nodsh && skip "remote OST with nodsh"
20814         local pid
20815
20816         do_facet ost1 "(while true; do \
20817                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20818                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20819         pid=$!
20820
20821         for LOOP in $(seq 20); do
20822                 stop ost1
20823                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20824         done
20825         kill -9 $pid
20826         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20827                 rm $TMP/sanity_276_pid"
20828 }
20829 run_test 276 "Race between mount and obd_statfs"
20830
20831 test_277() {
20832         $LCTL set_param ldlm.namespaces.*.lru_size=0
20833         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20834         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20835                         grep ^used_mb | awk '{print $2}')
20836         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20837         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20838                 oflag=direct conv=notrunc
20839         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20840                         grep ^used_mb | awk '{print $2}')
20841         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20842 }
20843 run_test 277 "Direct IO shall drop page cache"
20844
20845 test_278() {
20846         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20847         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20848         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20849                 skip "needs the same host for mdt1 mdt2" && return
20850
20851         local pid1
20852         local pid2
20853
20854 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20855         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20856         stop mds2 &
20857         pid2=$!
20858
20859         stop mds1
20860
20861         echo "Starting MDTs"
20862         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20863         wait $pid2
20864 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20865 #will return NULL
20866         do_facet mds2 $LCTL set_param fail_loc=0
20867
20868         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20869         wait_recovery_complete mds2
20870 }
20871 run_test 278 "Race starting MDS between MDTs stop/start"
20872
20873 test_280() {
20874         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20875                 skip "Need MGS version at least 2.13.52"
20876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20877         combined_mgs_mds || skip "needs combined MGS/MDT"
20878
20879         umount_client $MOUNT
20880 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20881         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20882
20883         mount_client $MOUNT &
20884         sleep 1
20885         stop mgs || error "stop mgs failed"
20886         #for a race mgs would crash
20887         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20888         mount_client $MOUNT || error "mount client failed"
20889 }
20890 run_test 280 "Race between MGS umount and client llog processing"
20891
20892 cleanup_test_300() {
20893         trap 0
20894         umask $SAVE_UMASK
20895 }
20896 test_striped_dir() {
20897         local mdt_index=$1
20898         local stripe_count
20899         local stripe_index
20900
20901         mkdir -p $DIR/$tdir
20902
20903         SAVE_UMASK=$(umask)
20904         trap cleanup_test_300 RETURN EXIT
20905
20906         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20907                                                 $DIR/$tdir/striped_dir ||
20908                 error "set striped dir error"
20909
20910         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20911         [ "$mode" = "755" ] || error "expect 755 got $mode"
20912
20913         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20914                 error "getdirstripe failed"
20915         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20916         if [ "$stripe_count" != "2" ]; then
20917                 error "1:stripe_count is $stripe_count, expect 2"
20918         fi
20919         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20920         if [ "$stripe_count" != "2" ]; then
20921                 error "2:stripe_count is $stripe_count, expect 2"
20922         fi
20923
20924         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20925         if [ "$stripe_index" != "$mdt_index" ]; then
20926                 error "stripe_index is $stripe_index, expect $mdt_index"
20927         fi
20928
20929         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20930                 error "nlink error after create striped dir"
20931
20932         mkdir $DIR/$tdir/striped_dir/a
20933         mkdir $DIR/$tdir/striped_dir/b
20934
20935         stat $DIR/$tdir/striped_dir/a ||
20936                 error "create dir under striped dir failed"
20937         stat $DIR/$tdir/striped_dir/b ||
20938                 error "create dir under striped dir failed"
20939
20940         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20941                 error "nlink error after mkdir"
20942
20943         rmdir $DIR/$tdir/striped_dir/a
20944         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20945                 error "nlink error after rmdir"
20946
20947         rmdir $DIR/$tdir/striped_dir/b
20948         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20949                 error "nlink error after rmdir"
20950
20951         chattr +i $DIR/$tdir/striped_dir
20952         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20953                 error "immutable flags not working under striped dir!"
20954         chattr -i $DIR/$tdir/striped_dir
20955
20956         rmdir $DIR/$tdir/striped_dir ||
20957                 error "rmdir striped dir error"
20958
20959         cleanup_test_300
20960
20961         true
20962 }
20963
20964 test_300a() {
20965         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20966                 skip "skipped for lustre < 2.7.0"
20967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20969
20970         test_striped_dir 0 || error "failed on striped dir on MDT0"
20971         test_striped_dir 1 || error "failed on striped dir on MDT0"
20972 }
20973 run_test 300a "basic striped dir sanity test"
20974
20975 test_300b() {
20976         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20977                 skip "skipped for lustre < 2.7.0"
20978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20979         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20980
20981         local i
20982         local mtime1
20983         local mtime2
20984         local mtime3
20985
20986         test_mkdir $DIR/$tdir || error "mkdir fail"
20987         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20988                 error "set striped dir error"
20989         for i in {0..9}; do
20990                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20991                 sleep 1
20992                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20993                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20994                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20995                 sleep 1
20996                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20997                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20998                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20999         done
21000         true
21001 }
21002 run_test 300b "check ctime/mtime for striped dir"
21003
21004 test_300c() {
21005         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21006                 skip "skipped for lustre < 2.7.0"
21007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21009
21010         local file_count
21011
21012         mkdir -p $DIR/$tdir
21013         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21014                 error "set striped dir error"
21015
21016         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21017                 error "chown striped dir failed"
21018
21019         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21020                 error "create 5k files failed"
21021
21022         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21023
21024         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21025
21026         rm -rf $DIR/$tdir
21027 }
21028 run_test 300c "chown && check ls under striped directory"
21029
21030 test_300d() {
21031         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21032                 skip "skipped for lustre < 2.7.0"
21033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21034         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21035
21036         local stripe_count
21037         local file
21038
21039         mkdir -p $DIR/$tdir
21040         $LFS setstripe -c 2 $DIR/$tdir
21041
21042         #local striped directory
21043         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21044                 error "set striped dir error"
21045         #look at the directories for debug purposes
21046         ls -l $DIR/$tdir
21047         $LFS getdirstripe $DIR/$tdir
21048         ls -l $DIR/$tdir/striped_dir
21049         $LFS getdirstripe $DIR/$tdir/striped_dir
21050         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21051                 error "create 10 files failed"
21052
21053         #remote striped directory
21054         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21055                 error "set striped dir error"
21056         #look at the directories for debug purposes
21057         ls -l $DIR/$tdir
21058         $LFS getdirstripe $DIR/$tdir
21059         ls -l $DIR/$tdir/remote_striped_dir
21060         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21061         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21062                 error "create 10 files failed"
21063
21064         for file in $(find $DIR/$tdir); do
21065                 stripe_count=$($LFS getstripe -c $file)
21066                 [ $stripe_count -eq 2 ] ||
21067                         error "wrong stripe $stripe_count for $file"
21068         done
21069
21070         rm -rf $DIR/$tdir
21071 }
21072 run_test 300d "check default stripe under striped directory"
21073
21074 test_300e() {
21075         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21076                 skip "Need MDS version at least 2.7.55"
21077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21078         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21079
21080         local stripe_count
21081         local file
21082
21083         mkdir -p $DIR/$tdir
21084
21085         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21086                 error "set striped dir error"
21087
21088         touch $DIR/$tdir/striped_dir/a
21089         touch $DIR/$tdir/striped_dir/b
21090         touch $DIR/$tdir/striped_dir/c
21091
21092         mkdir $DIR/$tdir/striped_dir/dir_a
21093         mkdir $DIR/$tdir/striped_dir/dir_b
21094         mkdir $DIR/$tdir/striped_dir/dir_c
21095
21096         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21097                 error "set striped adir under striped dir error"
21098
21099         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21100                 error "set striped bdir under striped dir error"
21101
21102         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21103                 error "set striped cdir under striped dir error"
21104
21105         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21106                 error "rename dir under striped dir fails"
21107
21108         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21109                 error "rename dir under different stripes fails"
21110
21111         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21112                 error "rename file under striped dir should succeed"
21113
21114         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21115                 error "rename dir under striped dir should succeed"
21116
21117         rm -rf $DIR/$tdir
21118 }
21119 run_test 300e "check rename under striped directory"
21120
21121 test_300f() {
21122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21124         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21125                 skip "Need MDS version at least 2.7.55"
21126
21127         local stripe_count
21128         local file
21129
21130         rm -rf $DIR/$tdir
21131         mkdir -p $DIR/$tdir
21132
21133         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21134                 error "set striped dir error"
21135
21136         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21137                 error "set striped dir error"
21138
21139         touch $DIR/$tdir/striped_dir/a
21140         mkdir $DIR/$tdir/striped_dir/dir_a
21141         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21142                 error "create striped dir under striped dir fails"
21143
21144         touch $DIR/$tdir/striped_dir1/b
21145         mkdir $DIR/$tdir/striped_dir1/dir_b
21146         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21147                 error "create striped dir under striped dir fails"
21148
21149         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21150                 error "rename dir under different striped dir should fail"
21151
21152         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21153                 error "rename striped dir under diff striped dir should fail"
21154
21155         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21156                 error "rename file under diff striped dirs fails"
21157
21158         rm -rf $DIR/$tdir
21159 }
21160 run_test 300f "check rename cross striped directory"
21161
21162 test_300_check_default_striped_dir()
21163 {
21164         local dirname=$1
21165         local default_count=$2
21166         local default_index=$3
21167         local stripe_count
21168         local stripe_index
21169         local dir_stripe_index
21170         local dir
21171
21172         echo "checking $dirname $default_count $default_index"
21173         $LFS setdirstripe -D -c $default_count -i $default_index \
21174                                 -t all_char $DIR/$tdir/$dirname ||
21175                 error "set default stripe on striped dir error"
21176         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21177         [ $stripe_count -eq $default_count ] ||
21178                 error "expect $default_count get $stripe_count for $dirname"
21179
21180         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21181         [ $stripe_index -eq $default_index ] ||
21182                 error "expect $default_index get $stripe_index for $dirname"
21183
21184         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21185                                                 error "create dirs failed"
21186
21187         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21188         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21189         for dir in $(find $DIR/$tdir/$dirname/*); do
21190                 stripe_count=$($LFS getdirstripe -c $dir)
21191                 [ $stripe_count -eq $default_count ] ||
21192                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21193                 error "stripe count $default_count != $stripe_count for $dir"
21194
21195                 stripe_index=$($LFS getdirstripe -i $dir)
21196                 [ $default_index -eq -1 ] ||
21197                         [ $stripe_index -eq $default_index ] ||
21198                         error "$stripe_index != $default_index for $dir"
21199
21200                 #check default stripe
21201                 stripe_count=$($LFS getdirstripe -D -c $dir)
21202                 [ $stripe_count -eq $default_count ] ||
21203                 error "default count $default_count != $stripe_count for $dir"
21204
21205                 stripe_index=$($LFS getdirstripe -D -i $dir)
21206                 [ $stripe_index -eq $default_index ] ||
21207                 error "default index $default_index != $stripe_index for $dir"
21208         done
21209         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21210 }
21211
21212 test_300g() {
21213         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21214         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21215                 skip "Need MDS version at least 2.7.55"
21216
21217         local dir
21218         local stripe_count
21219         local stripe_index
21220
21221         mkdir $DIR/$tdir
21222         mkdir $DIR/$tdir/normal_dir
21223
21224         #Checking when client cache stripe index
21225         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21226         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21227                 error "create striped_dir failed"
21228
21229         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21230                 error "create dir0 fails"
21231         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21232         [ $stripe_index -eq 0 ] ||
21233                 error "dir0 expect index 0 got $stripe_index"
21234
21235         mkdir $DIR/$tdir/striped_dir/dir1 ||
21236                 error "create dir1 fails"
21237         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21238         [ $stripe_index -eq 1 ] ||
21239                 error "dir1 expect index 1 got $stripe_index"
21240
21241         #check default stripe count/stripe index
21242         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21243         test_300_check_default_striped_dir normal_dir 1 0
21244         test_300_check_default_striped_dir normal_dir 2 1
21245         test_300_check_default_striped_dir normal_dir 2 -1
21246
21247         #delete default stripe information
21248         echo "delete default stripeEA"
21249         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21250                 error "set default stripe on striped dir error"
21251
21252         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21253         for dir in $(find $DIR/$tdir/normal_dir/*); do
21254                 stripe_count=$($LFS getdirstripe -c $dir)
21255                 [ $stripe_count -eq 0 ] ||
21256                         error "expect 1 get $stripe_count for $dir"
21257                 stripe_index=$($LFS getdirstripe -i $dir)
21258                 [ $stripe_index -eq 0 ] ||
21259                         error "expect 0 get $stripe_index for $dir"
21260         done
21261 }
21262 run_test 300g "check default striped directory for normal directory"
21263
21264 test_300h() {
21265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21266         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21267                 skip "Need MDS version at least 2.7.55"
21268
21269         local dir
21270         local stripe_count
21271
21272         mkdir $DIR/$tdir
21273         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21274                 error "set striped dir error"
21275
21276         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21277         test_300_check_default_striped_dir striped_dir 1 0
21278         test_300_check_default_striped_dir striped_dir 2 1
21279         test_300_check_default_striped_dir striped_dir 2 -1
21280
21281         #delete default stripe information
21282         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21283                 error "set default stripe on striped dir error"
21284
21285         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21286         for dir in $(find $DIR/$tdir/striped_dir/*); do
21287                 stripe_count=$($LFS getdirstripe -c $dir)
21288                 [ $stripe_count -eq 0 ] ||
21289                         error "expect 1 get $stripe_count for $dir"
21290         done
21291 }
21292 run_test 300h "check default striped directory for striped directory"
21293
21294 test_300i() {
21295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21296         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21297         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21298                 skip "Need MDS version at least 2.7.55"
21299
21300         local stripe_count
21301         local file
21302
21303         mkdir $DIR/$tdir
21304
21305         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21306                 error "set striped dir error"
21307
21308         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21309                 error "create files under striped dir failed"
21310
21311         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21312                 error "set striped hashdir error"
21313
21314         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21315                 error "create dir0 under hash dir failed"
21316         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21317                 error "create dir1 under hash dir failed"
21318
21319         # unfortunately, we need to umount to clear dir layout cache for now
21320         # once we fully implement dir layout, we can drop this
21321         umount_client $MOUNT || error "umount failed"
21322         mount_client $MOUNT || error "mount failed"
21323
21324         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21325         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21326         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21327
21328         #set the stripe to be unknown hash type
21329         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21330         $LCTL set_param fail_loc=0x1901
21331         for ((i = 0; i < 10; i++)); do
21332                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21333                         error "stat f-$i failed"
21334                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21335         done
21336
21337         touch $DIR/$tdir/striped_dir/f0 &&
21338                 error "create under striped dir with unknown hash should fail"
21339
21340         $LCTL set_param fail_loc=0
21341
21342         umount_client $MOUNT || error "umount failed"
21343         mount_client $MOUNT || error "mount failed"
21344
21345         return 0
21346 }
21347 run_test 300i "client handle unknown hash type striped directory"
21348
21349 test_300j() {
21350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21352         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21353                 skip "Need MDS version at least 2.7.55"
21354
21355         local stripe_count
21356         local file
21357
21358         mkdir $DIR/$tdir
21359
21360         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21361         $LCTL set_param fail_loc=0x1702
21362         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21363                 error "set striped dir error"
21364
21365         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21366                 error "create files under striped dir failed"
21367
21368         $LCTL set_param fail_loc=0
21369
21370         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21371
21372         return 0
21373 }
21374 run_test 300j "test large update record"
21375
21376 test_300k() {
21377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21379         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21380                 skip "Need MDS version at least 2.7.55"
21381
21382         # this test needs a huge transaction
21383         local kb
21384         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21385              osd*.$FSNAME-MDT0000.kbytestotal")
21386         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21387
21388         local stripe_count
21389         local file
21390
21391         mkdir $DIR/$tdir
21392
21393         #define OBD_FAIL_LARGE_STRIPE   0x1703
21394         $LCTL set_param fail_loc=0x1703
21395         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21396                 error "set striped dir error"
21397         $LCTL set_param fail_loc=0
21398
21399         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21400                 error "getstripeddir fails"
21401         rm -rf $DIR/$tdir/striped_dir ||
21402                 error "unlink striped dir fails"
21403
21404         return 0
21405 }
21406 run_test 300k "test large striped directory"
21407
21408 test_300l() {
21409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21411         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21412                 skip "Need MDS version at least 2.7.55"
21413
21414         local stripe_index
21415
21416         test_mkdir -p $DIR/$tdir/striped_dir
21417         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21418                         error "chown $RUNAS_ID failed"
21419         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21420                 error "set default striped dir failed"
21421
21422         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21423         $LCTL set_param fail_loc=0x80000158
21424         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21425
21426         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21427         [ $stripe_index -eq 1 ] ||
21428                 error "expect 1 get $stripe_index for $dir"
21429 }
21430 run_test 300l "non-root user to create dir under striped dir with stale layout"
21431
21432 test_300m() {
21433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21434         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21435         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21436                 skip "Need MDS version at least 2.7.55"
21437
21438         mkdir -p $DIR/$tdir/striped_dir
21439         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21440                 error "set default stripes dir error"
21441
21442         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21443
21444         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21445         [ $stripe_count -eq 0 ] ||
21446                         error "expect 0 get $stripe_count for a"
21447
21448         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21449                 error "set default stripes dir error"
21450
21451         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21452
21453         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21454         [ $stripe_count -eq 0 ] ||
21455                         error "expect 0 get $stripe_count for b"
21456
21457         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21458                 error "set default stripes dir error"
21459
21460         mkdir $DIR/$tdir/striped_dir/c &&
21461                 error "default stripe_index is invalid, mkdir c should fails"
21462
21463         rm -rf $DIR/$tdir || error "rmdir fails"
21464 }
21465 run_test 300m "setstriped directory on single MDT FS"
21466
21467 cleanup_300n() {
21468         local list=$(comma_list $(mdts_nodes))
21469
21470         trap 0
21471         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21472 }
21473
21474 test_300n() {
21475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21476         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21477         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21478                 skip "Need MDS version at least 2.7.55"
21479         remote_mds_nodsh && skip "remote MDS with nodsh"
21480
21481         local stripe_index
21482         local list=$(comma_list $(mdts_nodes))
21483
21484         trap cleanup_300n RETURN EXIT
21485         mkdir -p $DIR/$tdir
21486         chmod 777 $DIR/$tdir
21487         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21488                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21489                 error "create striped dir succeeds with gid=0"
21490
21491         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21492         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21493                 error "create striped dir fails with gid=-1"
21494
21495         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21496         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21497                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21498                 error "set default striped dir succeeds with gid=0"
21499
21500
21501         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21502         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21503                 error "set default striped dir fails with gid=-1"
21504
21505
21506         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21507         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21508                                         error "create test_dir fails"
21509         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21510                                         error "create test_dir1 fails"
21511         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21512                                         error "create test_dir2 fails"
21513         cleanup_300n
21514 }
21515 run_test 300n "non-root user to create dir under striped dir with default EA"
21516
21517 test_300o() {
21518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21520         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21521                 skip "Need MDS version at least 2.7.55"
21522
21523         local numfree1
21524         local numfree2
21525
21526         mkdir -p $DIR/$tdir
21527
21528         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21529         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21530         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21531                 skip "not enough free inodes $numfree1 $numfree2"
21532         fi
21533
21534         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21535         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21536         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21537                 skip "not enough free space $numfree1 $numfree2"
21538         fi
21539
21540         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21541                 error "setdirstripe fails"
21542
21543         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21544                 error "create dirs fails"
21545
21546         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21547         ls $DIR/$tdir/striped_dir > /dev/null ||
21548                 error "ls striped dir fails"
21549         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21550                 error "unlink big striped dir fails"
21551 }
21552 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21553
21554 test_300p() {
21555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21557         remote_mds_nodsh && skip "remote MDS with nodsh"
21558
21559         mkdir -p $DIR/$tdir
21560
21561         #define OBD_FAIL_OUT_ENOSPC     0x1704
21562         do_facet mds2 lctl set_param fail_loc=0x80001704
21563         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21564                  && error "create striped directory should fail"
21565
21566         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21567
21568         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21569         true
21570 }
21571 run_test 300p "create striped directory without space"
21572
21573 test_300q() {
21574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21576
21577         local fd=$(free_fd)
21578         local cmd="exec $fd<$tdir"
21579         cd $DIR
21580         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21581         eval $cmd
21582         cmd="exec $fd<&-"
21583         trap "eval $cmd" EXIT
21584         cd $tdir || error "cd $tdir fails"
21585         rmdir  ../$tdir || error "rmdir $tdir fails"
21586         mkdir local_dir && error "create dir succeeds"
21587         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21588         eval $cmd
21589         return 0
21590 }
21591 run_test 300q "create remote directory under orphan directory"
21592
21593 test_300r() {
21594         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21595                 skip "Need MDS version at least 2.7.55" && return
21596         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21597
21598         mkdir $DIR/$tdir
21599
21600         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21601                 error "set striped dir error"
21602
21603         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21604                 error "getstripeddir fails"
21605
21606         local stripe_count
21607         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21608                       awk '/lmv_stripe_count:/ { print $2 }')
21609
21610         [ $MDSCOUNT -ne $stripe_count ] &&
21611                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21612
21613         rm -rf $DIR/$tdir/striped_dir ||
21614                 error "unlink striped dir fails"
21615 }
21616 run_test 300r "test -1 striped directory"
21617
21618 prepare_remote_file() {
21619         mkdir $DIR/$tdir/src_dir ||
21620                 error "create remote source failed"
21621
21622         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21623                  error "cp to remote source failed"
21624         touch $DIR/$tdir/src_dir/a
21625
21626         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21627                 error "create remote target dir failed"
21628
21629         touch $DIR/$tdir/tgt_dir/b
21630
21631         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21632                 error "rename dir cross MDT failed!"
21633
21634         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21635                 error "src_child still exists after rename"
21636
21637         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21638                 error "missing file(a) after rename"
21639
21640         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21641                 error "diff after rename"
21642 }
21643
21644 test_310a() {
21645         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21647
21648         local remote_file=$DIR/$tdir/tgt_dir/b
21649
21650         mkdir -p $DIR/$tdir
21651
21652         prepare_remote_file || error "prepare remote file failed"
21653
21654         #open-unlink file
21655         $OPENUNLINK $remote_file $remote_file ||
21656                 error "openunlink $remote_file failed"
21657         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21658 }
21659 run_test 310a "open unlink remote file"
21660
21661 test_310b() {
21662         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21664
21665         local remote_file=$DIR/$tdir/tgt_dir/b
21666
21667         mkdir -p $DIR/$tdir
21668
21669         prepare_remote_file || error "prepare remote file failed"
21670
21671         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21672         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21673         $CHECKSTAT -t file $remote_file || error "check file failed"
21674 }
21675 run_test 310b "unlink remote file with multiple links while open"
21676
21677 test_310c() {
21678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21679         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21680
21681         local remote_file=$DIR/$tdir/tgt_dir/b
21682
21683         mkdir -p $DIR/$tdir
21684
21685         prepare_remote_file || error "prepare remote file failed"
21686
21687         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21688         multiop_bg_pause $remote_file O_uc ||
21689                         error "mulitop failed for remote file"
21690         MULTIPID=$!
21691         $MULTIOP $DIR/$tfile Ouc
21692         kill -USR1 $MULTIPID
21693         wait $MULTIPID
21694 }
21695 run_test 310c "open-unlink remote file with multiple links"
21696
21697 #LU-4825
21698 test_311() {
21699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21700         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21701         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21702                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21703         remote_mds_nodsh && skip "remote MDS with nodsh"
21704
21705         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21706         local mdts=$(comma_list $(mdts_nodes))
21707
21708         mkdir -p $DIR/$tdir
21709         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21710         createmany -o $DIR/$tdir/$tfile. 1000
21711
21712         # statfs data is not real time, let's just calculate it
21713         old_iused=$((old_iused + 1000))
21714
21715         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21716                         osp.*OST0000*MDT0000.create_count")
21717         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21718                                 osp.*OST0000*MDT0000.max_create_count")
21719         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21720
21721         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21722         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21723         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21724
21725         unlinkmany $DIR/$tdir/$tfile. 1000
21726
21727         do_nodes $mdts "$LCTL set_param -n \
21728                         osp.*OST0000*.max_create_count=$max_count"
21729         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21730                 do_nodes $mdts "$LCTL set_param -n \
21731                                 osp.*OST0000*.create_count=$count"
21732         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21733                         grep "=0" && error "create_count is zero"
21734
21735         local new_iused
21736         for i in $(seq 120); do
21737                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21738                 # system may be too busy to destroy all objs in time, use
21739                 # a somewhat small value to not fail autotest
21740                 [ $((old_iused - new_iused)) -gt 400 ] && break
21741                 sleep 1
21742         done
21743
21744         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21745         [ $((old_iused - new_iused)) -gt 400 ] ||
21746                 error "objs not destroyed after unlink"
21747 }
21748 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21749
21750 zfs_oid_to_objid()
21751 {
21752         local ost=$1
21753         local objid=$2
21754
21755         local vdevdir=$(dirname $(facet_vdevice $ost))
21756         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21757         local zfs_zapid=$(do_facet $ost $cmd |
21758                           grep -w "/O/0/d$((objid%32))" -C 5 |
21759                           awk '/Object/{getline; print $1}')
21760         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21761                           awk "/$objid = /"'{printf $3}')
21762
21763         echo $zfs_objid
21764 }
21765
21766 zfs_object_blksz() {
21767         local ost=$1
21768         local objid=$2
21769
21770         local vdevdir=$(dirname $(facet_vdevice $ost))
21771         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21772         local blksz=$(do_facet $ost $cmd $objid |
21773                       awk '/dblk/{getline; printf $4}')
21774
21775         case "${blksz: -1}" in
21776                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21777                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21778                 *) ;;
21779         esac
21780
21781         echo $blksz
21782 }
21783
21784 test_312() { # LU-4856
21785         remote_ost_nodsh && skip "remote OST with nodsh"
21786         [ "$ost1_FSTYPE" = "zfs" ] ||
21787                 skip_env "the test only applies to zfs"
21788
21789         local max_blksz=$(do_facet ost1 \
21790                           $ZFS get -p recordsize $(facet_device ost1) |
21791                           awk '!/VALUE/{print $3}')
21792
21793         # to make life a little bit easier
21794         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21795         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21796
21797         local tf=$DIR/$tdir/$tfile
21798         touch $tf
21799         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21800
21801         # Get ZFS object id
21802         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21803         # block size change by sequential overwrite
21804         local bs
21805
21806         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21807                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21808
21809                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21810                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21811         done
21812         rm -f $tf
21813
21814         # block size change by sequential append write
21815         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21816         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21817         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21818         local count
21819
21820         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21821                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21822                         oflag=sync conv=notrunc
21823
21824                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21825                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21826                         error "blksz error, actual $blksz, " \
21827                                 "expected: 2 * $count * $PAGE_SIZE"
21828         done
21829         rm -f $tf
21830
21831         # random write
21832         touch $tf
21833         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21834         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21835
21836         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21837         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21838         [ $blksz -eq $PAGE_SIZE ] ||
21839                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21840
21841         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21842         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21843         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21844
21845         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21846         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21847         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21848 }
21849 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21850
21851 test_313() {
21852         remote_ost_nodsh && skip "remote OST with nodsh"
21853
21854         local file=$DIR/$tfile
21855
21856         rm -f $file
21857         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21858
21859         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21860         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21861         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21862                 error "write should failed"
21863         do_facet ost1 "$LCTL set_param fail_loc=0"
21864         rm -f $file
21865 }
21866 run_test 313 "io should fail after last_rcvd update fail"
21867
21868 test_314() {
21869         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21870
21871         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21872         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21873         rm -f $DIR/$tfile
21874         wait_delete_completed
21875         do_facet ost1 "$LCTL set_param fail_loc=0"
21876 }
21877 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21878
21879 test_315() { # LU-618
21880         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21881
21882         local file=$DIR/$tfile
21883         rm -f $file
21884
21885         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21886                 error "multiop file write failed"
21887         $MULTIOP $file oO_RDONLY:r4063232_c &
21888         PID=$!
21889
21890         sleep 2
21891
21892         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21893         kill -USR1 $PID
21894
21895         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21896         rm -f $file
21897 }
21898 run_test 315 "read should be accounted"
21899
21900 test_316() {
21901         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21902         large_xattr_enabled || skip_env "ea_inode feature disabled"
21903
21904         rm -rf $DIR/$tdir/d
21905         mkdir -p $DIR/$tdir/d
21906         chown nobody $DIR/$tdir/d
21907         touch $DIR/$tdir/d/file
21908
21909         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21910 }
21911 run_test 316 "lfs mv"
21912
21913 test_317() {
21914         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21915                 skip "Need MDS version at least 2.11.53"
21916         if [ "$ost1_FSTYPE" == "zfs" ]; then
21917                 skip "LU-10370: no implementation for ZFS"
21918         fi
21919
21920         local trunc_sz
21921         local grant_blk_size
21922
21923         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21924                         awk '/grant_block_size:/ { print $2; exit; }')
21925         #
21926         # Create File of size 5M. Truncate it to below size's and verify
21927         # blocks count.
21928         #
21929         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21930                 error "Create file $DIR/$tfile failed"
21931         stack_trap "rm -f $DIR/$tfile" EXIT
21932
21933         for trunc_sz in 2097152 4097 4000 509 0; do
21934                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21935                         error "truncate $tfile to $trunc_sz failed"
21936                 local sz=$(stat --format=%s $DIR/$tfile)
21937                 local blk=$(stat --format=%b $DIR/$tfile)
21938                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21939                                      grant_blk_size) * 8))
21940
21941                 if [[ $blk -ne $trunc_blk ]]; then
21942                         $(which stat) $DIR/$tfile
21943                         error "Expected Block $trunc_blk got $blk for $tfile"
21944                 fi
21945
21946                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21947                         error "Expected Size $trunc_sz got $sz for $tfile"
21948         done
21949
21950         #
21951         # sparse file test
21952         # Create file with a hole and write actual two blocks. Block count
21953         # must be 16.
21954         #
21955         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21956                 conv=fsync || error "Create file : $DIR/$tfile"
21957
21958         # Calculate the final truncate size.
21959         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21960
21961         #
21962         # truncate to size $trunc_sz bytes. Strip the last block
21963         # The block count must drop to 8
21964         #
21965         $TRUNCATE $DIR/$tfile $trunc_sz ||
21966                 error "truncate $tfile to $trunc_sz failed"
21967
21968         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21969         sz=$(stat --format=%s $DIR/$tfile)
21970         blk=$(stat --format=%b $DIR/$tfile)
21971
21972         if [[ $blk -ne $trunc_bsz ]]; then
21973                 $(which stat) $DIR/$tfile
21974                 error "Expected Block $trunc_bsz got $blk for $tfile"
21975         fi
21976
21977         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21978                 error "Expected Size $trunc_sz got $sz for $tfile"
21979 }
21980 run_test 317 "Verify blocks get correctly update after truncate"
21981
21982 test_318() {
21983         local old_max_active=$($LCTL get_param -n \
21984                             llite.*.max_read_ahead_async_active 2>/dev/null)
21985
21986         $LCTL set_param llite.*.max_read_ahead_async_active=256
21987         local max_active=$($LCTL get_param -n \
21988                            llite.*.max_read_ahead_async_active 2>/dev/null)
21989         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21990
21991         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21992                 error "set max_read_ahead_async_active should succeed"
21993
21994         $LCTL set_param llite.*.max_read_ahead_async_active=512
21995         max_active=$($LCTL get_param -n \
21996                      llite.*.max_read_ahead_async_active 2>/dev/null)
21997         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21998
21999         # restore @max_active
22000         [ $old_max_active -ne 0 ] && $LCTL set_param \
22001                 llite.*.max_read_ahead_async_active=$old_max_active
22002
22003         local old_threshold=$($LCTL get_param -n \
22004                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22005         local max_per_file_mb=$($LCTL get_param -n \
22006                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22007
22008         local invalid=$(($max_per_file_mb + 1))
22009         $LCTL set_param \
22010                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22011                         && error "set $invalid should fail"
22012
22013         local valid=$(($invalid - 1))
22014         $LCTL set_param \
22015                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22016                         error "set $valid should succeed"
22017         local threshold=$($LCTL get_param -n \
22018                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22019         [ $threshold -eq $valid ] || error \
22020                 "expect threshold $valid got $threshold"
22021         $LCTL set_param \
22022                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22023 }
22024 run_test 318 "Verify async readahead tunables"
22025
22026 test_319() {
22027         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22028
22029         local before=$(date +%s)
22030         local evict
22031         local mdir=$DIR/$tdir
22032         local file=$mdir/xxx
22033
22034         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22035         touch $file
22036
22037 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22038         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22039         $LFS mv -m1 $file &
22040
22041         sleep 1
22042         dd if=$file of=/dev/null
22043         wait
22044         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22045           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22046
22047         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22048 }
22049 run_test 319 "lost lease lock on migrate error"
22050
22051 test_398a() { # LU-4198
22052         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22053         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22054
22055         # request a new lock on client
22056         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22057
22058         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22059         local lock_count=$($LCTL get_param -n \
22060                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22061         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22062
22063         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22064
22065         # no lock cached, should use lockless IO and not enqueue new lock
22066         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22067         lock_count=$($LCTL get_param -n \
22068                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22069         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22070 }
22071 run_test 398a "direct IO should cancel lock otherwise lockless"
22072
22073 test_398b() { # LU-4198
22074         which fio || skip_env "no fio installed"
22075         $LFS setstripe -c -1 $DIR/$tfile
22076
22077         local size=12
22078         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22079
22080         local njobs=4
22081         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22082         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22083                 --numjobs=$njobs --fallocate=none \
22084                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22085                 --filename=$DIR/$tfile &
22086         bg_pid=$!
22087
22088         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22089         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22090                 --numjobs=$njobs --fallocate=none \
22091                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22092                 --filename=$DIR/$tfile || true
22093         wait $bg_pid
22094
22095         rm -rf $DIR/$tfile
22096 }
22097 run_test 398b "DIO and buffer IO race"
22098
22099 test_398c() { # LU-4198
22100         which fio || skip_env "no fio installed"
22101
22102         saved_debug=$($LCTL get_param -n debug)
22103         $LCTL set_param debug=0
22104
22105         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22106         ((size /= 1024)) # by megabytes
22107         ((size /= 2)) # write half of the OST at most
22108         [ $size -gt 40 ] && size=40 #reduce test time anyway
22109
22110         $LFS setstripe -c 1 $DIR/$tfile
22111
22112         # it seems like ldiskfs reserves more space than necessary if the
22113         # writing blocks are not mapped, so it extends the file firstly
22114         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22115         cancel_lru_locks osc
22116
22117         # clear and verify rpc_stats later
22118         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22119
22120         local njobs=4
22121         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22122         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22123                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22124                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22125                 --filename=$DIR/$tfile
22126         [ $? -eq 0 ] || error "fio write error"
22127
22128         [ $($LCTL get_param -n \
22129          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22130                 error "Locks were requested while doing AIO"
22131
22132         # get the percentage of 1-page I/O
22133         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22134                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22135                 awk '{print $7}')
22136         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22137
22138         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22139         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22140                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22141                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22142                 --filename=$DIR/$tfile
22143         [ $? -eq 0 ] || error "fio mixed read write error"
22144
22145         echo "AIO with large block size ${size}M"
22146         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22147                 --numjobs=1 --fallocate=none --ioengine=libaio \
22148                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22149                 --filename=$DIR/$tfile
22150         [ $? -eq 0 ] || error "fio large block size failed"
22151
22152         rm -rf $DIR/$tfile
22153         $LCTL set_param debug="$saved_debug"
22154 }
22155 run_test 398c "run fio to test AIO"
22156
22157 test_398d() { #  LU-13846
22158         test -f aiocp || skip_env "no aiocp installed"
22159         local aio_file=$DIR/aio_file
22160
22161         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22162
22163         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22164         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22165
22166         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22167
22168         # make sure we don't crash and fail properly
22169         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22170                 error "aio not aligned with PAGE SIZE should fail"
22171
22172         rm -rf $DIR/$tfile $aio_file
22173 }
22174 run_test 398d "run aiocp to verify block size > stripe size"
22175
22176 test_fake_rw() {
22177         local read_write=$1
22178         if [ "$read_write" = "write" ]; then
22179                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22180         elif [ "$read_write" = "read" ]; then
22181                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22182         else
22183                 error "argument error"
22184         fi
22185
22186         # turn off debug for performance testing
22187         local saved_debug=$($LCTL get_param -n debug)
22188         $LCTL set_param debug=0
22189
22190         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22191
22192         # get ost1 size - $FSNAME-OST0000
22193         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22194         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22195         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22196
22197         if [ "$read_write" = "read" ]; then
22198                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22199         fi
22200
22201         local start_time=$(date +%s.%N)
22202         $dd_cmd bs=1M count=$blocks oflag=sync ||
22203                 error "real dd $read_write error"
22204         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22205
22206         if [ "$read_write" = "write" ]; then
22207                 rm -f $DIR/$tfile
22208         fi
22209
22210         # define OBD_FAIL_OST_FAKE_RW           0x238
22211         do_facet ost1 $LCTL set_param fail_loc=0x238
22212
22213         local start_time=$(date +%s.%N)
22214         $dd_cmd bs=1M count=$blocks oflag=sync ||
22215                 error "fake dd $read_write error"
22216         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22217
22218         if [ "$read_write" = "write" ]; then
22219                 # verify file size
22220                 cancel_lru_locks osc
22221                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22222                         error "$tfile size not $blocks MB"
22223         fi
22224         do_facet ost1 $LCTL set_param fail_loc=0
22225
22226         echo "fake $read_write $duration_fake vs. normal $read_write" \
22227                 "$duration in seconds"
22228         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22229                 error_not_in_vm "fake write is slower"
22230
22231         $LCTL set_param -n debug="$saved_debug"
22232         rm -f $DIR/$tfile
22233 }
22234 test_399a() { # LU-7655 for OST fake write
22235         remote_ost_nodsh && skip "remote OST with nodsh"
22236
22237         test_fake_rw write
22238 }
22239 run_test 399a "fake write should not be slower than normal write"
22240
22241 test_399b() { # LU-8726 for OST fake read
22242         remote_ost_nodsh && skip "remote OST with nodsh"
22243         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22244                 skip_env "ldiskfs only test"
22245         fi
22246
22247         test_fake_rw read
22248 }
22249 run_test 399b "fake read should not be slower than normal read"
22250
22251 test_400a() { # LU-1606, was conf-sanity test_74
22252         if ! which $CC > /dev/null 2>&1; then
22253                 skip_env "$CC is not installed"
22254         fi
22255
22256         local extra_flags=''
22257         local out=$TMP/$tfile
22258         local prefix=/usr/include/lustre
22259         local prog
22260
22261         # Oleg removes c files in his test rig so test if any c files exist
22262         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22263                 skip_env "Needed c test files are missing"
22264
22265         if ! [[ -d $prefix ]]; then
22266                 # Assume we're running in tree and fixup the include path.
22267                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22268                 extra_flags+=" -L$LUSTRE/utils/.lib"
22269         fi
22270
22271         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22272                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22273                         error "client api broken"
22274         done
22275         rm -f $out
22276 }
22277 run_test 400a "Lustre client api program can compile and link"
22278
22279 test_400b() { # LU-1606, LU-5011
22280         local header
22281         local out=$TMP/$tfile
22282         local prefix=/usr/include/linux/lustre
22283
22284         # We use a hard coded prefix so that this test will not fail
22285         # when run in tree. There are headers in lustre/include/lustre/
22286         # that are not packaged (like lustre_idl.h) and have more
22287         # complicated include dependencies (like config.h and lnet/types.h).
22288         # Since this test about correct packaging we just skip them when
22289         # they don't exist (see below) rather than try to fixup cppflags.
22290
22291         if ! which $CC > /dev/null 2>&1; then
22292                 skip_env "$CC is not installed"
22293         fi
22294
22295         for header in $prefix/*.h; do
22296                 if ! [[ -f "$header" ]]; then
22297                         continue
22298                 fi
22299
22300                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22301                         continue # lustre_ioctl.h is internal header
22302                 fi
22303
22304                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22305                         error "cannot compile '$header'"
22306         done
22307         rm -f $out
22308 }
22309 run_test 400b "packaged headers can be compiled"
22310
22311 test_401a() { #LU-7437
22312         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22313         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22314
22315         #count the number of parameters by "list_param -R"
22316         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22317         #count the number of parameters by listing proc files
22318         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22319         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22320         echo "proc_dirs='$proc_dirs'"
22321         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22322         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22323                       sort -u | wc -l)
22324
22325         [ $params -eq $procs ] ||
22326                 error "found $params parameters vs. $procs proc files"
22327
22328         # test the list_param -D option only returns directories
22329         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22330         #count the number of parameters by listing proc directories
22331         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22332                 sort -u | wc -l)
22333
22334         [ $params -eq $procs ] ||
22335                 error "found $params parameters vs. $procs proc files"
22336 }
22337 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22338
22339 test_401b() {
22340         # jobid_var may not allow arbitrary values, so use jobid_name
22341         # if available
22342         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22343                 local testname=jobid_name tmp='testing%p'
22344         else
22345                 local testname=jobid_var tmp=testing
22346         fi
22347
22348         local save=$($LCTL get_param -n $testname)
22349
22350         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22351                 error "no error returned when setting bad parameters"
22352
22353         local jobid_new=$($LCTL get_param -n foe $testname baz)
22354         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22355
22356         $LCTL set_param -n fog=bam $testname=$save bat=fog
22357         local jobid_old=$($LCTL get_param -n foe $testname bag)
22358         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22359 }
22360 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22361
22362 test_401c() {
22363         # jobid_var may not allow arbitrary values, so use jobid_name
22364         # if available
22365         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22366                 local testname=jobid_name
22367         else
22368                 local testname=jobid_var
22369         fi
22370
22371         local jobid_var_old=$($LCTL get_param -n $testname)
22372         local jobid_var_new
22373
22374         $LCTL set_param $testname= &&
22375                 error "no error returned for 'set_param a='"
22376
22377         jobid_var_new=$($LCTL get_param -n $testname)
22378         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22379                 error "$testname was changed by setting without value"
22380
22381         $LCTL set_param $testname &&
22382                 error "no error returned for 'set_param a'"
22383
22384         jobid_var_new=$($LCTL get_param -n $testname)
22385         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22386                 error "$testname was changed by setting without value"
22387 }
22388 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22389
22390 test_401d() {
22391         # jobid_var may not allow arbitrary values, so use jobid_name
22392         # if available
22393         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22394                 local testname=jobid_name new_value='foo=bar%p'
22395         else
22396                 local testname=jobid_var new_valuie=foo=bar
22397         fi
22398
22399         local jobid_var_old=$($LCTL get_param -n $testname)
22400         local jobid_var_new
22401
22402         $LCTL set_param $testname=$new_value ||
22403                 error "'set_param a=b' did not accept a value containing '='"
22404
22405         jobid_var_new=$($LCTL get_param -n $testname)
22406         [[ "$jobid_var_new" == "$new_value" ]] ||
22407                 error "'set_param a=b' failed on a value containing '='"
22408
22409         # Reset the $testname to test the other format
22410         $LCTL set_param $testname=$jobid_var_old
22411         jobid_var_new=$($LCTL get_param -n $testname)
22412         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22413                 error "failed to reset $testname"
22414
22415         $LCTL set_param $testname $new_value ||
22416                 error "'set_param a b' did not accept a value containing '='"
22417
22418         jobid_var_new=$($LCTL get_param -n $testname)
22419         [[ "$jobid_var_new" == "$new_value" ]] ||
22420                 error "'set_param a b' failed on a value containing '='"
22421
22422         $LCTL set_param $testname $jobid_var_old
22423         jobid_var_new=$($LCTL get_param -n $testname)
22424         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22425                 error "failed to reset $testname"
22426 }
22427 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22428
22429 test_402() {
22430         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22431         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22432                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22433         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22434                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22435                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22436         remote_mds_nodsh && skip "remote MDS with nodsh"
22437
22438         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22439 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22440         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22441         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22442                 echo "Touch failed - OK"
22443 }
22444 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22445
22446 test_403() {
22447         local file1=$DIR/$tfile.1
22448         local file2=$DIR/$tfile.2
22449         local tfile=$TMP/$tfile
22450
22451         rm -f $file1 $file2 $tfile
22452
22453         touch $file1
22454         ln $file1 $file2
22455
22456         # 30 sec OBD_TIMEOUT in ll_getattr()
22457         # right before populating st_nlink
22458         $LCTL set_param fail_loc=0x80001409
22459         stat -c %h $file1 > $tfile &
22460
22461         # create an alias, drop all locks and reclaim the dentry
22462         < $file2
22463         cancel_lru_locks mdc
22464         cancel_lru_locks osc
22465         sysctl -w vm.drop_caches=2
22466
22467         wait
22468
22469         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22470
22471         rm -f $tfile $file1 $file2
22472 }
22473 run_test 403 "i_nlink should not drop to zero due to aliasing"
22474
22475 test_404() { # LU-6601
22476         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22477                 skip "Need server version newer than 2.8.52"
22478         remote_mds_nodsh && skip "remote MDS with nodsh"
22479
22480         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22481                 awk '/osp .*-osc-MDT/ { print $4}')
22482
22483         local osp
22484         for osp in $mosps; do
22485                 echo "Deactivate: " $osp
22486                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22487                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22488                         awk -vp=$osp '$4 == p { print $2 }')
22489                 [ $stat = IN ] || {
22490                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22491                         error "deactivate error"
22492                 }
22493                 echo "Activate: " $osp
22494                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22495                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22496                         awk -vp=$osp '$4 == p { print $2 }')
22497                 [ $stat = UP ] || {
22498                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22499                         error "activate error"
22500                 }
22501         done
22502 }
22503 run_test 404 "validate manual {de}activated works properly for OSPs"
22504
22505 test_405() {
22506         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22507         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22508                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22509                         skip "Layout swap lock is not supported"
22510
22511         check_swap_layouts_support
22512         check_swap_layout_no_dom $DIR
22513
22514         test_mkdir $DIR/$tdir
22515         swap_lock_test -d $DIR/$tdir ||
22516                 error "One layout swap locked test failed"
22517 }
22518 run_test 405 "Various layout swap lock tests"
22519
22520 test_406() {
22521         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22522         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22523         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22525         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22526                 skip "Need MDS version at least 2.8.50"
22527
22528         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22529         local test_pool=$TESTNAME
22530
22531         pool_add $test_pool || error "pool_add failed"
22532         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22533                 error "pool_add_targets failed"
22534
22535         save_layout_restore_at_exit $MOUNT
22536
22537         # parent set default stripe count only, child will stripe from both
22538         # parent and fs default
22539         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22540                 error "setstripe $MOUNT failed"
22541         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22542         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22543         for i in $(seq 10); do
22544                 local f=$DIR/$tdir/$tfile.$i
22545                 touch $f || error "touch failed"
22546                 local count=$($LFS getstripe -c $f)
22547                 [ $count -eq $OSTCOUNT ] ||
22548                         error "$f stripe count $count != $OSTCOUNT"
22549                 local offset=$($LFS getstripe -i $f)
22550                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22551                 local size=$($LFS getstripe -S $f)
22552                 [ $size -eq $((def_stripe_size * 2)) ] ||
22553                         error "$f stripe size $size != $((def_stripe_size * 2))"
22554                 local pool=$($LFS getstripe -p $f)
22555                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22556         done
22557
22558         # change fs default striping, delete parent default striping, now child
22559         # will stripe from new fs default striping only
22560         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22561                 error "change $MOUNT default stripe failed"
22562         $LFS setstripe -c 0 $DIR/$tdir ||
22563                 error "delete $tdir default stripe failed"
22564         for i in $(seq 11 20); do
22565                 local f=$DIR/$tdir/$tfile.$i
22566                 touch $f || error "touch $f failed"
22567                 local count=$($LFS getstripe -c $f)
22568                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22569                 local offset=$($LFS getstripe -i $f)
22570                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22571                 local size=$($LFS getstripe -S $f)
22572                 [ $size -eq $def_stripe_size ] ||
22573                         error "$f stripe size $size != $def_stripe_size"
22574                 local pool=$($LFS getstripe -p $f)
22575                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22576         done
22577
22578         unlinkmany $DIR/$tdir/$tfile. 1 20
22579
22580         local f=$DIR/$tdir/$tfile
22581         pool_remove_all_targets $test_pool $f
22582         pool_remove $test_pool $f
22583 }
22584 run_test 406 "DNE support fs default striping"
22585
22586 test_407() {
22587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22588         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22589                 skip "Need MDS version at least 2.8.55"
22590         remote_mds_nodsh && skip "remote MDS with nodsh"
22591
22592         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22593                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22594         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22595                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22596         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22597
22598         #define OBD_FAIL_DT_TXN_STOP    0x2019
22599         for idx in $(seq $MDSCOUNT); do
22600                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22601         done
22602         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22603         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22604                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22605         true
22606 }
22607 run_test 407 "transaction fail should cause operation fail"
22608
22609 test_408() {
22610         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22611
22612         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22613         lctl set_param fail_loc=0x8000040a
22614         # let ll_prepare_partial_page() fail
22615         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22616
22617         rm -f $DIR/$tfile
22618
22619         # create at least 100 unused inodes so that
22620         # shrink_icache_memory(0) should not return 0
22621         touch $DIR/$tfile-{0..100}
22622         rm -f $DIR/$tfile-{0..100}
22623         sync
22624
22625         echo 2 > /proc/sys/vm/drop_caches
22626 }
22627 run_test 408 "drop_caches should not hang due to page leaks"
22628
22629 test_409()
22630 {
22631         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22632
22633         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22634         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22635         touch $DIR/$tdir/guard || error "(2) Fail to create"
22636
22637         local PREFIX=$(str_repeat 'A' 128)
22638         echo "Create 1K hard links start at $(date)"
22639         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22640                 error "(3) Fail to hard link"
22641
22642         echo "Links count should be right although linkEA overflow"
22643         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22644         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22645         [ $linkcount -eq 1001 ] ||
22646                 error "(5) Unexpected hard links count: $linkcount"
22647
22648         echo "List all links start at $(date)"
22649         ls -l $DIR/$tdir/foo > /dev/null ||
22650                 error "(6) Fail to list $DIR/$tdir/foo"
22651
22652         echo "Unlink hard links start at $(date)"
22653         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22654                 error "(7) Fail to unlink"
22655         echo "Unlink hard links finished at $(date)"
22656 }
22657 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22658
22659 test_410()
22660 {
22661         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22662                 skip "Need client version at least 2.9.59"
22663         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22664                 skip "Need MODULES build"
22665
22666         # Create a file, and stat it from the kernel
22667         local testfile=$DIR/$tfile
22668         touch $testfile
22669
22670         local run_id=$RANDOM
22671         local my_ino=$(stat --format "%i" $testfile)
22672
22673         # Try to insert the module. This will always fail as the
22674         # module is designed to not be inserted.
22675         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22676             &> /dev/null
22677
22678         # Anything but success is a test failure
22679         dmesg | grep -q \
22680             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22681             error "no inode match"
22682 }
22683 run_test 410 "Test inode number returned from kernel thread"
22684
22685 cleanup_test411_cgroup() {
22686         trap 0
22687         rmdir "$1"
22688 }
22689
22690 test_411() {
22691         local cg_basedir=/sys/fs/cgroup/memory
22692         # LU-9966
22693         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22694                 skip "no setup for cgroup"
22695
22696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22697                 error "test file creation failed"
22698         cancel_lru_locks osc
22699
22700         # Create a very small memory cgroup to force a slab allocation error
22701         local cgdir=$cg_basedir/osc_slab_alloc
22702         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22703         trap "cleanup_test411_cgroup $cgdir" EXIT
22704         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22705         echo 1M > $cgdir/memory.limit_in_bytes
22706
22707         # Should not LBUG, just be killed by oom-killer
22708         # dd will return 0 even allocation failure in some environment.
22709         # So don't check return value
22710         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22711         cleanup_test411_cgroup $cgdir
22712
22713         return 0
22714 }
22715 run_test 411 "Slab allocation error with cgroup does not LBUG"
22716
22717 test_412() {
22718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22719         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22720                 skip "Need server version at least 2.10.55"
22721         fi
22722
22723         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22724                 error "mkdir failed"
22725         $LFS getdirstripe $DIR/$tdir
22726         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22727         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22728                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22729         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22730         [ $stripe_count -eq 2 ] ||
22731                 error "expect 2 get $stripe_count"
22732 }
22733 run_test 412 "mkdir on specific MDTs"
22734
22735 test_qos_mkdir() {
22736         local mkdir_cmd=$1
22737         local stripe_count=$2
22738         local mdts=$(comma_list $(mdts_nodes))
22739
22740         local testdir
22741         local lmv_qos_prio_free
22742         local lmv_qos_threshold_rr
22743         local lmv_qos_maxage
22744         local lod_qos_prio_free
22745         local lod_qos_threshold_rr
22746         local lod_qos_maxage
22747         local count
22748         local i
22749
22750         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22751         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22752         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22753                 head -n1)
22754         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22755         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22756         stack_trap "$LCTL set_param \
22757                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22758         stack_trap "$LCTL set_param \
22759                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22760         stack_trap "$LCTL set_param \
22761                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22762
22763         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22764                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22765         lod_qos_prio_free=${lod_qos_prio_free%%%}
22766         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22767                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22768         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22769         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22770                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22771         stack_trap "do_nodes $mdts $LCTL set_param \
22772                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22773         stack_trap "do_nodes $mdts $LCTL set_param \
22774                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22775                 EXIT
22776         stack_trap "do_nodes $mdts $LCTL set_param \
22777                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22778
22779         echo
22780         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22781
22782         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22783         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22784
22785         testdir=$DIR/$tdir-s$stripe_count/rr
22786
22787         for i in $(seq $((100 * MDSCOUNT))); do
22788                 eval $mkdir_cmd $testdir/subdir$i ||
22789                         error "$mkdir_cmd subdir$i failed"
22790         done
22791
22792         for i in $(seq $MDSCOUNT); do
22793                 count=$($LFS getdirstripe -i $testdir/* |
22794                                 grep ^$((i - 1))$ | wc -l)
22795                 echo "$count directories created on MDT$((i - 1))"
22796                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22797
22798                 if [ $stripe_count -gt 1 ]; then
22799                         count=$($LFS getdirstripe $testdir/* |
22800                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22801                         echo "$count stripes created on MDT$((i - 1))"
22802                         # deviation should < 5% of average
22803                         [ $count -lt $((95 * stripe_count)) ] ||
22804                         [ $count -gt $((105 * stripe_count)) ] &&
22805                                 error "stripes are not evenly distributed"
22806                 fi
22807         done
22808
22809         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22810         do_nodes $mdts $LCTL set_param \
22811                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22812
22813         echo
22814         echo "Check for uneven MDTs: "
22815
22816         local ffree
22817         local bavail
22818         local max
22819         local min
22820         local max_index
22821         local min_index
22822         local tmp
22823
22824         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22825         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22826         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22827
22828         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22829         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22830         max_index=0
22831         min_index=0
22832         for ((i = 1; i < ${#ffree[@]}; i++)); do
22833                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22834                 if [ $tmp -gt $max ]; then
22835                         max=$tmp
22836                         max_index=$i
22837                 fi
22838                 if [ $tmp -lt $min ]; then
22839                         min=$tmp
22840                         min_index=$i
22841                 fi
22842         done
22843
22844         [ ${ffree[min_index]} -eq 0 ] &&
22845                 skip "no free files in MDT$min_index"
22846         [ ${ffree[min_index]} -gt 100000000 ] &&
22847                 skip "too much free files in MDT$min_index"
22848
22849         # Check if we need to generate uneven MDTs
22850         local threshold=50
22851         local diff=$(((max - min) * 100 / min))
22852         local value="$(generate_string 1024)"
22853
22854         while [ $diff -lt $threshold ]; do
22855                 # generate uneven MDTs, create till $threshold% diff
22856                 echo -n "weight diff=$diff% must be > $threshold% ..."
22857                 count=$((${ffree[min_index]} / 10))
22858                 # 50 sec per 10000 files in vm
22859                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22860                         skip "$count files to create"
22861                 echo "Fill MDT$min_index with $count files"
22862                 [ -d $DIR/$tdir-MDT$min_index ] ||
22863                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22864                         error "mkdir $tdir-MDT$min_index failed"
22865                 for i in $(seq $count); do
22866                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22867                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22868                                 error "create f$j_$i failed"
22869                         setfattr -n user.413b -v $value \
22870                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22871                                 error "setfattr f$j_$i failed"
22872                 done
22873
22874                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22875                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22876                 max=$(((${ffree[max_index]} >> 8) * \
22877                         (${bavail[max_index]} * bsize >> 16)))
22878                 min=$(((${ffree[min_index]} >> 8) * \
22879                         (${bavail[min_index]} * bsize >> 16)))
22880                 diff=$(((max - min) * 100 / min))
22881         done
22882
22883         echo "MDT filesfree available: ${ffree[@]}"
22884         echo "MDT blocks available: ${bavail[@]}"
22885         echo "weight diff=$diff%"
22886
22887         echo
22888         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22889
22890         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22891         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22892         # decrease statfs age, so that it can be updated in time
22893         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22894         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22895
22896         sleep 1
22897
22898         testdir=$DIR/$tdir-s$stripe_count/qos
22899
22900         for i in $(seq $((100 * MDSCOUNT))); do
22901                 eval $mkdir_cmd $testdir/subdir$i ||
22902                         error "$mkdir_cmd subdir$i failed"
22903         done
22904
22905         for i in $(seq $MDSCOUNT); do
22906                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22907                         wc -l)
22908                 echo "$count directories created on MDT$((i - 1))"
22909
22910                 if [ $stripe_count -gt 1 ]; then
22911                         count=$($LFS getdirstripe $testdir/* |
22912                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22913                         echo "$count stripes created on MDT$((i - 1))"
22914                 fi
22915         done
22916
22917         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22918         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22919
22920         # D-value should > 10% of averge
22921         [ $((max - min)) -lt 10 ] &&
22922                 error "subdirs shouldn't be evenly distributed"
22923
22924         # ditto
22925         if [ $stripe_count -gt 1 ]; then
22926                 max=$($LFS getdirstripe $testdir/* |
22927                         grep -P "^\s+$max_index\t" | wc -l)
22928                 min=$($LFS getdirstripe $testdir/* |
22929                         grep -P "^\s+$min_index\t" | wc -l)
22930                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22931                         error "stripes shouldn't be evenly distributed"|| true
22932         fi
22933 }
22934
22935 test_413a() {
22936         [ $MDSCOUNT -lt 2 ] &&
22937                 skip "We need at least 2 MDTs for this test"
22938
22939         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22940                 skip "Need server version at least 2.12.52"
22941
22942         local stripe_count
22943
22944         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22945                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22946                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22947                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22948                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22949         done
22950 }
22951 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22952
22953 test_413b() {
22954         [ $MDSCOUNT -lt 2 ] &&
22955                 skip "We need at least 2 MDTs for this test"
22956
22957         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22958                 skip "Need server version at least 2.12.52"
22959
22960         local stripe_count
22961
22962         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22963                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22964                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22965                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22966                 $LFS setdirstripe -D -c $stripe_count \
22967                         $DIR/$tdir-s$stripe_count/rr ||
22968                         error "setdirstripe failed"
22969                 $LFS setdirstripe -D -c $stripe_count \
22970                         $DIR/$tdir-s$stripe_count/qos ||
22971                         error "setdirstripe failed"
22972                 test_qos_mkdir "mkdir" $stripe_count
22973         done
22974 }
22975 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22976
22977 test_414() {
22978 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22979         $LCTL set_param fail_loc=0x80000521
22980         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22981         rm -f $DIR/$tfile
22982 }
22983 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22984
22985 test_415() {
22986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22987         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22988                 skip "Need server version at least 2.11.52"
22989
22990         # LU-11102
22991         local total
22992         local setattr_pid
22993         local start_time
22994         local end_time
22995         local duration
22996
22997         total=500
22998         # this test may be slow on ZFS
22999         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23000
23001         # though this test is designed for striped directory, let's test normal
23002         # directory too since lock is always saved as CoS lock.
23003         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23004         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23005
23006         (
23007                 while true; do
23008                         touch $DIR/$tdir
23009                 done
23010         ) &
23011         setattr_pid=$!
23012
23013         start_time=$(date +%s)
23014         for i in $(seq $total); do
23015                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23016                         > /dev/null
23017         done
23018         end_time=$(date +%s)
23019         duration=$((end_time - start_time))
23020
23021         kill -9 $setattr_pid
23022
23023         echo "rename $total files took $duration sec"
23024         [ $duration -lt 100 ] || error "rename took $duration sec"
23025 }
23026 run_test 415 "lock revoke is not missing"
23027
23028 test_416() {
23029         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23030                 skip "Need server version at least 2.11.55"
23031
23032         # define OBD_FAIL_OSD_TXN_START    0x19a
23033         do_facet mds1 lctl set_param fail_loc=0x19a
23034
23035         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23036
23037         true
23038 }
23039 run_test 416 "transaction start failure won't cause system hung"
23040
23041 cleanup_417() {
23042         trap 0
23043         do_nodes $(comma_list $(mdts_nodes)) \
23044                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23045         do_nodes $(comma_list $(mdts_nodes)) \
23046                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23047         do_nodes $(comma_list $(mdts_nodes)) \
23048                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23049 }
23050
23051 test_417() {
23052         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23053         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23054                 skip "Need MDS version at least 2.11.56"
23055
23056         trap cleanup_417 RETURN EXIT
23057
23058         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23059         do_nodes $(comma_list $(mdts_nodes)) \
23060                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23061         $LFS migrate -m 0 $DIR/$tdir.1 &&
23062                 error "migrate dir $tdir.1 should fail"
23063
23064         do_nodes $(comma_list $(mdts_nodes)) \
23065                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23066         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23067                 error "create remote dir $tdir.2 should fail"
23068
23069         do_nodes $(comma_list $(mdts_nodes)) \
23070                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23071         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23072                 error "create striped dir $tdir.3 should fail"
23073         true
23074 }
23075 run_test 417 "disable remote dir, striped dir and dir migration"
23076
23077 # Checks that the outputs of df [-i] and lfs df [-i] match
23078 #
23079 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23080 check_lfs_df() {
23081         local dir=$2
23082         local inodes
23083         local df_out
23084         local lfs_df_out
23085         local count
23086         local passed=false
23087
23088         # blocks or inodes
23089         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23090
23091         for count in {1..100}; do
23092                 cancel_lru_locks
23093                 sync; sleep 0.2
23094
23095                 # read the lines of interest
23096                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23097                         error "df $inodes $dir | tail -n +2 failed"
23098                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23099                         error "lfs df $inodes $dir | grep summary: failed"
23100
23101                 # skip first substrings of each output as they are different
23102                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23103                 # compare the two outputs
23104                 passed=true
23105                 for i in {1..5}; do
23106                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23107                 done
23108                 $passed && break
23109         done
23110
23111         if ! $passed; then
23112                 df -P $inodes $dir
23113                 echo
23114                 lfs df $inodes $dir
23115                 error "df and lfs df $1 output mismatch: "      \
23116                       "df ${inodes}: ${df_out[*]}, "            \
23117                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23118         fi
23119 }
23120
23121 test_418() {
23122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23123
23124         local dir=$DIR/$tdir
23125         local numfiles=$((RANDOM % 4096 + 2))
23126         local numblocks=$((RANDOM % 256 + 1))
23127
23128         wait_delete_completed
23129         test_mkdir $dir
23130
23131         # check block output
23132         check_lfs_df blocks $dir
23133         # check inode output
23134         check_lfs_df inodes $dir
23135
23136         # create a single file and retest
23137         echo "Creating a single file and testing"
23138         createmany -o $dir/$tfile- 1 &>/dev/null ||
23139                 error "creating 1 file in $dir failed"
23140         check_lfs_df blocks $dir
23141         check_lfs_df inodes $dir
23142
23143         # create a random number of files
23144         echo "Creating $((numfiles - 1)) files and testing"
23145         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23146                 error "creating $((numfiles - 1)) files in $dir failed"
23147
23148         # write a random number of blocks to the first test file
23149         echo "Writing $numblocks 4K blocks and testing"
23150         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23151                 count=$numblocks &>/dev/null ||
23152                 error "dd to $dir/${tfile}-0 failed"
23153
23154         # retest
23155         check_lfs_df blocks $dir
23156         check_lfs_df inodes $dir
23157
23158         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23159                 error "unlinking $numfiles files in $dir failed"
23160 }
23161 run_test 418 "df and lfs df outputs match"
23162
23163 test_419()
23164 {
23165         local dir=$DIR/$tdir
23166
23167         mkdir -p $dir
23168         touch $dir/file
23169
23170         cancel_lru_locks mdc
23171
23172         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23173         $LCTL set_param fail_loc=0x1410
23174         cat $dir/file
23175         $LCTL set_param fail_loc=0
23176         rm -rf $dir
23177 }
23178 run_test 419 "Verify open file by name doesn't crash kernel"
23179
23180 test_420()
23181 {
23182         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23183                 skip "Need MDS version at least 2.12.53"
23184
23185         local SAVE_UMASK=$(umask)
23186         local dir=$DIR/$tdir
23187         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23188
23189         mkdir -p $dir
23190         umask 0000
23191         mkdir -m03777 $dir/testdir
23192         ls -dn $dir/testdir
23193         # Need to remove trailing '.' when SELinux is enabled
23194         local dirperms=$(ls -dn $dir/testdir |
23195                          awk '{ sub(/\.$/, "", $1); print $1}')
23196         [ $dirperms == "drwxrwsrwt" ] ||
23197                 error "incorrect perms on $dir/testdir"
23198
23199         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23200                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23201         ls -n $dir/testdir/testfile
23202         local fileperms=$(ls -n $dir/testdir/testfile |
23203                           awk '{ sub(/\.$/, "", $1); print $1}')
23204         [ $fileperms == "-rwxr-xr-x" ] ||
23205                 error "incorrect perms on $dir/testdir/testfile"
23206
23207         umask $SAVE_UMASK
23208 }
23209 run_test 420 "clear SGID bit on non-directories for non-members"
23210
23211 test_421a() {
23212         local cnt
23213         local fid1
23214         local fid2
23215
23216         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23217                 skip "Need MDS version at least 2.12.54"
23218
23219         test_mkdir $DIR/$tdir
23220         createmany -o $DIR/$tdir/f 3
23221         cnt=$(ls -1 $DIR/$tdir | wc -l)
23222         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23223
23224         fid1=$(lfs path2fid $DIR/$tdir/f1)
23225         fid2=$(lfs path2fid $DIR/$tdir/f2)
23226         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23227
23228         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23229         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23230
23231         cnt=$(ls -1 $DIR/$tdir | wc -l)
23232         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23233
23234         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23235         createmany -o $DIR/$tdir/f 3
23236         cnt=$(ls -1 $DIR/$tdir | wc -l)
23237         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23238
23239         fid1=$(lfs path2fid $DIR/$tdir/f1)
23240         fid2=$(lfs path2fid $DIR/$tdir/f2)
23241         echo "remove using fsname $FSNAME"
23242         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23243
23244         cnt=$(ls -1 $DIR/$tdir | wc -l)
23245         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23246 }
23247 run_test 421a "simple rm by fid"
23248
23249 test_421b() {
23250         local cnt
23251         local FID1
23252         local FID2
23253
23254         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23255                 skip "Need MDS version at least 2.12.54"
23256
23257         test_mkdir $DIR/$tdir
23258         createmany -o $DIR/$tdir/f 3
23259         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23260         MULTIPID=$!
23261
23262         FID1=$(lfs path2fid $DIR/$tdir/f1)
23263         FID2=$(lfs path2fid $DIR/$tdir/f2)
23264         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23265
23266         kill -USR1 $MULTIPID
23267         wait
23268
23269         cnt=$(ls $DIR/$tdir | wc -l)
23270         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23271 }
23272 run_test 421b "rm by fid on open file"
23273
23274 test_421c() {
23275         local cnt
23276         local FIDS
23277
23278         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23279                 skip "Need MDS version at least 2.12.54"
23280
23281         test_mkdir $DIR/$tdir
23282         createmany -o $DIR/$tdir/f 3
23283         touch $DIR/$tdir/$tfile
23284         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23285         cnt=$(ls -1 $DIR/$tdir | wc -l)
23286         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23287
23288         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23289         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23290
23291         cnt=$(ls $DIR/$tdir | wc -l)
23292         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23293 }
23294 run_test 421c "rm by fid against hardlinked files"
23295
23296 test_421d() {
23297         local cnt
23298         local FIDS
23299
23300         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23301                 skip "Need MDS version at least 2.12.54"
23302
23303         test_mkdir $DIR/$tdir
23304         createmany -o $DIR/$tdir/f 4097
23305         cnt=$(ls -1 $DIR/$tdir | wc -l)
23306         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23307
23308         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23309         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23310
23311         cnt=$(ls $DIR/$tdir | wc -l)
23312         rm -rf $DIR/$tdir
23313         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23314 }
23315 run_test 421d "rmfid en masse"
23316
23317 test_421e() {
23318         local cnt
23319         local FID
23320
23321         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23322         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23323                 skip "Need MDS version at least 2.12.54"
23324
23325         mkdir -p $DIR/$tdir
23326         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23327         createmany -o $DIR/$tdir/striped_dir/f 512
23328         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23329         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23330
23331         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23332                 sed "s/[/][^:]*://g")
23333         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23334
23335         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23336         rm -rf $DIR/$tdir
23337         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23338 }
23339 run_test 421e "rmfid in DNE"
23340
23341 test_421f() {
23342         local cnt
23343         local FID
23344
23345         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23346                 skip "Need MDS version at least 2.12.54"
23347
23348         test_mkdir $DIR/$tdir
23349         touch $DIR/$tdir/f
23350         cnt=$(ls -1 $DIR/$tdir | wc -l)
23351         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23352
23353         FID=$(lfs path2fid $DIR/$tdir/f)
23354         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23355         # rmfid should fail
23356         cnt=$(ls -1 $DIR/$tdir | wc -l)
23357         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23358
23359         chmod a+rw $DIR/$tdir
23360         ls -la $DIR/$tdir
23361         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23362         # rmfid should fail
23363         cnt=$(ls -1 $DIR/$tdir | wc -l)
23364         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23365
23366         rm -f $DIR/$tdir/f
23367         $RUNAS touch $DIR/$tdir/f
23368         FID=$(lfs path2fid $DIR/$tdir/f)
23369         echo "rmfid as root"
23370         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23371         cnt=$(ls -1 $DIR/$tdir | wc -l)
23372         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23373
23374         rm -f $DIR/$tdir/f
23375         $RUNAS touch $DIR/$tdir/f
23376         cnt=$(ls -1 $DIR/$tdir | wc -l)
23377         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23378         FID=$(lfs path2fid $DIR/$tdir/f)
23379         # rmfid w/o user_fid2path mount option should fail
23380         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23381         cnt=$(ls -1 $DIR/$tdir | wc -l)
23382         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23383
23384         umount_client $MOUNT || error "failed to umount client"
23385         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23386                 error "failed to mount client'"
23387
23388         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23389         # rmfid should succeed
23390         cnt=$(ls -1 $DIR/$tdir | wc -l)
23391         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23392
23393         # rmfid shouldn't allow to remove files due to dir's permission
23394         chmod a+rwx $DIR/$tdir
23395         touch $DIR/$tdir/f
23396         ls -la $DIR/$tdir
23397         FID=$(lfs path2fid $DIR/$tdir/f)
23398         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23399
23400         umount_client $MOUNT || error "failed to umount client"
23401         mount_client $MOUNT "$MOUNT_OPTS" ||
23402                 error "failed to mount client'"
23403
23404 }
23405 run_test 421f "rmfid checks permissions"
23406
23407 test_421g() {
23408         local cnt
23409         local FIDS
23410
23411         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23412         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23413                 skip "Need MDS version at least 2.12.54"
23414
23415         mkdir -p $DIR/$tdir
23416         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23417         createmany -o $DIR/$tdir/striped_dir/f 512
23418         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23419         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23420
23421         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23422                 sed "s/[/][^:]*://g")
23423
23424         rm -f $DIR/$tdir/striped_dir/f1*
23425         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23426         removed=$((512 - cnt))
23427
23428         # few files have been just removed, so we expect
23429         # rmfid to fail on their fids
23430         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23431         [ $removed != $errors ] && error "$errors != $removed"
23432
23433         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23434         rm -rf $DIR/$tdir
23435         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23436 }
23437 run_test 421g "rmfid to return errors properly"
23438
23439 test_422() {
23440         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23441         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23442         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23443         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23444         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23445
23446         local amc=$(at_max_get client)
23447         local amo=$(at_max_get mds1)
23448         local timeout=`lctl get_param -n timeout`
23449
23450         at_max_set 0 client
23451         at_max_set 0 mds1
23452
23453 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23454         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23455                         fail_val=$(((2*timeout + 10)*1000))
23456         touch $DIR/$tdir/d3/file &
23457         sleep 2
23458 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23459         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23460                         fail_val=$((2*timeout + 5))
23461         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23462         local pid=$!
23463         sleep 1
23464         kill -9 $pid
23465         sleep $((2 * timeout))
23466         echo kill $pid
23467         kill -9 $pid
23468         lctl mark touch
23469         touch $DIR/$tdir/d2/file3
23470         touch $DIR/$tdir/d2/file4
23471         touch $DIR/$tdir/d2/file5
23472
23473         wait
23474         at_max_set $amc client
23475         at_max_set $amo mds1
23476
23477         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23478         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23479                 error "Watchdog is always throttled"
23480 }
23481 run_test 422 "kill a process with RPC in progress"
23482
23483 stat_test() {
23484     df -h $MOUNT &
23485     df -h $MOUNT &
23486     df -h $MOUNT &
23487     df -h $MOUNT &
23488     df -h $MOUNT &
23489     df -h $MOUNT &
23490 }
23491
23492 test_423() {
23493     local _stats
23494     # ensure statfs cache is expired
23495     sleep 2;
23496
23497     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23498     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23499
23500     return 0
23501 }
23502 run_test 423 "statfs should return a right data"
23503
23504 test_424() {
23505 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23506         $LCTL set_param fail_loc=0x80000522
23507         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23508         rm -f $DIR/$tfile
23509 }
23510 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23511
23512 test_425() {
23513         test_mkdir -c -1 $DIR/$tdir
23514         $LFS setstripe -c -1 $DIR/$tdir
23515
23516         lru_resize_disable "" 100
23517         stack_trap "lru_resize_enable" EXIT
23518
23519         sleep 5
23520
23521         for i in $(seq $((MDSCOUNT * 125))); do
23522                 local t=$DIR/$tdir/$tfile_$i
23523
23524                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23525                         error_noexit "Create file $t"
23526         done
23527         stack_trap "rm -rf $DIR/$tdir" EXIT
23528
23529         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23530                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23531                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23532
23533                 [ $lock_count -le $lru_size ] ||
23534                         error "osc lock count $lock_count > lru size $lru_size"
23535         done
23536
23537         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23538                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23539                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23540
23541                 [ $lock_count -le $lru_size ] ||
23542                         error "mdc lock count $lock_count > lru size $lru_size"
23543         done
23544 }
23545 run_test 425 "lock count should not exceed lru size"
23546
23547 test_426() {
23548         splice-test -r $DIR/$tfile
23549         splice-test -rd $DIR/$tfile
23550         splice-test $DIR/$tfile
23551         splice-test -d $DIR/$tfile
23552 }
23553 run_test 426 "splice test on Lustre"
23554
23555 prep_801() {
23556         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23557         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23558                 skip "Need server version at least 2.9.55"
23559
23560         start_full_debug_logging
23561 }
23562
23563 post_801() {
23564         stop_full_debug_logging
23565 }
23566
23567 barrier_stat() {
23568         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23569                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23570                            awk '/The barrier for/ { print $7 }')
23571                 echo $st
23572         else
23573                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23574                 echo \'$st\'
23575         fi
23576 }
23577
23578 barrier_expired() {
23579         local expired
23580
23581         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23582                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23583                           awk '/will be expired/ { print $7 }')
23584         else
23585                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23586         fi
23587
23588         echo $expired
23589 }
23590
23591 test_801a() {
23592         prep_801
23593
23594         echo "Start barrier_freeze at: $(date)"
23595         #define OBD_FAIL_BARRIER_DELAY          0x2202
23596         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23597         # Do not reduce barrier time - See LU-11873
23598         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23599
23600         sleep 2
23601         local b_status=$(barrier_stat)
23602         echo "Got barrier status at: $(date)"
23603         [ "$b_status" = "'freezing_p1'" ] ||
23604                 error "(1) unexpected barrier status $b_status"
23605
23606         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23607         wait
23608         b_status=$(barrier_stat)
23609         [ "$b_status" = "'frozen'" ] ||
23610                 error "(2) unexpected barrier status $b_status"
23611
23612         local expired=$(barrier_expired)
23613         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23614         sleep $((expired + 3))
23615
23616         b_status=$(barrier_stat)
23617         [ "$b_status" = "'expired'" ] ||
23618                 error "(3) unexpected barrier status $b_status"
23619
23620         # Do not reduce barrier time - See LU-11873
23621         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23622                 error "(4) fail to freeze barrier"
23623
23624         b_status=$(barrier_stat)
23625         [ "$b_status" = "'frozen'" ] ||
23626                 error "(5) unexpected barrier status $b_status"
23627
23628         echo "Start barrier_thaw at: $(date)"
23629         #define OBD_FAIL_BARRIER_DELAY          0x2202
23630         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23631         do_facet mgs $LCTL barrier_thaw $FSNAME &
23632
23633         sleep 2
23634         b_status=$(barrier_stat)
23635         echo "Got barrier status at: $(date)"
23636         [ "$b_status" = "'thawing'" ] ||
23637                 error "(6) unexpected barrier status $b_status"
23638
23639         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23640         wait
23641         b_status=$(barrier_stat)
23642         [ "$b_status" = "'thawed'" ] ||
23643                 error "(7) unexpected barrier status $b_status"
23644
23645         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23646         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23647         do_facet mgs $LCTL barrier_freeze $FSNAME
23648
23649         b_status=$(barrier_stat)
23650         [ "$b_status" = "'failed'" ] ||
23651                 error "(8) unexpected barrier status $b_status"
23652
23653         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23654         do_facet mgs $LCTL barrier_thaw $FSNAME
23655
23656         post_801
23657 }
23658 run_test 801a "write barrier user interfaces and stat machine"
23659
23660 test_801b() {
23661         prep_801
23662
23663         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23664         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23665         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23666         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23667         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23668
23669         cancel_lru_locks mdc
23670
23671         # 180 seconds should be long enough
23672         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23673
23674         local b_status=$(barrier_stat)
23675         [ "$b_status" = "'frozen'" ] ||
23676                 error "(6) unexpected barrier status $b_status"
23677
23678         mkdir $DIR/$tdir/d0/d10 &
23679         mkdir_pid=$!
23680
23681         touch $DIR/$tdir/d1/f13 &
23682         touch_pid=$!
23683
23684         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23685         ln_pid=$!
23686
23687         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23688         mv_pid=$!
23689
23690         rm -f $DIR/$tdir/d4/f12 &
23691         rm_pid=$!
23692
23693         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23694
23695         # To guarantee taht the 'stat' is not blocked
23696         b_status=$(barrier_stat)
23697         [ "$b_status" = "'frozen'" ] ||
23698                 error "(8) unexpected barrier status $b_status"
23699
23700         # let above commands to run at background
23701         sleep 5
23702
23703         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23704         ps -p $touch_pid || error "(10) touch should be blocked"
23705         ps -p $ln_pid || error "(11) link should be blocked"
23706         ps -p $mv_pid || error "(12) rename should be blocked"
23707         ps -p $rm_pid || error "(13) unlink should be blocked"
23708
23709         b_status=$(barrier_stat)
23710         [ "$b_status" = "'frozen'" ] ||
23711                 error "(14) unexpected barrier status $b_status"
23712
23713         do_facet mgs $LCTL barrier_thaw $FSNAME
23714         b_status=$(barrier_stat)
23715         [ "$b_status" = "'thawed'" ] ||
23716                 error "(15) unexpected barrier status $b_status"
23717
23718         wait $mkdir_pid || error "(16) mkdir should succeed"
23719         wait $touch_pid || error "(17) touch should succeed"
23720         wait $ln_pid || error "(18) link should succeed"
23721         wait $mv_pid || error "(19) rename should succeed"
23722         wait $rm_pid || error "(20) unlink should succeed"
23723
23724         post_801
23725 }
23726 run_test 801b "modification will be blocked by write barrier"
23727
23728 test_801c() {
23729         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23730
23731         prep_801
23732
23733         stop mds2 || error "(1) Fail to stop mds2"
23734
23735         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23736
23737         local b_status=$(barrier_stat)
23738         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23739                 do_facet mgs $LCTL barrier_thaw $FSNAME
23740                 error "(2) unexpected barrier status $b_status"
23741         }
23742
23743         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23744                 error "(3) Fail to rescan barrier bitmap"
23745
23746         # Do not reduce barrier time - See LU-11873
23747         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23748
23749         b_status=$(barrier_stat)
23750         [ "$b_status" = "'frozen'" ] ||
23751                 error "(4) unexpected barrier status $b_status"
23752
23753         do_facet mgs $LCTL barrier_thaw $FSNAME
23754         b_status=$(barrier_stat)
23755         [ "$b_status" = "'thawed'" ] ||
23756                 error "(5) unexpected barrier status $b_status"
23757
23758         local devname=$(mdsdevname 2)
23759
23760         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23761
23762         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23763                 error "(7) Fail to rescan barrier bitmap"
23764
23765         post_801
23766 }
23767 run_test 801c "rescan barrier bitmap"
23768
23769 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23770 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23771 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23772 saved_MOUNT_OPTS=$MOUNT_OPTS
23773
23774 cleanup_802a() {
23775         trap 0
23776
23777         stopall
23778         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23779         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23780         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23781         MOUNT_OPTS=$saved_MOUNT_OPTS
23782         setupall
23783 }
23784
23785 test_802a() {
23786         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23787         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23788         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23789                 skip "Need server version at least 2.9.55"
23790
23791         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23792
23793         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23794
23795         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23796                 error "(2) Fail to copy"
23797
23798         trap cleanup_802a EXIT
23799
23800         # sync by force before remount as readonly
23801         sync; sync_all_data; sleep 3; sync_all_data
23802
23803         stopall
23804
23805         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23806         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23807         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23808
23809         echo "Mount the server as read only"
23810         setupall server_only || error "(3) Fail to start servers"
23811
23812         echo "Mount client without ro should fail"
23813         mount_client $MOUNT &&
23814                 error "(4) Mount client without 'ro' should fail"
23815
23816         echo "Mount client with ro should succeed"
23817         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23818         mount_client $MOUNT ||
23819                 error "(5) Mount client with 'ro' should succeed"
23820
23821         echo "Modify should be refused"
23822         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23823
23824         echo "Read should be allowed"
23825         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23826                 error "(7) Read should succeed under ro mode"
23827
23828         cleanup_802a
23829 }
23830 run_test 802a "simulate readonly device"
23831
23832 test_802b() {
23833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23834         remote_mds_nodsh && skip "remote MDS with nodsh"
23835
23836         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23837                 skip "readonly option not available"
23838
23839         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23840
23841         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23842                 error "(2) Fail to copy"
23843
23844         # write back all cached data before setting MDT to readonly
23845         cancel_lru_locks
23846         sync_all_data
23847
23848         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23849         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23850
23851         echo "Modify should be refused"
23852         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23853
23854         echo "Read should be allowed"
23855         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23856                 error "(7) Read should succeed under ro mode"
23857
23858         # disable readonly
23859         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23860 }
23861 run_test 802b "be able to set MDTs to readonly"
23862
23863 test_803a() {
23864         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23865         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23866                 skip "MDS needs to be newer than 2.10.54"
23867
23868         mkdir -p $DIR/$tdir
23869         # Create some objects on all MDTs to trigger related logs objects
23870         for idx in $(seq $MDSCOUNT); do
23871                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23872                         $DIR/$tdir/dir${idx} ||
23873                         error "Fail to create $DIR/$tdir/dir${idx}"
23874         done
23875
23876         sync; sleep 3
23877         wait_delete_completed # ensure old test cleanups are finished
23878         echo "before create:"
23879         $LFS df -i $MOUNT
23880         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23881
23882         for i in {1..10}; do
23883                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23884                         error "Fail to create $DIR/$tdir/foo$i"
23885         done
23886
23887         sync; sleep 3
23888         echo "after create:"
23889         $LFS df -i $MOUNT
23890         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23891
23892         # allow for an llog to be cleaned up during the test
23893         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23894                 error "before ($before_used) + 10 > after ($after_used)"
23895
23896         for i in {1..10}; do
23897                 rm -rf $DIR/$tdir/foo$i ||
23898                         error "Fail to remove $DIR/$tdir/foo$i"
23899         done
23900
23901         sleep 3 # avoid MDT return cached statfs
23902         wait_delete_completed
23903         echo "after unlink:"
23904         $LFS df -i $MOUNT
23905         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23906
23907         # allow for an llog to be created during the test
23908         [ $after_used -le $((before_used + 1)) ] ||
23909                 error "after ($after_used) > before ($before_used) + 1"
23910 }
23911 run_test 803a "verify agent object for remote object"
23912
23913 test_803b() {
23914         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23915         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
23916                 skip "MDS needs to be newer than 2.13.56"
23917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23918
23919         for i in $(seq 0 $((MDSCOUNT - 1))); do
23920                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
23921         done
23922
23923         local before=0
23924         local after=0
23925
23926         local tmp
23927
23928         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
23929         for i in $(seq 0 $((MDSCOUNT - 1))); do
23930                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
23931                         awk '/getattr/ { print $2 }')
23932                 before=$((before + tmp))
23933         done
23934         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
23935         for i in $(seq 0 $((MDSCOUNT - 1))); do
23936                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
23937                         awk '/getattr/ { print $2 }')
23938                 after=$((after + tmp))
23939         done
23940
23941         [ $before -eq $after ] || error "getattr count $before != $after"
23942 }
23943 run_test 803b "remote object can getattr from cache"
23944
23945 test_804() {
23946         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23947         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23948                 skip "MDS needs to be newer than 2.10.54"
23949         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23950
23951         mkdir -p $DIR/$tdir
23952         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23953                 error "Fail to create $DIR/$tdir/dir0"
23954
23955         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23956         local dev=$(mdsdevname 2)
23957
23958         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23959                 grep ${fid} || error "NOT found agent entry for dir0"
23960
23961         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23962                 error "Fail to create $DIR/$tdir/dir1"
23963
23964         touch $DIR/$tdir/dir1/foo0 ||
23965                 error "Fail to create $DIR/$tdir/dir1/foo0"
23966         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23967         local rc=0
23968
23969         for idx in $(seq $MDSCOUNT); do
23970                 dev=$(mdsdevname $idx)
23971                 do_facet mds${idx} \
23972                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23973                         grep ${fid} && rc=$idx
23974         done
23975
23976         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23977                 error "Fail to rename foo0 to foo1"
23978         if [ $rc -eq 0 ]; then
23979                 for idx in $(seq $MDSCOUNT); do
23980                         dev=$(mdsdevname $idx)
23981                         do_facet mds${idx} \
23982                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23983                         grep ${fid} && rc=$idx
23984                 done
23985         fi
23986
23987         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23988                 error "Fail to rename foo1 to foo2"
23989         if [ $rc -eq 0 ]; then
23990                 for idx in $(seq $MDSCOUNT); do
23991                         dev=$(mdsdevname $idx)
23992                         do_facet mds${idx} \
23993                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23994                         grep ${fid} && rc=$idx
23995                 done
23996         fi
23997
23998         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23999
24000         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24001                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24002         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24003                 error "Fail to rename foo2 to foo0"
24004         unlink $DIR/$tdir/dir1/foo0 ||
24005                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24006         rm -rf $DIR/$tdir/dir0 ||
24007                 error "Fail to rm $DIR/$tdir/dir0"
24008
24009         for idx in $(seq $MDSCOUNT); do
24010                 dev=$(mdsdevname $idx)
24011                 rc=0
24012
24013                 stop mds${idx}
24014                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24015                         rc=$?
24016                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24017                         error "mount mds$idx failed"
24018                 df $MOUNT > /dev/null 2>&1
24019
24020                 # e2fsck should not return error
24021                 [ $rc -eq 0 ] ||
24022                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24023         done
24024 }
24025 run_test 804 "verify agent entry for remote entry"
24026
24027 cleanup_805() {
24028         do_facet $SINGLEMDS zfs set quota=$old $fsset
24029         unlinkmany $DIR/$tdir/f- 1000000
24030         trap 0
24031 }
24032
24033 test_805() {
24034         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24035         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24036         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24037                 skip "netfree not implemented before 0.7"
24038         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24039                 skip "Need MDS version at least 2.10.57"
24040
24041         local fsset
24042         local freekb
24043         local usedkb
24044         local old
24045         local quota
24046         local pref="osd-zfs.$FSNAME-MDT0000."
24047
24048         # limit available space on MDS dataset to meet nospace issue
24049         # quickly. then ZFS 0.7.2 can use reserved space if asked
24050         # properly (using netfree flag in osd_declare_destroy()
24051         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24052         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24053                 gawk '{print $3}')
24054         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24055         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24056         let "usedkb=usedkb-freekb"
24057         let "freekb=freekb/2"
24058         if let "freekb > 5000"; then
24059                 let "freekb=5000"
24060         fi
24061         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24062         trap cleanup_805 EXIT
24063         mkdir $DIR/$tdir
24064         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24065                 error "Can't set PFL layout"
24066         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24067         rm -rf $DIR/$tdir || error "not able to remove"
24068         do_facet $SINGLEMDS zfs set quota=$old $fsset
24069         trap 0
24070 }
24071 run_test 805 "ZFS can remove from full fs"
24072
24073 # Size-on-MDS test
24074 check_lsom_data()
24075 {
24076         local file=$1
24077         local size=$($LFS getsom -s $file)
24078         local expect=$(stat -c %s $file)
24079
24080         [[ $size == $expect ]] ||
24081                 error "$file expected size: $expect, got: $size"
24082
24083         local blocks=$($LFS getsom -b $file)
24084         expect=$(stat -c %b $file)
24085         [[ $blocks == $expect ]] ||
24086                 error "$file expected blocks: $expect, got: $blocks"
24087 }
24088
24089 check_lsom_size()
24090 {
24091         local size=$($LFS getsom -s $1)
24092         local expect=$2
24093
24094         [[ $size == $expect ]] ||
24095                 error "$file expected size: $expect, got: $size"
24096 }
24097
24098 test_806() {
24099         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24100                 skip "Need MDS version at least 2.11.52"
24101
24102         local bs=1048576
24103
24104         touch $DIR/$tfile || error "touch $tfile failed"
24105
24106         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24107         save_lustre_params client "llite.*.xattr_cache" > $save
24108         lctl set_param llite.*.xattr_cache=0
24109         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24110
24111         # single-threaded write
24112         echo "Test SOM for single-threaded write"
24113         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24114                 error "write $tfile failed"
24115         check_lsom_size $DIR/$tfile $bs
24116
24117         local num=32
24118         local size=$(($num * $bs))
24119         local offset=0
24120         local i
24121
24122         echo "Test SOM for single client multi-threaded($num) write"
24123         $TRUNCATE $DIR/$tfile 0
24124         for ((i = 0; i < $num; i++)); do
24125                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24126                 local pids[$i]=$!
24127                 offset=$((offset + $bs))
24128         done
24129         for (( i=0; i < $num; i++ )); do
24130                 wait ${pids[$i]}
24131         done
24132         check_lsom_size $DIR/$tfile $size
24133
24134         $TRUNCATE $DIR/$tfile 0
24135         for ((i = 0; i < $num; i++)); do
24136                 offset=$((offset - $bs))
24137                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24138                 local pids[$i]=$!
24139         done
24140         for (( i=0; i < $num; i++ )); do
24141                 wait ${pids[$i]}
24142         done
24143         check_lsom_size $DIR/$tfile $size
24144
24145         # multi-client writes
24146         num=$(get_node_count ${CLIENTS//,/ })
24147         size=$(($num * $bs))
24148         offset=0
24149         i=0
24150
24151         echo "Test SOM for multi-client ($num) writes"
24152         $TRUNCATE $DIR/$tfile 0
24153         for client in ${CLIENTS//,/ }; do
24154                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24155                 local pids[$i]=$!
24156                 i=$((i + 1))
24157                 offset=$((offset + $bs))
24158         done
24159         for (( i=0; i < $num; i++ )); do
24160                 wait ${pids[$i]}
24161         done
24162         check_lsom_size $DIR/$tfile $offset
24163
24164         i=0
24165         $TRUNCATE $DIR/$tfile 0
24166         for client in ${CLIENTS//,/ }; do
24167                 offset=$((offset - $bs))
24168                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24169                 local pids[$i]=$!
24170                 i=$((i + 1))
24171         done
24172         for (( i=0; i < $num; i++ )); do
24173                 wait ${pids[$i]}
24174         done
24175         check_lsom_size $DIR/$tfile $size
24176
24177         # verify truncate
24178         echo "Test SOM for truncate"
24179         $TRUNCATE $DIR/$tfile 1048576
24180         check_lsom_size $DIR/$tfile 1048576
24181         $TRUNCATE $DIR/$tfile 1234
24182         check_lsom_size $DIR/$tfile 1234
24183
24184         # verify SOM blocks count
24185         echo "Verify SOM block count"
24186         $TRUNCATE $DIR/$tfile 0
24187         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24188                 error "failed to write file $tfile"
24189         check_lsom_data $DIR/$tfile
24190 }
24191 run_test 806 "Verify Lazy Size on MDS"
24192
24193 test_807() {
24194         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24195         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24196                 skip "Need MDS version at least 2.11.52"
24197
24198         # Registration step
24199         changelog_register || error "changelog_register failed"
24200         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24201         changelog_users $SINGLEMDS | grep -q $cl_user ||
24202                 error "User $cl_user not found in changelog_users"
24203
24204         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24205         save_lustre_params client "llite.*.xattr_cache" > $save
24206         lctl set_param llite.*.xattr_cache=0
24207         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24208
24209         rm -rf $DIR/$tdir || error "rm $tdir failed"
24210         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24211         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24212         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24213         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24214                 error "truncate $tdir/trunc failed"
24215
24216         local bs=1048576
24217         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24218                 error "write $tfile failed"
24219
24220         # multi-client wirtes
24221         local num=$(get_node_count ${CLIENTS//,/ })
24222         local offset=0
24223         local i=0
24224
24225         echo "Test SOM for multi-client ($num) writes"
24226         touch $DIR/$tfile || error "touch $tfile failed"
24227         $TRUNCATE $DIR/$tfile 0
24228         for client in ${CLIENTS//,/ }; do
24229                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24230                 local pids[$i]=$!
24231                 i=$((i + 1))
24232                 offset=$((offset + $bs))
24233         done
24234         for (( i=0; i < $num; i++ )); do
24235                 wait ${pids[$i]}
24236         done
24237
24238         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24239         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24240         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24241         check_lsom_data $DIR/$tdir/trunc
24242         check_lsom_data $DIR/$tdir/single_dd
24243         check_lsom_data $DIR/$tfile
24244
24245         rm -rf $DIR/$tdir
24246         # Deregistration step
24247         changelog_deregister || error "changelog_deregister failed"
24248 }
24249 run_test 807 "verify LSOM syncing tool"
24250
24251 check_som_nologged()
24252 {
24253         local lines=$($LFS changelog $FSNAME-MDT0000 |
24254                 grep 'x=trusted.som' | wc -l)
24255         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24256 }
24257
24258 test_808() {
24259         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24260                 skip "Need MDS version at least 2.11.55"
24261
24262         # Registration step
24263         changelog_register || error "changelog_register failed"
24264
24265         touch $DIR/$tfile || error "touch $tfile failed"
24266         check_som_nologged
24267
24268         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24269                 error "write $tfile failed"
24270         check_som_nologged
24271
24272         $TRUNCATE $DIR/$tfile 1234
24273         check_som_nologged
24274
24275         $TRUNCATE $DIR/$tfile 1048576
24276         check_som_nologged
24277
24278         # Deregistration step
24279         changelog_deregister || error "changelog_deregister failed"
24280 }
24281 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24282
24283 check_som_nodata()
24284 {
24285         $LFS getsom $1
24286         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24287 }
24288
24289 test_809() {
24290         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24291                 skip "Need MDS version at least 2.11.56"
24292
24293         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24294                 error "failed to create DoM-only file $DIR/$tfile"
24295         touch $DIR/$tfile || error "touch $tfile failed"
24296         check_som_nodata $DIR/$tfile
24297
24298         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24299                 error "write $tfile failed"
24300         check_som_nodata $DIR/$tfile
24301
24302         $TRUNCATE $DIR/$tfile 1234
24303         check_som_nodata $DIR/$tfile
24304
24305         $TRUNCATE $DIR/$tfile 4097
24306         check_som_nodata $DIR/$file
24307 }
24308 run_test 809 "Verify no SOM xattr store for DoM-only files"
24309
24310 test_810() {
24311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24312         $GSS && skip_env "could not run with gss"
24313         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24314                 skip "OST < 2.12.58 doesn't align checksum"
24315
24316         set_checksums 1
24317         stack_trap "set_checksums $ORIG_CSUM" EXIT
24318         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24319
24320         local csum
24321         local before
24322         local after
24323         for csum in $CKSUM_TYPES; do
24324                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24325                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24326                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24327                         eval set -- $i
24328                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24329                         before=$(md5sum $DIR/$tfile)
24330                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24331                         after=$(md5sum $DIR/$tfile)
24332                         [ "$before" == "$after" ] ||
24333                                 error "$csum: $before != $after bs=$1 seek=$2"
24334                 done
24335         done
24336 }
24337 run_test 810 "partial page writes on ZFS (LU-11663)"
24338
24339 test_812a() {
24340         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24341                 skip "OST < 2.12.51 doesn't support this fail_loc"
24342
24343         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24344         # ensure ost1 is connected
24345         stat $DIR/$tfile >/dev/null || error "can't stat"
24346         wait_osc_import_state client ost1 FULL
24347         # no locks, no reqs to let the connection idle
24348         cancel_lru_locks osc
24349
24350         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24351 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24352         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24353         wait_osc_import_state client ost1 CONNECTING
24354         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24355
24356         stat $DIR/$tfile >/dev/null || error "can't stat file"
24357 }
24358 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24359
24360 test_812b() { # LU-12378
24361         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24362                 skip "OST < 2.12.51 doesn't support this fail_loc"
24363
24364         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24365         # ensure ost1 is connected
24366         stat $DIR/$tfile >/dev/null || error "can't stat"
24367         wait_osc_import_state client ost1 FULL
24368         # no locks, no reqs to let the connection idle
24369         cancel_lru_locks osc
24370
24371         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24372 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24373         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24374         wait_osc_import_state client ost1 CONNECTING
24375         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24376
24377         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24378         wait_osc_import_state client ost1 IDLE
24379 }
24380 run_test 812b "do not drop no resend request for idle connect"
24381
24382 test_813() {
24383         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24384         [ -z "$file_heat_sav" ] && skip "no file heat support"
24385
24386         local readsample
24387         local writesample
24388         local readbyte
24389         local writebyte
24390         local readsample1
24391         local writesample1
24392         local readbyte1
24393         local writebyte1
24394
24395         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24396         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24397
24398         $LCTL set_param -n llite.*.file_heat=1
24399         echo "Turn on file heat"
24400         echo "Period second: $period_second, Decay percentage: $decay_pct"
24401
24402         echo "QQQQ" > $DIR/$tfile
24403         echo "QQQQ" > $DIR/$tfile
24404         echo "QQQQ" > $DIR/$tfile
24405         cat $DIR/$tfile > /dev/null
24406         cat $DIR/$tfile > /dev/null
24407         cat $DIR/$tfile > /dev/null
24408         cat $DIR/$tfile > /dev/null
24409
24410         local out=$($LFS heat_get $DIR/$tfile)
24411
24412         $LFS heat_get $DIR/$tfile
24413         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24414         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24415         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24416         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24417
24418         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24419         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24420         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24421         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24422
24423         sleep $((period_second + 3))
24424         echo "Sleep $((period_second + 3)) seconds..."
24425         # The recursion formula to calculate the heat of the file f is as
24426         # follow:
24427         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24428         # Where Hi is the heat value in the period between time points i*I and
24429         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24430         # to the weight of Ci.
24431         out=$($LFS heat_get $DIR/$tfile)
24432         $LFS heat_get $DIR/$tfile
24433         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24434         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24435         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24436         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24437
24438         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24439                 error "read sample ($readsample) is wrong"
24440         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24441                 error "write sample ($writesample) is wrong"
24442         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24443                 error "read bytes ($readbyte) is wrong"
24444         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24445                 error "write bytes ($writebyte) is wrong"
24446
24447         echo "QQQQ" > $DIR/$tfile
24448         echo "QQQQ" > $DIR/$tfile
24449         echo "QQQQ" > $DIR/$tfile
24450         cat $DIR/$tfile > /dev/null
24451         cat $DIR/$tfile > /dev/null
24452         cat $DIR/$tfile > /dev/null
24453         cat $DIR/$tfile > /dev/null
24454
24455         sleep $((period_second + 3))
24456         echo "Sleep $((period_second + 3)) seconds..."
24457
24458         out=$($LFS heat_get $DIR/$tfile)
24459         $LFS heat_get $DIR/$tfile
24460         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24461         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24462         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24463         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24464
24465         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24466                 4 * $decay_pct) / 100") -eq 1 ] ||
24467                 error "read sample ($readsample1) is wrong"
24468         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24469                 3 * $decay_pct) / 100") -eq 1 ] ||
24470                 error "write sample ($writesample1) is wrong"
24471         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24472                 20 * $decay_pct) / 100") -eq 1 ] ||
24473                 error "read bytes ($readbyte1) is wrong"
24474         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24475                 15 * $decay_pct) / 100") -eq 1 ] ||
24476                 error "write bytes ($writebyte1) is wrong"
24477
24478         echo "Turn off file heat for the file $DIR/$tfile"
24479         $LFS heat_set -o $DIR/$tfile
24480
24481         echo "QQQQ" > $DIR/$tfile
24482         echo "QQQQ" > $DIR/$tfile
24483         echo "QQQQ" > $DIR/$tfile
24484         cat $DIR/$tfile > /dev/null
24485         cat $DIR/$tfile > /dev/null
24486         cat $DIR/$tfile > /dev/null
24487         cat $DIR/$tfile > /dev/null
24488
24489         out=$($LFS heat_get $DIR/$tfile)
24490         $LFS heat_get $DIR/$tfile
24491         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24492         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24493         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24494         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24495
24496         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24497         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24498         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24499         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24500
24501         echo "Trun on file heat for the file $DIR/$tfile"
24502         $LFS heat_set -O $DIR/$tfile
24503
24504         echo "QQQQ" > $DIR/$tfile
24505         echo "QQQQ" > $DIR/$tfile
24506         echo "QQQQ" > $DIR/$tfile
24507         cat $DIR/$tfile > /dev/null
24508         cat $DIR/$tfile > /dev/null
24509         cat $DIR/$tfile > /dev/null
24510         cat $DIR/$tfile > /dev/null
24511
24512         out=$($LFS heat_get $DIR/$tfile)
24513         $LFS heat_get $DIR/$tfile
24514         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24515         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24516         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24517         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24518
24519         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24520         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24521         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24522         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24523
24524         $LFS heat_set -c $DIR/$tfile
24525         $LCTL set_param -n llite.*.file_heat=0
24526         echo "Turn off file heat support for the Lustre filesystem"
24527
24528         echo "QQQQ" > $DIR/$tfile
24529         echo "QQQQ" > $DIR/$tfile
24530         echo "QQQQ" > $DIR/$tfile
24531         cat $DIR/$tfile > /dev/null
24532         cat $DIR/$tfile > /dev/null
24533         cat $DIR/$tfile > /dev/null
24534         cat $DIR/$tfile > /dev/null
24535
24536         out=$($LFS heat_get $DIR/$tfile)
24537         $LFS heat_get $DIR/$tfile
24538         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24539         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24540         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24541         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24542
24543         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24544         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24545         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24546         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24547
24548         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24549         rm -f $DIR/$tfile
24550 }
24551 run_test 813 "File heat verfication"
24552
24553 test_814()
24554 {
24555         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24556         echo -n y >> $DIR/$tfile
24557         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24558         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24559 }
24560 run_test 814 "sparse cp works as expected (LU-12361)"
24561
24562 test_815()
24563 {
24564         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24565         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24566 }
24567 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24568
24569 test_816() {
24570         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24571         # ensure ost1 is connected
24572         stat $DIR/$tfile >/dev/null || error "can't stat"
24573         wait_osc_import_state client ost1 FULL
24574         # no locks, no reqs to let the connection idle
24575         cancel_lru_locks osc
24576         lru_resize_disable osc
24577         local before
24578         local now
24579         before=$($LCTL get_param -n \
24580                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24581
24582         wait_osc_import_state client ost1 IDLE
24583         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24584         now=$($LCTL get_param -n \
24585               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24586         [ $before == $now ] || error "lru_size changed $before != $now"
24587 }
24588 run_test 816 "do not reset lru_resize on idle reconnect"
24589
24590 cleanup_817() {
24591         umount $tmpdir
24592         exportfs -u localhost:$DIR/nfsexp
24593         rm -rf $DIR/nfsexp
24594 }
24595
24596 test_817() {
24597         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24598
24599         mkdir -p $DIR/nfsexp
24600         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24601                 error "failed to export nfs"
24602
24603         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24604         stack_trap cleanup_817 EXIT
24605
24606         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24607                 error "failed to mount nfs to $tmpdir"
24608
24609         cp /bin/true $tmpdir
24610         $DIR/nfsexp/true || error "failed to execute 'true' command"
24611 }
24612 run_test 817 "nfsd won't cache write lock for exec file"
24613
24614 test_818() {
24615         mkdir $DIR/$tdir
24616         $LFS setstripe -c1 -i0 $DIR/$tfile
24617         $LFS setstripe -c1 -i1 $DIR/$tfile
24618         stop $SINGLEMDS
24619         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24620         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24621         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24622                 error "start $SINGLEMDS failed"
24623         rm -rf $DIR/$tdir
24624 }
24625 run_test 818 "unlink with failed llog"
24626
24627 test_819a() {
24628         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24629         cancel_lru_locks osc
24630         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24631         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24632         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24633         rm -f $TDIR/$tfile
24634 }
24635 run_test 819a "too big niobuf in read"
24636
24637 test_819b() {
24638         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24639         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24640         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24641         cancel_lru_locks osc
24642         sleep 1
24643         rm -f $TDIR/$tfile
24644 }
24645 run_test 819b "too big niobuf in write"
24646
24647
24648 function test_820_start_ost() {
24649         sleep 5
24650
24651         for num in $(seq $OSTCOUNT); do
24652                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24653         done
24654 }
24655
24656 test_820() {
24657         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24658
24659         mkdir $DIR/$tdir
24660         umount_client $MOUNT || error "umount failed"
24661         for num in $(seq $OSTCOUNT); do
24662                 stop ost$num
24663         done
24664
24665         # mount client with no active OSTs
24666         # so that the client can't initialize max LOV EA size
24667         # from OSC notifications
24668         mount_client $MOUNT || error "mount failed"
24669         # delay OST starting to keep this 0 max EA size for a while
24670         test_820_start_ost &
24671
24672         # create a directory on MDS2
24673         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24674                 error "Failed to create directory"
24675         # open intent should update default EA size
24676         # see mdc_update_max_ea_from_body()
24677         # notice this is the very first RPC to MDS2
24678         cp /etc/services $DIR/$tdir/mds2 ||
24679                 error "Failed to copy files to mds$n"
24680 }
24681 run_test 820 "update max EA from open intent"
24682
24683 #
24684 # tests that do cleanup/setup should be run at the end
24685 #
24686
24687 test_900() {
24688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24689         local ls
24690
24691         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24692         $LCTL set_param fail_loc=0x903
24693
24694         cancel_lru_locks MGC
24695
24696         FAIL_ON_ERROR=true cleanup
24697         FAIL_ON_ERROR=true setup
24698 }
24699 run_test 900 "umount should not race with any mgc requeue thread"
24700
24701 # LUS-6253/LU-11185
24702 test_901() {
24703         local oldc
24704         local newc
24705         local olds
24706         local news
24707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24708
24709         # some get_param have a bug to handle dot in param name
24710         cancel_lru_locks MGC
24711         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24712         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24713         umount_client $MOUNT || error "umount failed"
24714         mount_client $MOUNT || error "mount failed"
24715         cancel_lru_locks MGC
24716         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24717         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24718
24719         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24720         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24721
24722         return 0
24723 }
24724 run_test 901 "don't leak a mgc lock on client umount"
24725
24726 # LU-13377
24727 test_902() {
24728         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24729                 skip "client does not have LU-13377 fix"
24730         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24731         $LCTL set_param fail_loc=0x1415
24732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24733         cancel_lru_locks osc
24734         rm -f $DIR/$tfile
24735 }
24736 run_test 902 "test short write doesn't hang lustre"
24737
24738 complete $SECONDS
24739 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24740 check_and_cleanup_lustre
24741 if [ "$I_MOUNTED" != "yes" ]; then
24742         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24743 fi
24744 exit_status