Whamcloud - gitweb
LU-14181 tests: except sanity test_64e 64f with SHARED_KEY
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
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 test_31q() {
3356         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3357
3358         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3359         index=$($LFS getdirstripe -i $DIR/$tdir)
3360         [ $index -eq 3 ] || error "first stripe index $index != 3"
3361         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3362         [ $index -eq 1 ] || error "second stripe index $index != 1"
3363
3364         # when "-c <stripe_count>" is set, the number of MDTs specified after
3365         # "-i" should equal to the stripe count
3366         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3367 }
3368 run_test 31q "create striped directory on specific MDTs"
3369
3370 cleanup_test32_mount() {
3371         local rc=0
3372         trap 0
3373         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3374         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3375         losetup -d $loopdev || true
3376         rm -rf $DIR/$tdir
3377         return $rc
3378 }
3379
3380 test_32a() {
3381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3382
3383         echo "== more mountpoints and symlinks ================="
3384         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3385         trap cleanup_test32_mount EXIT
3386         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3387         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3388                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3389         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3390                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3391         cleanup_test32_mount
3392 }
3393 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3394
3395 test_32b() {
3396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3397
3398         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3399         trap cleanup_test32_mount EXIT
3400         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3401         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3402                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3403         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3404                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3405         cleanup_test32_mount
3406 }
3407 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3408
3409 test_32c() {
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         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3419                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3420         cleanup_test32_mount
3421 }
3422 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3423
3424 test_32d() {
3425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3426
3427         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3428         trap cleanup_test32_mount EXIT
3429         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3430         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3431                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3432         test_mkdir -p $DIR/$tdir/d2/test_dir
3433         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3434                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3435         cleanup_test32_mount
3436 }
3437 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3438
3439 test_32e() {
3440         rm -fr $DIR/$tdir
3441         test_mkdir -p $DIR/$tdir/tmp
3442         local tmp_dir=$DIR/$tdir/tmp
3443         ln -s $DIR/$tdir $tmp_dir/symlink11
3444         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3445         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3446         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3447 }
3448 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3449
3450 test_32f() {
3451         rm -fr $DIR/$tdir
3452         test_mkdir -p $DIR/$tdir/tmp
3453         local tmp_dir=$DIR/$tdir/tmp
3454         ln -s $DIR/$tdir $tmp_dir/symlink11
3455         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3456         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3457         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3458 }
3459 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3460
3461 test_32g() {
3462         local tmp_dir=$DIR/$tdir/tmp
3463         test_mkdir -p $tmp_dir
3464         test_mkdir $DIR/${tdir}2
3465         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3466         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3467         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3468         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3469         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3470         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3471 }
3472 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3473
3474 test_32h() {
3475         rm -fr $DIR/$tdir $DIR/${tdir}2
3476         tmp_dir=$DIR/$tdir/tmp
3477         test_mkdir -p $tmp_dir
3478         test_mkdir $DIR/${tdir}2
3479         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3480         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3481         ls $tmp_dir/symlink12 || error "listing symlink12"
3482         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3483 }
3484 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3485
3486 test_32i() {
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         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3496                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3497         cleanup_test32_mount
3498 }
3499 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3500
3501 test_32j() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         [ -e $DIR/$tdir ] && 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         touch $DIR/$tdir/test_file
3510         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3511                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3512         cleanup_test32_mount
3513 }
3514 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3515
3516 test_32k() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         rm -fr $DIR/$tdir
3520         trap cleanup_test32_mount EXIT
3521         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3522         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3523                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3524         test_mkdir -p $DIR/$tdir/d2
3525         touch $DIR/$tdir/d2/test_file || error "touch failed"
3526         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3527                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3528         cleanup_test32_mount
3529 }
3530 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3531
3532 test_32l() {
3533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3534
3535         rm -fr $DIR/$tdir
3536         trap cleanup_test32_mount EXIT
3537         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3538         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3539                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3540         test_mkdir -p $DIR/$tdir/d2
3541         touch $DIR/$tdir/d2/test_file || error "touch failed"
3542         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3543                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3544         cleanup_test32_mount
3545 }
3546 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3547
3548 test_32m() {
3549         rm -fr $DIR/d32m
3550         test_mkdir -p $DIR/d32m/tmp
3551         TMP_DIR=$DIR/d32m/tmp
3552         ln -s $DIR $TMP_DIR/symlink11
3553         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3554         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3555                 error "symlink11 not a link"
3556         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3557                 error "symlink01 not a link"
3558 }
3559 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3560
3561 test_32n() {
3562         rm -fr $DIR/d32n
3563         test_mkdir -p $DIR/d32n/tmp
3564         TMP_DIR=$DIR/d32n/tmp
3565         ln -s $DIR $TMP_DIR/symlink11
3566         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3567         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3568         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3569 }
3570 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3571
3572 test_32o() {
3573         touch $DIR/$tfile
3574         test_mkdir -p $DIR/d32o/tmp
3575         TMP_DIR=$DIR/d32o/tmp
3576         ln -s $DIR/$tfile $TMP_DIR/symlink12
3577         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3578         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3579                 error "symlink12 not a link"
3580         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3581         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3582                 error "$DIR/d32o/tmp/symlink12 not file type"
3583         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3584                 error "$DIR/d32o/symlink02 not file type"
3585 }
3586 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3587
3588 test_32p() {
3589         log 32p_1
3590         rm -fr $DIR/d32p
3591         log 32p_2
3592         rm -f $DIR/$tfile
3593         log 32p_3
3594         touch $DIR/$tfile
3595         log 32p_4
3596         test_mkdir -p $DIR/d32p/tmp
3597         log 32p_5
3598         TMP_DIR=$DIR/d32p/tmp
3599         log 32p_6
3600         ln -s $DIR/$tfile $TMP_DIR/symlink12
3601         log 32p_7
3602         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3603         log 32p_8
3604         cat $DIR/d32p/tmp/symlink12 ||
3605                 error "Can't open $DIR/d32p/tmp/symlink12"
3606         log 32p_9
3607         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3608         log 32p_10
3609 }
3610 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3611
3612 test_32q() {
3613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3614
3615         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3616         trap cleanup_test32_mount EXIT
3617         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3618         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3619         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3620                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3621         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3622         cleanup_test32_mount
3623 }
3624 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3625
3626 test_32r() {
3627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3628
3629         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3630         trap cleanup_test32_mount EXIT
3631         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3632         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3633         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3634                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3635         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3636         cleanup_test32_mount
3637 }
3638 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3639
3640 test_33aa() {
3641         rm -f $DIR/$tfile
3642         touch $DIR/$tfile
3643         chmod 444 $DIR/$tfile
3644         chown $RUNAS_ID $DIR/$tfile
3645         log 33_1
3646         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3647         log 33_2
3648 }
3649 run_test 33aa "write file with mode 444 (should return error)"
3650
3651 test_33a() {
3652         rm -fr $DIR/$tdir
3653         test_mkdir $DIR/$tdir
3654         chown $RUNAS_ID $DIR/$tdir
3655         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3656                 error "$RUNAS create $tdir/$tfile failed"
3657         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3658                 error "open RDWR" || true
3659 }
3660 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3661
3662 test_33b() {
3663         rm -fr $DIR/$tdir
3664         test_mkdir $DIR/$tdir
3665         chown $RUNAS_ID $DIR/$tdir
3666         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3667 }
3668 run_test 33b "test open file with malformed flags (No panic)"
3669
3670 test_33c() {
3671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3672         remote_ost_nodsh && skip "remote OST with nodsh"
3673
3674         local ostnum
3675         local ostname
3676         local write_bytes
3677         local all_zeros
3678
3679         all_zeros=:
3680         rm -fr $DIR/$tdir
3681         test_mkdir $DIR/$tdir
3682         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3683
3684         sync
3685         for ostnum in $(seq $OSTCOUNT); do
3686                 # test-framework's OST numbering is one-based, while Lustre's
3687                 # is zero-based
3688                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3689                 # Parsing llobdstat's output sucks; we could grep the /proc
3690                 # path, but that's likely to not be as portable as using the
3691                 # llobdstat utility.  So we parse lctl output instead.
3692                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3693                         obdfilter/$ostname/stats |
3694                         awk '/^write_bytes/ {print $7}' )
3695                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3696                 if (( ${write_bytes:-0} > 0 ))
3697                 then
3698                         all_zeros=false
3699                         break;
3700                 fi
3701         done
3702
3703         $all_zeros || return 0
3704
3705         # Write four bytes
3706         echo foo > $DIR/$tdir/bar
3707         # Really write them
3708         sync
3709
3710         # Total up write_bytes after writing.  We'd better find non-zeros.
3711         for ostnum in $(seq $OSTCOUNT); do
3712                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3713                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3714                         obdfilter/$ostname/stats |
3715                         awk '/^write_bytes/ {print $7}' )
3716                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3717                 if (( ${write_bytes:-0} > 0 ))
3718                 then
3719                         all_zeros=false
3720                         break;
3721                 fi
3722         done
3723
3724         if $all_zeros
3725         then
3726                 for ostnum in $(seq $OSTCOUNT); do
3727                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3728                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3729                         do_facet ost$ostnum lctl get_param -n \
3730                                 obdfilter/$ostname/stats
3731                 done
3732                 error "OST not keeping write_bytes stats (b22312)"
3733         fi
3734 }
3735 run_test 33c "test llobdstat and write_bytes"
3736
3737 test_33d() {
3738         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3740
3741         local MDTIDX=1
3742         local remote_dir=$DIR/$tdir/remote_dir
3743
3744         test_mkdir $DIR/$tdir
3745         $LFS mkdir -i $MDTIDX $remote_dir ||
3746                 error "create remote directory failed"
3747
3748         touch $remote_dir/$tfile
3749         chmod 444 $remote_dir/$tfile
3750         chown $RUNAS_ID $remote_dir/$tfile
3751
3752         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3753
3754         chown $RUNAS_ID $remote_dir
3755         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3756                                         error "create" || true
3757         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3758                                     error "open RDWR" || true
3759         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3760 }
3761 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3762
3763 test_33e() {
3764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3765
3766         mkdir $DIR/$tdir
3767
3768         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3769         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3770         mkdir $DIR/$tdir/local_dir
3771
3772         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3773         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3774         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3775
3776         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3777                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3778
3779         rmdir $DIR/$tdir/* || error "rmdir failed"
3780
3781         umask 777
3782         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3783         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3784         mkdir $DIR/$tdir/local_dir
3785
3786         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3787         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3788         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3789
3790         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3791                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3792
3793         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3794
3795         umask 000
3796         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3797         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3798         mkdir $DIR/$tdir/local_dir
3799
3800         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3801         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3802         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3803
3804         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3805                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3806 }
3807 run_test 33e "mkdir and striped directory should have same mode"
3808
3809 cleanup_33f() {
3810         trap 0
3811         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3812 }
3813
3814 test_33f() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         remote_mds_nodsh && skip "remote MDS with nodsh"
3817
3818         mkdir $DIR/$tdir
3819         chmod go+rwx $DIR/$tdir
3820         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3821         trap cleanup_33f EXIT
3822
3823         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3824                 error "cannot create striped directory"
3825
3826         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3827                 error "cannot create files in striped directory"
3828
3829         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3830                 error "cannot remove files in striped directory"
3831
3832         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3833                 error "cannot remove striped directory"
3834
3835         cleanup_33f
3836 }
3837 run_test 33f "nonroot user can create, access, and remove a striped directory"
3838
3839 test_33g() {
3840         mkdir -p $DIR/$tdir/dir2
3841
3842         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3843         echo $err
3844         [[ $err =~ "exists" ]] || error "Not exists error"
3845 }
3846 run_test 33g "nonroot user create already existing root created file"
3847
3848 test_33h() {
3849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3850         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3851                 skip "Need MDS version at least 2.13.50"
3852
3853         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3854                 error "mkdir $tdir failed"
3855         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3856
3857         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3858         local index2
3859
3860         for fname in $DIR/$tdir/$tfile.bak \
3861                      $DIR/$tdir/$tfile.SAV \
3862                      $DIR/$tdir/$tfile.orig \
3863                      $DIR/$tdir/$tfile~; do
3864                 touch $fname  || error "touch $fname failed"
3865                 index2=$($LFS getstripe -m $fname)
3866                 [ $index -eq $index2 ] ||
3867                         error "$fname MDT index mismatch $index != $index2"
3868         done
3869
3870         local failed=0
3871         for i in {1..250}; do
3872                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3873                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3874                         touch $fname  || error "touch $fname failed"
3875                         index2=$($LFS getstripe -m $fname)
3876                         if [[ $index != $index2 ]]; then
3877                                 failed=$((failed + 1))
3878                                 echo "$fname MDT index mismatch $index != $index2"
3879                         fi
3880                 done
3881         done
3882         echo "$failed MDT index mismatches"
3883         (( failed < 20 )) || error "MDT index mismatch $failed times"
3884
3885 }
3886 run_test 33h "temp file is located on the same MDT as target"
3887
3888 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3889 test_34a() {
3890         rm -f $DIR/f34
3891         $MCREATE $DIR/f34 || error "mcreate failed"
3892         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3893                 error "getstripe failed"
3894         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3895         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3896                 error "getstripe failed"
3897         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3898                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3899 }
3900 run_test 34a "truncate file that has not been opened ==========="
3901
3902 test_34b() {
3903         [ ! -f $DIR/f34 ] && test_34a
3904         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3905                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3906         $OPENFILE -f O_RDONLY $DIR/f34
3907         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3908                 error "getstripe failed"
3909         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3910                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3911 }
3912 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3913
3914 test_34c() {
3915         [ ! -f $DIR/f34 ] && test_34a
3916         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3917                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3918         $OPENFILE -f O_RDWR $DIR/f34
3919         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3920                 error "$LFS getstripe failed"
3921         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3922                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3923 }
3924 run_test 34c "O_RDWR opening file-with-size works =============="
3925
3926 test_34d() {
3927         [ ! -f $DIR/f34 ] && test_34a
3928         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3929                 error "dd failed"
3930         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3931                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3932         rm $DIR/f34
3933 }
3934 run_test 34d "write to sparse file ============================="
3935
3936 test_34e() {
3937         rm -f $DIR/f34e
3938         $MCREATE $DIR/f34e || error "mcreate failed"
3939         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3940         $CHECKSTAT -s 1000 $DIR/f34e ||
3941                 error "Size of $DIR/f34e not equal to 1000 bytes"
3942         $OPENFILE -f O_RDWR $DIR/f34e
3943         $CHECKSTAT -s 1000 $DIR/f34e ||
3944                 error "Size of $DIR/f34e not equal to 1000 bytes"
3945 }
3946 run_test 34e "create objects, some with size and some without =="
3947
3948 test_34f() { # bug 6242, 6243
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         SIZE34F=48000
3952         rm -f $DIR/f34f
3953         $MCREATE $DIR/f34f || error "mcreate failed"
3954         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3955         dd if=$DIR/f34f of=$TMP/f34f
3956         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3957         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3958         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3959         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3960         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3961 }
3962 run_test 34f "read from a file with no objects until EOF ======="
3963
3964 test_34g() {
3965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3966
3967         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3968                 error "dd failed"
3969         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3970         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3971                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3972         cancel_lru_locks osc
3973         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3974                 error "wrong size after lock cancel"
3975
3976         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3977         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3978                 error "expanding truncate failed"
3979         cancel_lru_locks osc
3980         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3981                 error "wrong expanded size after lock cancel"
3982 }
3983 run_test 34g "truncate long file ==============================="
3984
3985 test_34h() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         local gid=10
3989         local sz=1000
3990
3991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3992         sync # Flush the cache so that multiop below does not block on cache
3993              # flush when getting the group lock
3994         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3995         MULTIPID=$!
3996
3997         # Since just timed wait is not good enough, let's do a sync write
3998         # that way we are sure enough time for a roundtrip + processing
3999         # passed + 2 seconds of extra margin.
4000         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4001         rm $DIR/${tfile}-1
4002         sleep 2
4003
4004         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4005                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4006                 kill -9 $MULTIPID
4007         fi
4008         wait $MULTIPID
4009         local nsz=`stat -c %s $DIR/$tfile`
4010         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4011 }
4012 run_test 34h "ftruncate file under grouplock should not block"
4013
4014 test_35a() {
4015         cp /bin/sh $DIR/f35a
4016         chmod 444 $DIR/f35a
4017         chown $RUNAS_ID $DIR/f35a
4018         $RUNAS $DIR/f35a && error || true
4019         rm $DIR/f35a
4020 }
4021 run_test 35a "exec file with mode 444 (should return and not leak)"
4022
4023 test_36a() {
4024         rm -f $DIR/f36
4025         utime $DIR/f36 || error "utime failed for MDS"
4026 }
4027 run_test 36a "MDS utime check (mknod, utime)"
4028
4029 test_36b() {
4030         echo "" > $DIR/f36
4031         utime $DIR/f36 || error "utime failed for OST"
4032 }
4033 run_test 36b "OST utime check (open, utime)"
4034
4035 test_36c() {
4036         rm -f $DIR/d36/f36
4037         test_mkdir $DIR/d36
4038         chown $RUNAS_ID $DIR/d36
4039         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4040 }
4041 run_test 36c "non-root MDS utime check (mknod, utime)"
4042
4043 test_36d() {
4044         [ ! -d $DIR/d36 ] && test_36c
4045         echo "" > $DIR/d36/f36
4046         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4047 }
4048 run_test 36d "non-root OST utime check (open, utime)"
4049
4050 test_36e() {
4051         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4052
4053         test_mkdir $DIR/$tdir
4054         touch $DIR/$tdir/$tfile
4055         $RUNAS utime $DIR/$tdir/$tfile &&
4056                 error "utime worked, expected failure" || true
4057 }
4058 run_test 36e "utime on non-owned file (should return error)"
4059
4060 subr_36fh() {
4061         local fl="$1"
4062         local LANG_SAVE=$LANG
4063         local LC_LANG_SAVE=$LC_LANG
4064         export LANG=C LC_LANG=C # for date language
4065
4066         DATESTR="Dec 20  2000"
4067         test_mkdir $DIR/$tdir
4068         lctl set_param fail_loc=$fl
4069         date; date +%s
4070         cp /etc/hosts $DIR/$tdir/$tfile
4071         sync & # write RPC generated with "current" inode timestamp, but delayed
4072         sleep 1
4073         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4074         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4075         cancel_lru_locks $OSC
4076         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4077         date; date +%s
4078         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4079                 echo "BEFORE: $LS_BEFORE" && \
4080                 echo "AFTER : $LS_AFTER" && \
4081                 echo "WANT  : $DATESTR" && \
4082                 error "$DIR/$tdir/$tfile timestamps changed" || true
4083
4084         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4085 }
4086
4087 test_36f() {
4088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4089
4090         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4091         subr_36fh "0x80000214"
4092 }
4093 run_test 36f "utime on file racing with OST BRW write =========="
4094
4095 test_36g() {
4096         remote_ost_nodsh && skip "remote OST with nodsh"
4097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4098         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4099                 skip "Need MDS version at least 2.12.51"
4100
4101         local fmd_max_age
4102         local fmd
4103         local facet="ost1"
4104         local tgt="obdfilter"
4105
4106         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4107
4108         test_mkdir $DIR/$tdir
4109         fmd_max_age=$(do_facet $facet \
4110                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4111                 head -n 1")
4112
4113         echo "FMD max age: ${fmd_max_age}s"
4114         touch $DIR/$tdir/$tfile
4115         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4116                 gawk '{cnt=cnt+$1}  END{print cnt}')
4117         echo "FMD before: $fmd"
4118         [[ $fmd == 0 ]] &&
4119                 error "FMD wasn't create by touch"
4120         sleep $((fmd_max_age + 12))
4121         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4122                 gawk '{cnt=cnt+$1}  END{print cnt}')
4123         echo "FMD after: $fmd"
4124         [[ $fmd == 0 ]] ||
4125                 error "FMD wasn't expired by ping"
4126 }
4127 run_test 36g "FMD cache expiry ====================="
4128
4129 test_36h() {
4130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4131
4132         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4133         subr_36fh "0x80000227"
4134 }
4135 run_test 36h "utime on file racing with OST BRW write =========="
4136
4137 test_36i() {
4138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4139
4140         test_mkdir $DIR/$tdir
4141         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4142
4143         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4144         local new_mtime=$((mtime + 200))
4145
4146         #change Modify time of striped dir
4147         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4148                         error "change mtime failed"
4149
4150         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4151
4152         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4153 }
4154 run_test 36i "change mtime on striped directory"
4155
4156 # test_37 - duplicate with tests 32q 32r
4157
4158 test_38() {
4159         local file=$DIR/$tfile
4160         touch $file
4161         openfile -f O_DIRECTORY $file
4162         local RC=$?
4163         local ENOTDIR=20
4164         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4165         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4166 }
4167 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4168
4169 test_39a() { # was test_39
4170         touch $DIR/$tfile
4171         touch $DIR/${tfile}2
4172 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4173 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4174 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4175         sleep 2
4176         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4177         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4178                 echo "mtime"
4179                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4180                 echo "atime"
4181                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4182                 echo "ctime"
4183                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4184                 error "O_TRUNC didn't change timestamps"
4185         fi
4186 }
4187 run_test 39a "mtime changed on create"
4188
4189 test_39b() {
4190         test_mkdir -c1 $DIR/$tdir
4191         cp -p /etc/passwd $DIR/$tdir/fopen
4192         cp -p /etc/passwd $DIR/$tdir/flink
4193         cp -p /etc/passwd $DIR/$tdir/funlink
4194         cp -p /etc/passwd $DIR/$tdir/frename
4195         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4196
4197         sleep 1
4198         echo "aaaaaa" >> $DIR/$tdir/fopen
4199         echo "aaaaaa" >> $DIR/$tdir/flink
4200         echo "aaaaaa" >> $DIR/$tdir/funlink
4201         echo "aaaaaa" >> $DIR/$tdir/frename
4202
4203         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4204         local link_new=`stat -c %Y $DIR/$tdir/flink`
4205         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4206         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4207
4208         cat $DIR/$tdir/fopen > /dev/null
4209         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4210         rm -f $DIR/$tdir/funlink2
4211         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4212
4213         for (( i=0; i < 2; i++ )) ; do
4214                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4215                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4216                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4217                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4218
4219                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4220                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4221                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4222                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39b "mtime change on open, link, unlink, rename  ======"
4229
4230 # this should be set to past
4231 TEST_39_MTIME=`date -d "1 year ago" +%s`
4232
4233 # bug 11063
4234 test_39c() {
4235         touch $DIR1/$tfile
4236         sleep 2
4237         local mtime0=`stat -c %Y $DIR1/$tfile`
4238
4239         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4240         local mtime1=`stat -c %Y $DIR1/$tfile`
4241         [ "$mtime1" = $TEST_39_MTIME ] || \
4242                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4243
4244         local d1=`date +%s`
4245         echo hello >> $DIR1/$tfile
4246         local d2=`date +%s`
4247         local mtime2=`stat -c %Y $DIR1/$tfile`
4248         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4249                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4250
4251         mv $DIR1/$tfile $DIR1/$tfile-1
4252
4253         for (( i=0; i < 2; i++ )) ; do
4254                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4255                 [ "$mtime2" = "$mtime3" ] || \
4256                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4257
4258                 cancel_lru_locks $OSC
4259                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4260         done
4261 }
4262 run_test 39c "mtime change on rename ==========================="
4263
4264 # bug 21114
4265 test_39d() {
4266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4267
4268         touch $DIR1/$tfile
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39d "create, utime, stat =============================="
4281
4282 # bug 21114
4283 test_39e() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         touch $DIR1/$tfile
4287         local mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4290
4291         for (( i=0; i < 2; i++ )) ; do
4292                 local mtime2=`stat -c %Y $DIR1/$tfile`
4293                 [ $mtime2 = $TEST_39_MTIME ] || \
4294                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4295
4296                 cancel_lru_locks $OSC
4297                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4298         done
4299 }
4300 run_test 39e "create, stat, utime, stat ========================"
4301
4302 # bug 21114
4303 test_39f() {
4304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4305
4306         touch $DIR1/$tfile
4307         mtime1=`stat -c %Y $DIR1/$tfile`
4308
4309         sleep 2
4310         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4311
4312         for (( i=0; i < 2; i++ )) ; do
4313                 local mtime2=`stat -c %Y $DIR1/$tfile`
4314                 [ $mtime2 = $TEST_39_MTIME ] || \
4315                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4316
4317                 cancel_lru_locks $OSC
4318                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4319         done
4320 }
4321 run_test 39f "create, stat, sleep, utime, stat ================="
4322
4323 # bug 11063
4324 test_39g() {
4325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4326
4327         echo hello >> $DIR1/$tfile
4328         local mtime1=`stat -c %Y $DIR1/$tfile`
4329
4330         sleep 2
4331         chmod o+r $DIR1/$tfile
4332
4333         for (( i=0; i < 2; i++ )) ; do
4334                 local mtime2=`stat -c %Y $DIR1/$tfile`
4335                 [ "$mtime1" = "$mtime2" ] || \
4336                         error "lost mtime: $mtime2, should be $mtime1"
4337
4338                 cancel_lru_locks $OSC
4339                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4340         done
4341 }
4342 run_test 39g "write, chmod, stat ==============================="
4343
4344 # bug 11063
4345 test_39h() {
4346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4347
4348         touch $DIR1/$tfile
4349         sleep 1
4350
4351         local d1=`date`
4352         echo hello >> $DIR1/$tfile
4353         local mtime1=`stat -c %Y $DIR1/$tfile`
4354
4355         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4356         local d2=`date`
4357         if [ "$d1" != "$d2" ]; then
4358                 echo "write and touch not within one second"
4359         else
4360                 for (( i=0; i < 2; i++ )) ; do
4361                         local mtime2=`stat -c %Y $DIR1/$tfile`
4362                         [ "$mtime2" = $TEST_39_MTIME ] || \
4363                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4364
4365                         cancel_lru_locks $OSC
4366                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4367                 done
4368         fi
4369 }
4370 run_test 39h "write, utime within one second, stat ============="
4371
4372 test_39i() {
4373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4374
4375         touch $DIR1/$tfile
4376         sleep 1
4377
4378         echo hello >> $DIR1/$tfile
4379         local mtime1=`stat -c %Y $DIR1/$tfile`
4380
4381         mv $DIR1/$tfile $DIR1/$tfile-1
4382
4383         for (( i=0; i < 2; i++ )) ; do
4384                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4385
4386                 [ "$mtime1" = "$mtime2" ] || \
4387                         error "lost mtime: $mtime2, should be $mtime1"
4388
4389                 cancel_lru_locks $OSC
4390                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4391         done
4392 }
4393 run_test 39i "write, rename, stat =============================="
4394
4395 test_39j() {
4396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4397
4398         start_full_debug_logging
4399         touch $DIR1/$tfile
4400         sleep 1
4401
4402         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4403         lctl set_param fail_loc=0x80000412
4404         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4405                 error "multiop failed"
4406         local multipid=$!
4407         local mtime1=`stat -c %Y $DIR1/$tfile`
4408
4409         mv $DIR1/$tfile $DIR1/$tfile-1
4410
4411         kill -USR1 $multipid
4412         wait $multipid || error "multiop close failed"
4413
4414         for (( i=0; i < 2; i++ )) ; do
4415                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4416                 [ "$mtime1" = "$mtime2" ] ||
4417                         error "mtime is lost on close: $mtime2, " \
4418                               "should be $mtime1"
4419
4420                 cancel_lru_locks
4421                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4422         done
4423         lctl set_param fail_loc=0
4424         stop_full_debug_logging
4425 }
4426 run_test 39j "write, rename, close, stat ======================="
4427
4428 test_39k() {
4429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4430
4431         touch $DIR1/$tfile
4432         sleep 1
4433
4434         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4435         local multipid=$!
4436         local mtime1=`stat -c %Y $DIR1/$tfile`
4437
4438         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4439
4440         kill -USR1 $multipid
4441         wait $multipid || error "multiop close failed"
4442
4443         for (( i=0; i < 2; i++ )) ; do
4444                 local mtime2=`stat -c %Y $DIR1/$tfile`
4445
4446                 [ "$mtime2" = $TEST_39_MTIME ] || \
4447                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4448
4449                 cancel_lru_locks
4450                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4451         done
4452 }
4453 run_test 39k "write, utime, close, stat ========================"
4454
4455 # this should be set to future
4456 TEST_39_ATIME=`date -d "1 year" +%s`
4457
4458 test_39l() {
4459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4460         remote_mds_nodsh && skip "remote MDS with nodsh"
4461
4462         local atime_diff=$(do_facet $SINGLEMDS \
4463                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4464         rm -rf $DIR/$tdir
4465         mkdir -p $DIR/$tdir
4466
4467         # test setting directory atime to future
4468         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4469         local atime=$(stat -c %X $DIR/$tdir)
4470         [ "$atime" = $TEST_39_ATIME ] ||
4471                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4472
4473         # test setting directory atime from future to now
4474         local now=$(date +%s)
4475         touch -a -d @$now $DIR/$tdir
4476
4477         atime=$(stat -c %X $DIR/$tdir)
4478         [ "$atime" -eq "$now"  ] ||
4479                 error "atime is not updated from future: $atime, $now"
4480
4481         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4482         sleep 3
4483
4484         # test setting directory atime when now > dir atime + atime_diff
4485         local d1=$(date +%s)
4486         ls $DIR/$tdir
4487         local d2=$(date +%s)
4488         cancel_lru_locks mdc
4489         atime=$(stat -c %X $DIR/$tdir)
4490         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4491                 error "atime is not updated  : $atime, should be $d2"
4492
4493         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4494         sleep 3
4495
4496         # test not setting directory atime when now < dir atime + atime_diff
4497         ls $DIR/$tdir
4498         cancel_lru_locks mdc
4499         atime=$(stat -c %X $DIR/$tdir)
4500         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4501                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4502
4503         do_facet $SINGLEMDS \
4504                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4505 }
4506 run_test 39l "directory atime update ==========================="
4507
4508 test_39m() {
4509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4510
4511         touch $DIR1/$tfile
4512         sleep 2
4513         local far_past_mtime=$(date -d "May 29 1953" +%s)
4514         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4515
4516         touch -m -d @$far_past_mtime $DIR1/$tfile
4517         touch -a -d @$far_past_atime $DIR1/$tfile
4518
4519         for (( i=0; i < 2; i++ )) ; do
4520                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4521                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4522                         error "atime or mtime set incorrectly"
4523
4524                 cancel_lru_locks $OSC
4525                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4526         done
4527 }
4528 run_test 39m "test atime and mtime before 1970"
4529
4530 test_39n() { # LU-3832
4531         remote_mds_nodsh && skip "remote MDS with nodsh"
4532
4533         local atime_diff=$(do_facet $SINGLEMDS \
4534                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4535         local atime0
4536         local atime1
4537         local atime2
4538
4539         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4540
4541         rm -rf $DIR/$tfile
4542         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4543         atime0=$(stat -c %X $DIR/$tfile)
4544
4545         sleep 5
4546         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4547         atime1=$(stat -c %X $DIR/$tfile)
4548
4549         sleep 5
4550         cancel_lru_locks mdc
4551         cancel_lru_locks osc
4552         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4553         atime2=$(stat -c %X $DIR/$tfile)
4554
4555         do_facet $SINGLEMDS \
4556                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4557
4558         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4559         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4560 }
4561 run_test 39n "check that O_NOATIME is honored"
4562
4563 test_39o() {
4564         TESTDIR=$DIR/$tdir/$tfile
4565         [ -e $TESTDIR ] && rm -rf $TESTDIR
4566         mkdir -p $TESTDIR
4567         cd $TESTDIR
4568         links1=2
4569         ls
4570         mkdir a b
4571         ls
4572         links2=$(stat -c %h .)
4573         [ $(($links1 + 2)) != $links2 ] &&
4574                 error "wrong links count $(($links1 + 2)) != $links2"
4575         rmdir b
4576         links3=$(stat -c %h .)
4577         [ $(($links1 + 1)) != $links3 ] &&
4578                 error "wrong links count $links1 != $links3"
4579         return 0
4580 }
4581 run_test 39o "directory cached attributes updated after create"
4582
4583 test_39p() {
4584         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4585
4586         local MDTIDX=1
4587         TESTDIR=$DIR/$tdir/$tdir
4588         [ -e $TESTDIR ] && rm -rf $TESTDIR
4589         test_mkdir -p $TESTDIR
4590         cd $TESTDIR
4591         links1=2
4592         ls
4593         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4594         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4595         ls
4596         links2=$(stat -c %h .)
4597         [ $(($links1 + 2)) != $links2 ] &&
4598                 error "wrong links count $(($links1 + 2)) != $links2"
4599         rmdir remote_dir2
4600         links3=$(stat -c %h .)
4601         [ $(($links1 + 1)) != $links3 ] &&
4602                 error "wrong links count $links1 != $links3"
4603         return 0
4604 }
4605 run_test 39p "remote directory cached attributes updated after create ========"
4606
4607 test_39r() {
4608         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4609                 skip "no atime update on old OST"
4610         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4611                 skip_env "ldiskfs only test"
4612         fi
4613
4614         local saved_adiff
4615         saved_adiff=$(do_facet ost1 \
4616                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4617         stack_trap "do_facet ost1 \
4618                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4619
4620         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4621
4622         $LFS setstripe -i 0 $DIR/$tfile
4623         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4624                 error "can't write initial file"
4625         cancel_lru_locks osc
4626
4627         # exceed atime_diff and access file
4628         sleep 6
4629         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4630
4631         local atime_cli=$(stat -c %X $DIR/$tfile)
4632         echo "client atime: $atime_cli"
4633         # allow atime update to be written to device
4634         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4635         sleep 5
4636
4637         local ostdev=$(ostdevname 1)
4638         local fid=($(lfs getstripe -y $DIR/$tfile |
4639                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4640         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4641         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4642
4643         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4644         local atime_ost=$(do_facet ost1 "$cmd" |&
4645                           awk -F'[: ]' '/atime:/ { print $4 }')
4646         (( atime_cli == atime_ost )) ||
4647                 error "atime on client $atime_cli != ost $atime_ost"
4648 }
4649 run_test 39r "lazy atime update on OST"
4650
4651 test_39q() { # LU-8041
4652         local testdir=$DIR/$tdir
4653         mkdir -p $testdir
4654         multiop_bg_pause $testdir D_c || error "multiop failed"
4655         local multipid=$!
4656         cancel_lru_locks mdc
4657         kill -USR1 $multipid
4658         local atime=$(stat -c %X $testdir)
4659         [ "$atime" -ne 0 ] || error "atime is zero"
4660 }
4661 run_test 39q "close won't zero out atime"
4662
4663 test_40() {
4664         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4665         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4666                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4667         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4668                 error "$tfile is not 4096 bytes in size"
4669 }
4670 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4671
4672 test_41() {
4673         # bug 1553
4674         small_write $DIR/f41 18
4675 }
4676 run_test 41 "test small file write + fstat ====================="
4677
4678 count_ost_writes() {
4679         lctl get_param -n ${OSC}.*.stats |
4680                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4681                         END { printf("%0.0f", writes) }'
4682 }
4683
4684 # decent default
4685 WRITEBACK_SAVE=500
4686 DIRTY_RATIO_SAVE=40
4687 MAX_DIRTY_RATIO=50
4688 BG_DIRTY_RATIO_SAVE=10
4689 MAX_BG_DIRTY_RATIO=25
4690
4691 start_writeback() {
4692         trap 0
4693         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4694         # dirty_ratio, dirty_background_ratio
4695         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4696                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4697                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4698                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4699         else
4700                 # if file not here, we are a 2.4 kernel
4701                 kill -CONT `pidof kupdated`
4702         fi
4703 }
4704
4705 stop_writeback() {
4706         # setup the trap first, so someone cannot exit the test at the
4707         # exact wrong time and mess up a machine
4708         trap start_writeback EXIT
4709         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4710         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4711                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4712                 sysctl -w vm.dirty_writeback_centisecs=0
4713                 sysctl -w vm.dirty_writeback_centisecs=0
4714                 # save and increase /proc/sys/vm/dirty_ratio
4715                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4716                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4717                 # save and increase /proc/sys/vm/dirty_background_ratio
4718                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4719                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4720         else
4721                 # if file not here, we are a 2.4 kernel
4722                 kill -STOP `pidof kupdated`
4723         fi
4724 }
4725
4726 # ensure that all stripes have some grant before we test client-side cache
4727 setup_test42() {
4728         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4729                 dd if=/dev/zero of=$i bs=4k count=1
4730                 rm $i
4731         done
4732 }
4733
4734 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4735 # file truncation, and file removal.
4736 test_42a() {
4737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4738
4739         setup_test42
4740         cancel_lru_locks $OSC
4741         stop_writeback
4742         sync; sleep 1; sync # just to be safe
4743         BEFOREWRITES=`count_ost_writes`
4744         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4745         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4746         AFTERWRITES=`count_ost_writes`
4747         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4748                 error "$BEFOREWRITES < $AFTERWRITES"
4749         start_writeback
4750 }
4751 run_test 42a "ensure that we don't flush on close"
4752
4753 test_42b() {
4754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4755
4756         setup_test42
4757         cancel_lru_locks $OSC
4758         stop_writeback
4759         sync
4760         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4761         BEFOREWRITES=$(count_ost_writes)
4762         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4763         AFTERWRITES=$(count_ost_writes)
4764         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4765                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4766         fi
4767         BEFOREWRITES=$(count_ost_writes)
4768         sync || error "sync: $?"
4769         AFTERWRITES=$(count_ost_writes)
4770         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4771                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4772         fi
4773         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4774         start_writeback
4775         return 0
4776 }
4777 run_test 42b "test destroy of file with cached dirty data ======"
4778
4779 # if these tests just want to test the effect of truncation,
4780 # they have to be very careful.  consider:
4781 # - the first open gets a {0,EOF}PR lock
4782 # - the first write conflicts and gets a {0, count-1}PW
4783 # - the rest of the writes are under {count,EOF}PW
4784 # - the open for truncate tries to match a {0,EOF}PR
4785 #   for the filesize and cancels the PWs.
4786 # any number of fixes (don't get {0,EOF} on open, match
4787 # composite locks, do smarter file size management) fix
4788 # this, but for now we want these tests to verify that
4789 # the cancellation with truncate intent works, so we
4790 # start the file with a full-file pw lock to match against
4791 # until the truncate.
4792 trunc_test() {
4793         test=$1
4794         file=$DIR/$test
4795         offset=$2
4796         cancel_lru_locks $OSC
4797         stop_writeback
4798         # prime the file with 0,EOF PW to match
4799         touch $file
4800         $TRUNCATE $file 0
4801         sync; sync
4802         # now the real test..
4803         dd if=/dev/zero of=$file bs=1024 count=100
4804         BEFOREWRITES=`count_ost_writes`
4805         $TRUNCATE $file $offset
4806         cancel_lru_locks $OSC
4807         AFTERWRITES=`count_ost_writes`
4808         start_writeback
4809 }
4810
4811 test_42c() {
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         trunc_test 42c 1024
4815         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4816                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4817         rm $file
4818 }
4819 run_test 42c "test partial truncate of file with cached dirty data"
4820
4821 test_42d() {
4822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4823
4824         trunc_test 42d 0
4825         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4826                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4827         rm $file
4828 }
4829 run_test 42d "test complete truncate of file with cached dirty data"
4830
4831 test_42e() { # bug22074
4832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4833
4834         local TDIR=$DIR/${tdir}e
4835         local pages=16 # hardcoded 16 pages, don't change it.
4836         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4837         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4838         local max_dirty_mb
4839         local warmup_files
4840
4841         test_mkdir $DIR/${tdir}e
4842         $LFS setstripe -c 1 $TDIR
4843         createmany -o $TDIR/f $files
4844
4845         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4846
4847         # we assume that with $OSTCOUNT files, at least one of them will
4848         # be allocated on OST0.
4849         warmup_files=$((OSTCOUNT * max_dirty_mb))
4850         createmany -o $TDIR/w $warmup_files
4851
4852         # write a large amount of data into one file and sync, to get good
4853         # avail_grant number from OST.
4854         for ((i=0; i<$warmup_files; i++)); do
4855                 idx=$($LFS getstripe -i $TDIR/w$i)
4856                 [ $idx -ne 0 ] && continue
4857                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4858                 break
4859         done
4860         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4861         sync
4862         $LCTL get_param $proc_osc0/cur_dirty_bytes
4863         $LCTL get_param $proc_osc0/cur_grant_bytes
4864
4865         # create as much dirty pages as we can while not to trigger the actual
4866         # RPCs directly. but depends on the env, VFS may trigger flush during this
4867         # period, hopefully we are good.
4868         for ((i=0; i<$warmup_files; i++)); do
4869                 idx=$($LFS getstripe -i $TDIR/w$i)
4870                 [ $idx -ne 0 ] && continue
4871                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4872         done
4873         $LCTL get_param $proc_osc0/cur_dirty_bytes
4874         $LCTL get_param $proc_osc0/cur_grant_bytes
4875
4876         # perform the real test
4877         $LCTL set_param $proc_osc0/rpc_stats 0
4878         for ((;i<$files; i++)); do
4879                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4880                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4881         done
4882         sync
4883         $LCTL get_param $proc_osc0/rpc_stats
4884
4885         local percent=0
4886         local have_ppr=false
4887         $LCTL get_param $proc_osc0/rpc_stats |
4888                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4889                         # skip lines until we are at the RPC histogram data
4890                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4891                         $have_ppr || continue
4892
4893                         # we only want the percent stat for < 16 pages
4894                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4895
4896                         percent=$((percent + WPCT))
4897                         if [[ $percent -gt 15 ]]; then
4898                                 error "less than 16-pages write RPCs" \
4899                                       "$percent% > 15%"
4900                                 break
4901                         fi
4902                 done
4903         rm -rf $TDIR
4904 }
4905 run_test 42e "verify sub-RPC writes are not done synchronously"
4906
4907 test_43A() { # was test_43
4908         test_mkdir $DIR/$tdir
4909         cp -p /bin/ls $DIR/$tdir/$tfile
4910         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4911         pid=$!
4912         # give multiop a chance to open
4913         sleep 1
4914
4915         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4916         kill -USR1 $pid
4917         # Wait for multiop to exit
4918         wait $pid
4919 }
4920 run_test 43A "execution of file opened for write should return -ETXTBSY"
4921
4922 test_43a() {
4923         test_mkdir $DIR/$tdir
4924         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4925         $DIR/$tdir/sleep 60 &
4926         SLEEP_PID=$!
4927         # Make sure exec of $tdir/sleep wins race with truncate
4928         sleep 1
4929         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4930         kill $SLEEP_PID
4931 }
4932 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4933
4934 test_43b() {
4935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4936
4937         test_mkdir $DIR/$tdir
4938         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4939         $DIR/$tdir/sleep 60 &
4940         SLEEP_PID=$!
4941         # Make sure exec of $tdir/sleep wins race with truncate
4942         sleep 1
4943         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4944         kill $SLEEP_PID
4945 }
4946 run_test 43b "truncate of file being executed should return -ETXTBSY"
4947
4948 test_43c() {
4949         local testdir="$DIR/$tdir"
4950         test_mkdir $testdir
4951         cp $SHELL $testdir/
4952         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4953                 ( cd $testdir && md5sum -c )
4954 }
4955 run_test 43c "md5sum of copy into lustre"
4956
4957 test_44A() { # was test_44
4958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4959
4960         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4961         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4962 }
4963 run_test 44A "zero length read from a sparse stripe"
4964
4965 test_44a() {
4966         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4967                 awk '{ print $2 }')
4968         [ -z "$nstripe" ] && skip "can't get stripe info"
4969         [[ $nstripe -gt $OSTCOUNT ]] &&
4970                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4971
4972         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4973                 awk '{ print $2 }')
4974         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4975                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4976                         awk '{ print $2 }')
4977         fi
4978
4979         OFFSETS="0 $((stride/2)) $((stride-1))"
4980         for offset in $OFFSETS; do
4981                 for i in $(seq 0 $((nstripe-1))); do
4982                         local GLOBALOFFSETS=""
4983                         # size in Bytes
4984                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4985                         local myfn=$DIR/d44a-$size
4986                         echo "--------writing $myfn at $size"
4987                         ll_sparseness_write $myfn $size ||
4988                                 error "ll_sparseness_write"
4989                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4990                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4991                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4992
4993                         for j in $(seq 0 $((nstripe-1))); do
4994                                 # size in Bytes
4995                                 size=$((((j + $nstripe )*$stride + $offset)))
4996                                 ll_sparseness_write $myfn $size ||
4997                                         error "ll_sparseness_write"
4998                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4999                         done
5000                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5001                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5002                         rm -f $myfn
5003                 done
5004         done
5005 }
5006 run_test 44a "test sparse pwrite ==============================="
5007
5008 dirty_osc_total() {
5009         tot=0
5010         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5011                 tot=$(($tot + $d))
5012         done
5013         echo $tot
5014 }
5015 do_dirty_record() {
5016         before=`dirty_osc_total`
5017         echo executing "\"$*\""
5018         eval $*
5019         after=`dirty_osc_total`
5020         echo before $before, after $after
5021 }
5022 test_45() {
5023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5024
5025         f="$DIR/f45"
5026         # Obtain grants from OST if it supports it
5027         echo blah > ${f}_grant
5028         stop_writeback
5029         sync
5030         do_dirty_record "echo blah > $f"
5031         [[ $before -eq $after ]] && error "write wasn't cached"
5032         do_dirty_record "> $f"
5033         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5034         do_dirty_record "echo blah > $f"
5035         [[ $before -eq $after ]] && error "write wasn't cached"
5036         do_dirty_record "sync"
5037         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5038         do_dirty_record "echo blah > $f"
5039         [[ $before -eq $after ]] && error "write wasn't cached"
5040         do_dirty_record "cancel_lru_locks osc"
5041         [[ $before -gt $after ]] ||
5042                 error "lock cancellation didn't lower dirty count"
5043         start_writeback
5044 }
5045 run_test 45 "osc io page accounting ============================"
5046
5047 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5048 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5049 # objects offset and an assert hit when an rpc was built with 1023's mapped
5050 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5051 test_46() {
5052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5053
5054         f="$DIR/f46"
5055         stop_writeback
5056         sync
5057         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5058         sync
5059         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5060         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5061         sync
5062         start_writeback
5063 }
5064 run_test 46 "dirtying a previously written page ================"
5065
5066 # test_47 is removed "Device nodes check" is moved to test_28
5067
5068 test_48a() { # bug 2399
5069         [ "$mds1_FSTYPE" = "zfs" ] &&
5070         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5071                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5072
5073         test_mkdir $DIR/$tdir
5074         cd $DIR/$tdir
5075         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5076         test_mkdir $DIR/$tdir
5077         touch foo || error "'touch foo' failed after recreating cwd"
5078         test_mkdir bar
5079         touch .foo || error "'touch .foo' failed after recreating cwd"
5080         test_mkdir .bar
5081         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5082         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5083         cd . || error "'cd .' failed after recreating cwd"
5084         mkdir . && error "'mkdir .' worked after recreating cwd"
5085         rmdir . && error "'rmdir .' worked after recreating cwd"
5086         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5087         cd .. || error "'cd ..' failed after recreating cwd"
5088 }
5089 run_test 48a "Access renamed working dir (should return errors)="
5090
5091 test_48b() { # bug 2399
5092         rm -rf $DIR/$tdir
5093         test_mkdir $DIR/$tdir
5094         cd $DIR/$tdir
5095         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5096         touch foo && error "'touch foo' worked after removing cwd"
5097         mkdir foo && error "'mkdir foo' worked after removing cwd"
5098         touch .foo && error "'touch .foo' worked after removing cwd"
5099         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5100         ls . > /dev/null && error "'ls .' worked after removing cwd"
5101         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5102         mkdir . && error "'mkdir .' worked after removing cwd"
5103         rmdir . && error "'rmdir .' worked after removing cwd"
5104         ln -s . foo && error "'ln -s .' worked after removing cwd"
5105         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5106 }
5107 run_test 48b "Access removed working dir (should return errors)="
5108
5109 test_48c() { # bug 2350
5110         #lctl set_param debug=-1
5111         #set -vx
5112         rm -rf $DIR/$tdir
5113         test_mkdir -p $DIR/$tdir/dir
5114         cd $DIR/$tdir/dir
5115         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5116         $TRACE touch foo && error "touch foo worked after removing cwd"
5117         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5118         touch .foo && error "touch .foo worked after removing cwd"
5119         mkdir .foo && error "mkdir .foo worked after removing cwd"
5120         $TRACE ls . && error "'ls .' worked after removing cwd"
5121         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5122         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5123         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5124         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5125         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5126 }
5127 run_test 48c "Access removed working subdir (should return errors)"
5128
5129 test_48d() { # bug 2350
5130         #lctl set_param debug=-1
5131         #set -vx
5132         rm -rf $DIR/$tdir
5133         test_mkdir -p $DIR/$tdir/dir
5134         cd $DIR/$tdir/dir
5135         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5136         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5137         $TRACE touch foo && error "'touch foo' worked after removing parent"
5138         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5139         touch .foo && error "'touch .foo' worked after removing parent"
5140         mkdir .foo && error "mkdir .foo worked after removing parent"
5141         $TRACE ls . && error "'ls .' worked after removing parent"
5142         $TRACE ls .. && error "'ls ..' worked after removing parent"
5143         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5144         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5145         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5146         true
5147 }
5148 run_test 48d "Access removed parent subdir (should return errors)"
5149
5150 test_48e() { # bug 4134
5151         #lctl set_param debug=-1
5152         #set -vx
5153         rm -rf $DIR/$tdir
5154         test_mkdir -p $DIR/$tdir/dir
5155         cd $DIR/$tdir/dir
5156         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5157         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5158         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5159         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5160         # On a buggy kernel addition of "touch foo" after cd .. will
5161         # produce kernel oops in lookup_hash_it
5162         touch ../foo && error "'cd ..' worked after recreate parent"
5163         cd $DIR
5164         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5165 }
5166 run_test 48e "Access to recreated parent subdir (should return errors)"
5167
5168 test_48f() {
5169         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5170                 skip "need MDS >= 2.13.55"
5171         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5172         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5173                 skip "needs different host for mdt1 mdt2"
5174         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5175
5176         $LFS mkdir -i0 $DIR/$tdir
5177         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5178
5179         for d in sub1 sub2 sub3; do
5180                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5181                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5182                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5183         done
5184
5185         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5186 }
5187 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5188
5189 test_49() { # LU-1030
5190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5191         remote_ost_nodsh && skip "remote OST with nodsh"
5192
5193         # get ost1 size - $FSNAME-OST0000
5194         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5195                 awk '{ print $4 }')
5196         # write 800M at maximum
5197         [[ $ost1_size -lt 2 ]] && ost1_size=2
5198         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5199
5200         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5201         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5202         local dd_pid=$!
5203
5204         # change max_pages_per_rpc while writing the file
5205         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5206         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5207         # loop until dd process exits
5208         while ps ax -opid | grep -wq $dd_pid; do
5209                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5210                 sleep $((RANDOM % 5 + 1))
5211         done
5212         # restore original max_pages_per_rpc
5213         $LCTL set_param $osc1_mppc=$orig_mppc
5214         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5215 }
5216 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5217
5218 test_50() {
5219         # bug 1485
5220         test_mkdir $DIR/$tdir
5221         cd $DIR/$tdir
5222         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5223 }
5224 run_test 50 "special situations: /proc symlinks  ==============="
5225
5226 test_51a() {    # was test_51
5227         # bug 1516 - create an empty entry right after ".." then split dir
5228         test_mkdir -c1 $DIR/$tdir
5229         touch $DIR/$tdir/foo
5230         $MCREATE $DIR/$tdir/bar
5231         rm $DIR/$tdir/foo
5232         createmany -m $DIR/$tdir/longfile 201
5233         FNUM=202
5234         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5235                 $MCREATE $DIR/$tdir/longfile$FNUM
5236                 FNUM=$(($FNUM + 1))
5237                 echo -n "+"
5238         done
5239         echo
5240         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5241 }
5242 run_test 51a "special situations: split htree with empty entry =="
5243
5244 cleanup_print_lfs_df () {
5245         trap 0
5246         $LFS df
5247         $LFS df -i
5248 }
5249
5250 test_51b() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252
5253         local dir=$DIR/$tdir
5254         local nrdirs=$((65536 + 100))
5255
5256         # cleanup the directory
5257         rm -fr $dir
5258
5259         test_mkdir -c1 $dir
5260
5261         $LFS df
5262         $LFS df -i
5263         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5264         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5265         [[ $numfree -lt $nrdirs ]] &&
5266                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5267
5268         # need to check free space for the directories as well
5269         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5270         numfree=$(( blkfree / $(fs_inode_ksize) ))
5271         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5272
5273         trap cleanup_print_lfs_df EXIT
5274
5275         # create files
5276         createmany -d $dir/d $nrdirs || {
5277                 unlinkmany $dir/d $nrdirs
5278                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5279         }
5280
5281         # really created :
5282         nrdirs=$(ls -U $dir | wc -l)
5283
5284         # unlink all but 100 subdirectories, then check it still works
5285         local left=100
5286         local delete=$((nrdirs - left))
5287
5288         $LFS df
5289         $LFS df -i
5290
5291         # for ldiskfs the nlink count should be 1, but this is OSD specific
5292         # and so this is listed for informational purposes only
5293         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5294         unlinkmany -d $dir/d $delete ||
5295                 error "unlink of first $delete subdirs failed"
5296
5297         echo "nlink between: $(stat -c %h $dir)"
5298         local found=$(ls -U $dir | wc -l)
5299         [ $found -ne $left ] &&
5300                 error "can't find subdirs: found only $found, expected $left"
5301
5302         unlinkmany -d $dir/d $delete $left ||
5303                 error "unlink of second $left subdirs failed"
5304         # regardless of whether the backing filesystem tracks nlink accurately
5305         # or not, the nlink count shouldn't be more than "." and ".." here
5306         local after=$(stat -c %h $dir)
5307         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5308                 echo "nlink after: $after"
5309
5310         cleanup_print_lfs_df
5311 }
5312 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5313
5314 test_51d() {
5315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5316         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5317
5318         test_mkdir $DIR/$tdir
5319         createmany -o $DIR/$tdir/t- 1000
5320         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5321         for N in $(seq 0 $((OSTCOUNT - 1))); do
5322                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5323                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5324                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5325                         '($1 == '$N') { objs += 1 } \
5326                         END { printf("%0.0f", objs) }')
5327                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5328         done
5329         unlinkmany $DIR/$tdir/t- 1000
5330
5331         NLAST=0
5332         for N in $(seq 1 $((OSTCOUNT - 1))); do
5333                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5334                         error "OST $N has less objects vs OST $NLAST" \
5335                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5336                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5337                         error "OST $N has less objects vs OST $NLAST" \
5338                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5339
5340                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5341                         error "OST $N has less #0 objects vs OST $NLAST" \
5342                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5343                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5344                         error "OST $N has less #0 objects vs OST $NLAST" \
5345                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5346                 NLAST=$N
5347         done
5348         rm -f $TMP/$tfile
5349 }
5350 run_test 51d "check object distribution"
5351
5352 test_51e() {
5353         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5354                 skip_env "ldiskfs only test"
5355         fi
5356
5357         test_mkdir -c1 $DIR/$tdir
5358         test_mkdir -c1 $DIR/$tdir/d0
5359
5360         touch $DIR/$tdir/d0/foo
5361         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5362                 error "file exceed 65000 nlink limit!"
5363         unlinkmany $DIR/$tdir/d0/f- 65001
5364         return 0
5365 }
5366 run_test 51e "check file nlink limit"
5367
5368 test_51f() {
5369         test_mkdir $DIR/$tdir
5370
5371         local max=100000
5372         local ulimit_old=$(ulimit -n)
5373         local spare=20 # number of spare fd's for scripts/libraries, etc.
5374         local mdt=$($LFS getstripe -m $DIR/$tdir)
5375         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5376
5377         echo "MDT$mdt numfree=$numfree, max=$max"
5378         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5379         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5380                 while ! ulimit -n $((numfree + spare)); do
5381                         numfree=$((numfree * 3 / 4))
5382                 done
5383                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5384         else
5385                 echo "left ulimit at $ulimit_old"
5386         fi
5387
5388         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5389                 unlinkmany $DIR/$tdir/f $numfree
5390                 error "create+open $numfree files in $DIR/$tdir failed"
5391         }
5392         ulimit -n $ulimit_old
5393
5394         # if createmany exits at 120s there will be fewer than $numfree files
5395         unlinkmany $DIR/$tdir/f $numfree || true
5396 }
5397 run_test 51f "check many open files limit"
5398
5399 test_52a() {
5400         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5401         test_mkdir $DIR/$tdir
5402         touch $DIR/$tdir/foo
5403         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5404         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5405         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5406         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5407         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5408                                         error "link worked"
5409         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5410         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5411         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5412                                                      error "lsattr"
5413         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5414         cp -r $DIR/$tdir $TMP/
5415         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5416 }
5417 run_test 52a "append-only flag test (should return errors)"
5418
5419 test_52b() {
5420         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5421         test_mkdir $DIR/$tdir
5422         touch $DIR/$tdir/foo
5423         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5424         cat test > $DIR/$tdir/foo && error "cat test worked"
5425         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5426         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5427         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5428                                         error "link worked"
5429         echo foo >> $DIR/$tdir/foo && error "echo worked"
5430         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5431         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5432         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5433         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5434                                                         error "lsattr"
5435         chattr -i $DIR/$tdir/foo || error "chattr failed"
5436
5437         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5438 }
5439 run_test 52b "immutable flag test (should return errors) ======="
5440
5441 test_53() {
5442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5443         remote_mds_nodsh && skip "remote MDS with nodsh"
5444         remote_ost_nodsh && skip "remote OST with nodsh"
5445
5446         local param
5447         local param_seq
5448         local ostname
5449         local mds_last
5450         local mds_last_seq
5451         local ost_last
5452         local ost_last_seq
5453         local ost_last_id
5454         local ostnum
5455         local node
5456         local found=false
5457         local support_last_seq=true
5458
5459         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5460                 support_last_seq=false
5461
5462         # only test MDT0000
5463         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5464         local value
5465         for value in $(do_facet $SINGLEMDS \
5466                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5467                 param=$(echo ${value[0]} | cut -d "=" -f1)
5468                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5469
5470                 if $support_last_seq; then
5471                         param_seq=$(echo $param |
5472                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5473                         mds_last_seq=$(do_facet $SINGLEMDS \
5474                                        $LCTL get_param -n $param_seq)
5475                 fi
5476                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5477
5478                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5479                 node=$(facet_active_host ost$((ostnum+1)))
5480                 param="obdfilter.$ostname.last_id"
5481                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5482                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5483                         ost_last_id=$ost_last
5484
5485                         if $support_last_seq; then
5486                                 ost_last_id=$(echo $ost_last |
5487                                               awk -F':' '{print $2}' |
5488                                               sed -e "s/^0x//g")
5489                                 ost_last_seq=$(echo $ost_last |
5490                                                awk -F':' '{print $1}')
5491                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5492                         fi
5493
5494                         if [[ $ost_last_id != $mds_last ]]; then
5495                                 error "$ost_last_id != $mds_last"
5496                         else
5497                                 found=true
5498                                 break
5499                         fi
5500                 done
5501         done
5502         $found || error "can not match last_seq/last_id for $mdtosc"
5503         return 0
5504 }
5505 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5506
5507 test_54a() {
5508         perl -MSocket -e ';' || skip "no Socket perl module installed"
5509
5510         $SOCKETSERVER $DIR/socket ||
5511                 error "$SOCKETSERVER $DIR/socket failed: $?"
5512         $SOCKETCLIENT $DIR/socket ||
5513                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5514         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5515 }
5516 run_test 54a "unix domain socket test =========================="
5517
5518 test_54b() {
5519         f="$DIR/f54b"
5520         mknod $f c 1 3
5521         chmod 0666 $f
5522         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5523 }
5524 run_test 54b "char device works in lustre ======================"
5525
5526 find_loop_dev() {
5527         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5528         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5529         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5530
5531         for i in $(seq 3 7); do
5532                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5533                 LOOPDEV=$LOOPBASE$i
5534                 LOOPNUM=$i
5535                 break
5536         done
5537 }
5538
5539 cleanup_54c() {
5540         local rc=0
5541         loopdev="$DIR/loop54c"
5542
5543         trap 0
5544         $UMOUNT $DIR/$tdir || rc=$?
5545         losetup -d $loopdev || true
5546         losetup -d $LOOPDEV || true
5547         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5548         return $rc
5549 }
5550
5551 test_54c() {
5552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5553
5554         loopdev="$DIR/loop54c"
5555
5556         find_loop_dev
5557         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5558         trap cleanup_54c EXIT
5559         mknod $loopdev b 7 $LOOPNUM
5560         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5561         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5562         losetup $loopdev $DIR/$tfile ||
5563                 error "can't set up $loopdev for $DIR/$tfile"
5564         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5565         test_mkdir $DIR/$tdir
5566         mount -t ext2 $loopdev $DIR/$tdir ||
5567                 error "error mounting $loopdev on $DIR/$tdir"
5568         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5569                 error "dd write"
5570         df $DIR/$tdir
5571         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5572                 error "dd read"
5573         cleanup_54c
5574 }
5575 run_test 54c "block device works in lustre ====================="
5576
5577 test_54d() {
5578         f="$DIR/f54d"
5579         string="aaaaaa"
5580         mknod $f p
5581         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5582 }
5583 run_test 54d "fifo device works in lustre ======================"
5584
5585 test_54e() {
5586         f="$DIR/f54e"
5587         string="aaaaaa"
5588         cp -aL /dev/console $f
5589         echo $string > $f || error "echo $string to $f failed"
5590 }
5591 run_test 54e "console/tty device works in lustre ======================"
5592
5593 test_56a() {
5594         local numfiles=3
5595         local dir=$DIR/$tdir
5596
5597         rm -rf $dir
5598         test_mkdir -p $dir/dir
5599         for i in $(seq $numfiles); do
5600                 touch $dir/file$i
5601                 touch $dir/dir/file$i
5602         done
5603
5604         local numcomp=$($LFS getstripe --component-count $dir)
5605
5606         [[ $numcomp == 0 ]] && numcomp=1
5607
5608         # test lfs getstripe with --recursive
5609         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5610
5611         [[ $filenum -eq $((numfiles * 2)) ]] ||
5612                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5613         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5614         [[ $filenum -eq $numfiles ]] ||
5615                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5616         echo "$LFS getstripe showed obdidx or l_ost_idx"
5617
5618         # test lfs getstripe with file instead of dir
5619         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5620         [[ $filenum -eq 1 ]] ||
5621                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5622         echo "$LFS getstripe file1 passed"
5623
5624         #test lfs getstripe with --verbose
5625         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5626         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5627                 error "$LFS getstripe --verbose $dir: "\
5628                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5629         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5630                 error "$LFS getstripe $dir: showed lmm_magic"
5631
5632         #test lfs getstripe with -v prints lmm_fid
5633         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5634         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5635                 error "$LFS getstripe -v $dir: "\
5636                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5637         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5638                 error "$LFS getstripe $dir: showed lmm_fid by default"
5639         echo "$LFS getstripe --verbose passed"
5640
5641         #check for FID information
5642         local fid1=$($LFS getstripe --fid $dir/file1)
5643         local fid2=$($LFS getstripe --verbose $dir/file1 |
5644                      awk '/lmm_fid: / { print $2; exit; }')
5645         local fid3=$($LFS path2fid $dir/file1)
5646
5647         [ "$fid1" != "$fid2" ] &&
5648                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5649         [ "$fid1" != "$fid3" ] &&
5650                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5651         echo "$LFS getstripe --fid passed"
5652
5653         #test lfs getstripe with --obd
5654         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5655                 error "$LFS getstripe --obd wrong_uuid: should return error"
5656
5657         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5658
5659         local ostidx=1
5660         local obduuid=$(ostuuid_from_index $ostidx)
5661         local found=$($LFS getstripe -r --obd $obduuid $dir |
5662                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5663
5664         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5665         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5666                 ((filenum--))
5667         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5668                 ((filenum--))
5669
5670         [[ $found -eq $filenum ]] ||
5671                 error "$LFS getstripe --obd: found $found expect $filenum"
5672         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5673                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5674                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5675                 error "$LFS getstripe --obd: should not show file on other obd"
5676         echo "$LFS getstripe --obd passed"
5677 }
5678 run_test 56a "check $LFS getstripe"
5679
5680 test_56b() {
5681         local dir=$DIR/$tdir
5682         local numdirs=3
5683
5684         test_mkdir $dir
5685         for i in $(seq $numdirs); do
5686                 test_mkdir $dir/dir$i
5687         done
5688
5689         # test lfs getdirstripe default mode is non-recursion, which is
5690         # different from lfs getstripe
5691         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5692
5693         [[ $dircnt -eq 1 ]] ||
5694                 error "$LFS getdirstripe: found $dircnt, not 1"
5695         dircnt=$($LFS getdirstripe --recursive $dir |
5696                 grep -c lmv_stripe_count)
5697         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5698                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5699 }
5700 run_test 56b "check $LFS getdirstripe"
5701
5702 test_56c() {
5703         remote_ost_nodsh && skip "remote OST with nodsh"
5704
5705         local ost_idx=0
5706         local ost_name=$(ostname_from_index $ost_idx)
5707         local old_status=$(ost_dev_status $ost_idx)
5708         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5709
5710         [[ -z "$old_status" ]] ||
5711                 skip_env "OST $ost_name is in $old_status status"
5712
5713         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5714         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5715                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5716         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5717                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5718                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5719         fi
5720
5721         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5722                 error "$LFS df -v showing inactive devices"
5723         sleep_maxage
5724
5725         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5726
5727         [[ "$new_status" =~ "D" ]] ||
5728                 error "$ost_name status is '$new_status', missing 'D'"
5729         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5730                 [[ "$new_status" =~ "N" ]] ||
5731                         error "$ost_name status is '$new_status', missing 'N'"
5732         fi
5733         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5734                 [[ "$new_status" =~ "f" ]] ||
5735                         error "$ost_name status is '$new_status', missing 'f'"
5736         fi
5737
5738         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5739         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5740                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5741         [[ -z "$p" ]] && restore_lustre_params < $p || true
5742         sleep_maxage
5743
5744         new_status=$(ost_dev_status $ost_idx)
5745         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5746                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5747         # can't check 'f' as devices may actually be on flash
5748 }
5749 run_test 56c "check 'lfs df' showing device status"
5750
5751 test_56d() {
5752         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5753         local osts=$($LFS df -v $MOUNT | grep -c OST)
5754
5755         $LFS df $MOUNT
5756
5757         (( mdts == MDSCOUNT )) ||
5758                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5759         (( osts == OSTCOUNT )) ||
5760                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5761 }
5762 run_test 56d "'lfs df -v' prints only configured devices"
5763
5764 NUMFILES=3
5765 NUMDIRS=3
5766 setup_56() {
5767         local local_tdir="$1"
5768         local local_numfiles="$2"
5769         local local_numdirs="$3"
5770         local dir_params="$4"
5771         local dir_stripe_params="$5"
5772
5773         if [ ! -d "$local_tdir" ] ; then
5774                 test_mkdir -p $dir_stripe_params $local_tdir
5775                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5776                 for i in $(seq $local_numfiles) ; do
5777                         touch $local_tdir/file$i
5778                 done
5779                 for i in $(seq $local_numdirs) ; do
5780                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5781                         for j in $(seq $local_numfiles) ; do
5782                                 touch $local_tdir/dir$i/file$j
5783                         done
5784                 done
5785         fi
5786 }
5787
5788 setup_56_special() {
5789         local local_tdir=$1
5790         local local_numfiles=$2
5791         local local_numdirs=$3
5792
5793         setup_56 $local_tdir $local_numfiles $local_numdirs
5794
5795         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5796                 for i in $(seq $local_numfiles) ; do
5797                         mknod $local_tdir/loop${i}b b 7 $i
5798                         mknod $local_tdir/null${i}c c 1 3
5799                         ln -s $local_tdir/file1 $local_tdir/link${i}
5800                 done
5801                 for i in $(seq $local_numdirs) ; do
5802                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5803                         mknod $local_tdir/dir$i/null${i}c c 1 3
5804                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5805                 done
5806         fi
5807 }
5808
5809 test_56g() {
5810         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5811         local expected=$(($NUMDIRS + 2))
5812
5813         setup_56 $dir $NUMFILES $NUMDIRS
5814
5815         # test lfs find with -name
5816         for i in $(seq $NUMFILES) ; do
5817                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5818
5819                 [ $nums -eq $expected ] ||
5820                         error "lfs find -name '*$i' $dir wrong: "\
5821                               "found $nums, expected $expected"
5822         done
5823 }
5824 run_test 56g "check lfs find -name"
5825
5826 test_56h() {
5827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5828         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5829
5830         setup_56 $dir $NUMFILES $NUMDIRS
5831
5832         # test lfs find with ! -name
5833         for i in $(seq $NUMFILES) ; do
5834                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5835
5836                 [ $nums -eq $expected ] ||
5837                         error "lfs find ! -name '*$i' $dir wrong: "\
5838                               "found $nums, expected $expected"
5839         done
5840 }
5841 run_test 56h "check lfs find ! -name"
5842
5843 test_56i() {
5844         local dir=$DIR/$tdir
5845
5846         test_mkdir $dir
5847
5848         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5849         local out=$($cmd)
5850
5851         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5852 }
5853 run_test 56i "check 'lfs find -ost UUID' skips directories"
5854
5855 test_56j() {
5856         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5857
5858         setup_56_special $dir $NUMFILES $NUMDIRS
5859
5860         local expected=$((NUMDIRS + 1))
5861         local cmd="$LFS find -type d $dir"
5862         local nums=$($cmd | wc -l)
5863
5864         [ $nums -eq $expected ] ||
5865                 error "'$cmd' wrong: found $nums, expected $expected"
5866 }
5867 run_test 56j "check lfs find -type d"
5868
5869 test_56k() {
5870         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5871
5872         setup_56_special $dir $NUMFILES $NUMDIRS
5873
5874         local expected=$(((NUMDIRS + 1) * NUMFILES))
5875         local cmd="$LFS find -type f $dir"
5876         local nums=$($cmd | wc -l)
5877
5878         [ $nums -eq $expected ] ||
5879                 error "'$cmd' wrong: found $nums, expected $expected"
5880 }
5881 run_test 56k "check lfs find -type f"
5882
5883 test_56l() {
5884         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5885
5886         setup_56_special $dir $NUMFILES $NUMDIRS
5887
5888         local expected=$((NUMDIRS + NUMFILES))
5889         local cmd="$LFS find -type b $dir"
5890         local nums=$($cmd | wc -l)
5891
5892         [ $nums -eq $expected ] ||
5893                 error "'$cmd' wrong: found $nums, expected $expected"
5894 }
5895 run_test 56l "check lfs find -type b"
5896
5897 test_56m() {
5898         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5899
5900         setup_56_special $dir $NUMFILES $NUMDIRS
5901
5902         local expected=$((NUMDIRS + NUMFILES))
5903         local cmd="$LFS find -type c $dir"
5904         local nums=$($cmd | wc -l)
5905         [ $nums -eq $expected ] ||
5906                 error "'$cmd' wrong: found $nums, expected $expected"
5907 }
5908 run_test 56m "check lfs find -type c"
5909
5910 test_56n() {
5911         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5912         setup_56_special $dir $NUMFILES $NUMDIRS
5913
5914         local expected=$((NUMDIRS + NUMFILES))
5915         local cmd="$LFS find -type l $dir"
5916         local nums=$($cmd | wc -l)
5917
5918         [ $nums -eq $expected ] ||
5919                 error "'$cmd' wrong: found $nums, expected $expected"
5920 }
5921 run_test 56n "check lfs find -type l"
5922
5923 test_56o() {
5924         local dir=$DIR/$tdir
5925
5926         setup_56 $dir $NUMFILES $NUMDIRS
5927         utime $dir/file1 > /dev/null || error "utime (1)"
5928         utime $dir/file2 > /dev/null || error "utime (2)"
5929         utime $dir/dir1 > /dev/null || error "utime (3)"
5930         utime $dir/dir2 > /dev/null || error "utime (4)"
5931         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5932         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5933
5934         local expected=4
5935         local nums=$($LFS find -mtime +0 $dir | wc -l)
5936
5937         [ $nums -eq $expected ] ||
5938                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5939
5940         expected=12
5941         cmd="$LFS find -mtime 0 $dir"
5942         nums=$($cmd | wc -l)
5943         [ $nums -eq $expected ] ||
5944                 error "'$cmd' wrong: found $nums, expected $expected"
5945 }
5946 run_test 56o "check lfs find -mtime for old files"
5947
5948 test_56ob() {
5949         local dir=$DIR/$tdir
5950         local expected=1
5951         local count=0
5952
5953         # just to make sure there is something that won't be found
5954         test_mkdir $dir
5955         touch $dir/$tfile.now
5956
5957         for age in year week day hour min; do
5958                 count=$((count + 1))
5959
5960                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5961                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5962                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5963
5964                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5965                 local nums=$($cmd | wc -l)
5966                 [ $nums -eq $expected ] ||
5967                         error "'$cmd' wrong: found $nums, expected $expected"
5968
5969                 cmd="$LFS find $dir -atime $count${age:0:1}"
5970                 nums=$($cmd | wc -l)
5971                 [ $nums -eq $expected ] ||
5972                         error "'$cmd' wrong: found $nums, expected $expected"
5973         done
5974
5975         sleep 2
5976         cmd="$LFS find $dir -ctime +1s -type f"
5977         nums=$($cmd | wc -l)
5978         (( $nums == $count * 2 + 1)) ||
5979                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5980 }
5981 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5982
5983 test_newerXY_base() {
5984         local x=$1
5985         local y=$2
5986         local dir=$DIR/$tdir
5987         local ref
5988         local negref
5989
5990         if [ $y == "t" ]; then
5991                 if [ $x == "b" ]; then
5992                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5993                 else
5994                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5995                 fi
5996         else
5997                 ref=$DIR/$tfile.newer.$x$y
5998                 touch $ref || error "touch $ref failed"
5999         fi
6000
6001         echo "before = $ref"
6002         sleep 2
6003         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6004         sleep 2
6005         if [ $y == "t" ]; then
6006                 if [ $x == "b" ]; then
6007                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6008                 else
6009                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6010                 fi
6011         else
6012                 negref=$DIR/$tfile.negnewer.$x$y
6013                 touch $negref || error "touch $negref failed"
6014         fi
6015
6016         echo "after = $negref"
6017         local cmd="$LFS find $dir -newer$x$y $ref"
6018         local nums=$(eval $cmd | wc -l)
6019         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6020
6021         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6022                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6023
6024         cmd="$LFS find $dir ! -newer$x$y $negref"
6025         nums=$(eval $cmd | wc -l)
6026         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6027                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6028
6029         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6030         nums=$(eval $cmd | wc -l)
6031         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6032                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6033
6034         rm -rf $DIR/*
6035 }
6036
6037 test_56oc() {
6038         test_newerXY_base "a" "a"
6039         test_newerXY_base "a" "m"
6040         test_newerXY_base "a" "c"
6041         test_newerXY_base "m" "a"
6042         test_newerXY_base "m" "m"
6043         test_newerXY_base "m" "c"
6044         test_newerXY_base "c" "a"
6045         test_newerXY_base "c" "m"
6046         test_newerXY_base "c" "c"
6047
6048         [[ -n "$sles_version" ]] &&
6049                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6050
6051         test_newerXY_base "a" "t"
6052         test_newerXY_base "m" "t"
6053         test_newerXY_base "c" "t"
6054
6055         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6056            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6057                 ! btime_supported && echo "btime unsupported" && return 0
6058
6059         test_newerXY_base "b" "b"
6060         test_newerXY_base "b" "t"
6061 }
6062 run_test 56oc "check lfs find -newerXY work"
6063
6064 btime_supported() {
6065         local dir=$DIR/$tdir
6066         local rc
6067
6068         mkdir -p $dir
6069         touch $dir/$tfile
6070         $LFS find $dir -btime -1d -type f
6071         rc=$?
6072         rm -rf $dir
6073         return $rc
6074 }
6075
6076 test_56od() {
6077         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6078                 ! btime_supported && skip "btime unsupported on MDS"
6079
6080         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6081                 ! btime_supported && skip "btime unsupported on clients"
6082
6083         local dir=$DIR/$tdir
6084         local ref=$DIR/$tfile.ref
6085         local negref=$DIR/$tfile.negref
6086
6087         mkdir $dir || error "mkdir $dir failed"
6088         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6089         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6090         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6091         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6092         touch $ref || error "touch $ref failed"
6093         # sleep 3 seconds at least
6094         sleep 3
6095
6096         local before=$(do_facet mds1 date +%s)
6097         local skew=$(($(date +%s) - before + 1))
6098
6099         if (( skew < 0 && skew > -5 )); then
6100                 sleep $((0 - skew + 1))
6101                 skew=0
6102         fi
6103
6104         # Set the dir stripe params to limit files all on MDT0,
6105         # otherwise we need to calc the max clock skew between
6106         # the client and MDTs.
6107         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6108         sleep 2
6109         touch $negref || error "touch $negref failed"
6110
6111         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6112         local nums=$($cmd | wc -l)
6113         local expected=$(((NUMFILES + 1) * NUMDIRS))
6114
6115         [ $nums -eq $expected ] ||
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117
6118         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6119         nums=$($cmd | wc -l)
6120         expected=$((NUMFILES + 1))
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123
6124         [ $skew -lt 0 ] && return
6125
6126         local after=$(do_facet mds1 date +%s)
6127         local age=$((after - before + 1 + skew))
6128
6129         cmd="$LFS find $dir -btime -${age}s -type f"
6130         nums=$($cmd | wc -l)
6131         expected=$(((NUMFILES + 1) * NUMDIRS))
6132
6133         echo "Clock skew between client and server: $skew, age:$age"
6134         [ $nums -eq $expected ] ||
6135                 error "'$cmd' wrong: found $nums, expected $expected"
6136
6137         expected=$(($NUMDIRS + 1))
6138         cmd="$LFS find $dir -btime -${age}s -type d"
6139         nums=$($cmd | wc -l)
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142         rm -f $ref $negref || error "Failed to remove $ref $negref"
6143 }
6144 run_test 56od "check lfs find -btime with units"
6145
6146 test_56p() {
6147         [ $RUNAS_ID -eq $UID ] &&
6148                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6149
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6154
6155         local expected=$NUMFILES
6156         local cmd="$LFS find -uid $RUNAS_ID $dir"
6157         local nums=$($cmd | wc -l)
6158
6159         [ $nums -eq $expected ] ||
6160                 error "'$cmd' wrong: found $nums, expected $expected"
6161
6162         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6163         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6164         nums=$($cmd | wc -l)
6165         [ $nums -eq $expected ] ||
6166                 error "'$cmd' wrong: found $nums, expected $expected"
6167 }
6168 run_test 56p "check lfs find -uid and ! -uid"
6169
6170 test_56q() {
6171         [ $RUNAS_ID -eq $UID ] &&
6172                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6173
6174         local dir=$DIR/$tdir
6175
6176         setup_56 $dir $NUMFILES $NUMDIRS
6177         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6178
6179         local expected=$NUMFILES
6180         local cmd="$LFS find -gid $RUNAS_GID $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185
6186         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6187         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6188         nums=$($cmd | wc -l)
6189         [ $nums -eq $expected ] ||
6190                 error "'$cmd' wrong: found $nums, expected $expected"
6191 }
6192 run_test 56q "check lfs find -gid and ! -gid"
6193
6194 test_56r() {
6195         local dir=$DIR/$tdir
6196
6197         setup_56 $dir $NUMFILES $NUMDIRS
6198
6199         local expected=12
6200         local cmd="$LFS find -size 0 -type f -lazy $dir"
6201         local nums=$($cmd | wc -l)
6202
6203         [ $nums -eq $expected ] ||
6204                 error "'$cmd' wrong: found $nums, expected $expected"
6205         cmd="$LFS find -size 0 -type f $dir"
6206         nums=$($cmd | wc -l)
6207         [ $nums -eq $expected ] ||
6208                 error "'$cmd' wrong: found $nums, expected $expected"
6209
6210         expected=0
6211         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] ||
6214                 error "'$cmd' wrong: found $nums, expected $expected"
6215         cmd="$LFS find ! -size 0 -type f $dir"
6216         nums=$($cmd | wc -l)
6217         [ $nums -eq $expected ] ||
6218                 error "'$cmd' wrong: found $nums, expected $expected"
6219
6220         echo "test" > $dir/$tfile
6221         echo "test2" > $dir/$tfile.2 && sync
6222         expected=1
6223         cmd="$LFS find -size 5 -type f -lazy $dir"
6224         nums=$($cmd | wc -l)
6225         [ $nums -eq $expected ] ||
6226                 error "'$cmd' wrong: found $nums, expected $expected"
6227         cmd="$LFS find -size 5 -type f $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231
6232         expected=1
6233         cmd="$LFS find -size +5 -type f -lazy $dir"
6234         nums=$($cmd | wc -l)
6235         [ $nums -eq $expected ] ||
6236                 error "'$cmd' wrong: found $nums, expected $expected"
6237         cmd="$LFS find -size +5 -type f $dir"
6238         nums=$($cmd | wc -l)
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         expected=2
6243         cmd="$LFS find -size +0 -type f -lazy $dir"
6244         nums=$($cmd | wc -l)
6245         [ $nums -eq $expected ] ||
6246                 error "'$cmd' wrong: found $nums, expected $expected"
6247         cmd="$LFS find -size +0 -type f $dir"
6248         nums=$($cmd | wc -l)
6249         [ $nums -eq $expected ] ||
6250                 error "'$cmd' wrong: found $nums, expected $expected"
6251
6252         expected=2
6253         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6254         nums=$($cmd | wc -l)
6255         [ $nums -eq $expected ] ||
6256                 error "'$cmd' wrong: found $nums, expected $expected"
6257         cmd="$LFS find ! -size -5 -type f $dir"
6258         nums=$($cmd | wc -l)
6259         [ $nums -eq $expected ] ||
6260                 error "'$cmd' wrong: found $nums, expected $expected"
6261
6262         expected=12
6263         cmd="$LFS find -size -5 -type f -lazy $dir"
6264         nums=$($cmd | wc -l)
6265         [ $nums -eq $expected ] ||
6266                 error "'$cmd' wrong: found $nums, expected $expected"
6267         cmd="$LFS find -size -5 -type f $dir"
6268         nums=$($cmd | wc -l)
6269         [ $nums -eq $expected ] ||
6270                 error "'$cmd' wrong: found $nums, expected $expected"
6271 }
6272 run_test 56r "check lfs find -size works"
6273
6274 test_56ra_sub() {
6275         local expected=$1
6276         local glimpses=$2
6277         local cmd="$3"
6278
6279         cancel_lru_locks $OSC
6280
6281         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6282         local nums=$($cmd | wc -l)
6283
6284         [ $nums -eq $expected ] ||
6285                 error "'$cmd' wrong: found $nums, expected $expected"
6286
6287         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6288
6289         if (( rpcs_before + glimpses != rpcs_after )); then
6290                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6291                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6292
6293                 if [[ $glimpses == 0 ]]; then
6294                         error "'$cmd' should not send glimpse RPCs to OST"
6295                 else
6296                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6297                 fi
6298         fi
6299 }
6300
6301 test_56ra() {
6302         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6303                 skip "MDS < 2.12.58 doesn't return LSOM data"
6304         local dir=$DIR/$tdir
6305         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6306
6307         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6308
6309         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6310         $LCTL set_param -n llite.*.statahead_agl=0
6311         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6312
6313         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6314         # open and close all files to ensure LSOM is updated
6315         cancel_lru_locks $OSC
6316         find $dir -type f | xargs cat > /dev/null
6317
6318         #   expect_found  glimpse_rpcs  command_to_run
6319         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6320         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6321         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6322         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6323
6324         echo "test" > $dir/$tfile
6325         echo "test2" > $dir/$tfile.2 && sync
6326         cancel_lru_locks $OSC
6327         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6328
6329         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6330         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6331         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6332         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6333
6334         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6335         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6336         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6337         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6338         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6339         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6340 }
6341 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6342
6343 test_56rb() {
6344         local dir=$DIR/$tdir
6345         local tmp=$TMP/$tfile.log
6346         local mdt_idx;
6347
6348         test_mkdir -p $dir || error "failed to mkdir $dir"
6349         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6350                 error "failed to setstripe $dir/$tfile"
6351         mdt_idx=$($LFS getdirstripe -i $dir)
6352         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6353
6354         stack_trap "rm -f $tmp" EXIT
6355         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6356         ! grep -q obd_uuid $tmp ||
6357                 error "failed to find --size +100K --ost 0 $dir"
6358         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6359         ! grep -q obd_uuid $tmp ||
6360                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6361 }
6362 run_test 56rb "check lfs find --size --ost/--mdt works"
6363
6364 test_56s() { # LU-611 #LU-9369
6365         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6366
6367         local dir=$DIR/$tdir
6368         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6369
6370         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6371         for i in $(seq $NUMDIRS); do
6372                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6373         done
6374
6375         local expected=$NUMDIRS
6376         local cmd="$LFS find -c $OSTCOUNT $dir"
6377         local nums=$($cmd | wc -l)
6378
6379         [ $nums -eq $expected ] || {
6380                 $LFS getstripe -R $dir
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382         }
6383
6384         expected=$((NUMDIRS + onestripe))
6385         cmd="$LFS find -stripe-count +0 -type f $dir"
6386         nums=$($cmd | wc -l)
6387         [ $nums -eq $expected ] || {
6388                 $LFS getstripe -R $dir
6389                 error "'$cmd' wrong: found $nums, expected $expected"
6390         }
6391
6392         expected=$onestripe
6393         cmd="$LFS find -stripe-count 1 -type f $dir"
6394         nums=$($cmd | wc -l)
6395         [ $nums -eq $expected ] || {
6396                 $LFS getstripe -R $dir
6397                 error "'$cmd' wrong: found $nums, expected $expected"
6398         }
6399
6400         cmd="$LFS find -stripe-count -2 -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] || {
6403                 $LFS getstripe -R $dir
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405         }
6406
6407         expected=0
6408         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6409         nums=$($cmd | wc -l)
6410         [ $nums -eq $expected ] || {
6411                 $LFS getstripe -R $dir
6412                 error "'$cmd' wrong: found $nums, expected $expected"
6413         }
6414 }
6415 run_test 56s "check lfs find -stripe-count works"
6416
6417 test_56t() { # LU-611 #LU-9369
6418         local dir=$DIR/$tdir
6419
6420         setup_56 $dir 0 $NUMDIRS
6421         for i in $(seq $NUMDIRS); do
6422                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6423         done
6424
6425         local expected=$NUMDIRS
6426         local cmd="$LFS find -S 8M $dir"
6427         local nums=$($cmd | wc -l)
6428
6429         [ $nums -eq $expected ] || {
6430                 $LFS getstripe -R $dir
6431                 error "'$cmd' wrong: found $nums, expected $expected"
6432         }
6433         rm -rf $dir
6434
6435         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6436
6437         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6438
6439         expected=$(((NUMDIRS + 1) * NUMFILES))
6440         cmd="$LFS find -stripe-size 512k -type f $dir"
6441         nums=$($cmd | wc -l)
6442         [ $nums -eq $expected ] ||
6443                 error "'$cmd' wrong: found $nums, expected $expected"
6444
6445         cmd="$LFS find -stripe-size +320k -type f $dir"
6446         nums=$($cmd | wc -l)
6447         [ $nums -eq $expected ] ||
6448                 error "'$cmd' wrong: found $nums, expected $expected"
6449
6450         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6451         cmd="$LFS find -stripe-size +200k -type f $dir"
6452         nums=$($cmd | wc -l)
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         cmd="$LFS find -stripe-size -640k -type f $dir"
6457         nums=$($cmd | wc -l)
6458         [ $nums -eq $expected ] ||
6459                 error "'$cmd' wrong: found $nums, expected $expected"
6460
6461         expected=4
6462         cmd="$LFS find -stripe-size 256k -type f $dir"
6463         nums=$($cmd | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         cmd="$LFS find -stripe-size -320k -type f $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         expected=0
6473         cmd="$LFS find -stripe-size 1024k -type f $dir"
6474         nums=$($cmd | wc -l)
6475         [ $nums -eq $expected ] ||
6476                 error "'$cmd' wrong: found $nums, expected $expected"
6477 }
6478 run_test 56t "check lfs find -stripe-size works"
6479
6480 test_56u() { # LU-611
6481         local dir=$DIR/$tdir
6482
6483         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6484
6485         if [[ $OSTCOUNT -gt 1 ]]; then
6486                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6487                 onestripe=4
6488         else
6489                 onestripe=0
6490         fi
6491
6492         local expected=$(((NUMDIRS + 1) * NUMFILES))
6493         local cmd="$LFS find -stripe-index 0 -type f $dir"
6494         local nums=$($cmd | wc -l)
6495
6496         [ $nums -eq $expected ] ||
6497                 error "'$cmd' wrong: found $nums, expected $expected"
6498
6499         expected=$onestripe
6500         cmd="$LFS find -stripe-index 1 -type f $dir"
6501         nums=$($cmd | wc -l)
6502         [ $nums -eq $expected ] ||
6503                 error "'$cmd' wrong: found $nums, expected $expected"
6504
6505         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6506         nums=$($cmd | wc -l)
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509
6510         expected=0
6511         # This should produce an error and not return any files
6512         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6513         nums=$($cmd 2>/dev/null | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516
6517         if [[ $OSTCOUNT -gt 1 ]]; then
6518                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6519                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6520                 nums=$($cmd | wc -l)
6521                 [ $nums -eq $expected ] ||
6522                         error "'$cmd' wrong: found $nums, expected $expected"
6523         fi
6524 }
6525 run_test 56u "check lfs find -stripe-index works"
6526
6527 test_56v() {
6528         local mdt_idx=0
6529         local dir=$DIR/$tdir
6530
6531         setup_56 $dir $NUMFILES $NUMDIRS
6532
6533         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6534         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6535
6536         for file in $($LFS find -m $UUID $dir); do
6537                 file_midx=$($LFS getstripe -m $file)
6538                 [ $file_midx -eq $mdt_idx ] ||
6539                         error "lfs find -m $UUID != getstripe -m $file_midx"
6540         done
6541 }
6542 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6543
6544 test_56w() {
6545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6547
6548         local dir=$DIR/$tdir
6549
6550         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6551
6552         local stripe_size=$($LFS getstripe -S -d $dir) ||
6553                 error "$LFS getstripe -S -d $dir failed"
6554         stripe_size=${stripe_size%% *}
6555
6556         local file_size=$((stripe_size * OSTCOUNT))
6557         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6558         local required_space=$((file_num * file_size))
6559         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6560                            head -n1)
6561         [[ $free_space -le $((required_space / 1024)) ]] &&
6562                 skip_env "need $required_space, have $free_space kbytes"
6563
6564         local dd_bs=65536
6565         local dd_count=$((file_size / dd_bs))
6566
6567         # write data into the files
6568         local i
6569         local j
6570         local file
6571
6572         for i in $(seq $NUMFILES); do
6573                 file=$dir/file$i
6574                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6575                         error "write data into $file failed"
6576         done
6577         for i in $(seq $NUMDIRS); do
6578                 for j in $(seq $NUMFILES); do
6579                         file=$dir/dir$i/file$j
6580                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6581                                 error "write data into $file failed"
6582                 done
6583         done
6584
6585         # $LFS_MIGRATE will fail if hard link migration is unsupported
6586         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6587                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6588                         error "creating links to $dir/dir1/file1 failed"
6589         fi
6590
6591         local expected=-1
6592
6593         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6594
6595         # lfs_migrate file
6596         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6597
6598         echo "$cmd"
6599         eval $cmd || error "$cmd failed"
6600
6601         check_stripe_count $dir/file1 $expected
6602
6603         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6604         then
6605                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6606                 # OST 1 if it is on OST 0. This file is small enough to
6607                 # be on only one stripe.
6608                 file=$dir/migr_1_ost
6609                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6610                         error "write data into $file failed"
6611                 local obdidx=$($LFS getstripe -i $file)
6612                 local oldmd5=$(md5sum $file)
6613                 local newobdidx=0
6614
6615                 [[ $obdidx -eq 0 ]] && newobdidx=1
6616                 cmd="$LFS migrate -i $newobdidx $file"
6617                 echo $cmd
6618                 eval $cmd || error "$cmd failed"
6619
6620                 local realobdix=$($LFS getstripe -i $file)
6621                 local newmd5=$(md5sum $file)
6622
6623                 [[ $newobdidx -ne $realobdix ]] &&
6624                         error "new OST is different (was=$obdidx, "\
6625                               "wanted=$newobdidx, got=$realobdix)"
6626                 [[ "$oldmd5" != "$newmd5" ]] &&
6627                         error "md5sum differ: $oldmd5, $newmd5"
6628         fi
6629
6630         # lfs_migrate dir
6631         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6632         echo "$cmd"
6633         eval $cmd || error "$cmd failed"
6634
6635         for j in $(seq $NUMFILES); do
6636                 check_stripe_count $dir/dir1/file$j $expected
6637         done
6638
6639         # lfs_migrate works with lfs find
6640         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6641              $LFS_MIGRATE -y -c $expected"
6642         echo "$cmd"
6643         eval $cmd || error "$cmd failed"
6644
6645         for i in $(seq 2 $NUMFILES); do
6646                 check_stripe_count $dir/file$i $expected
6647         done
6648         for i in $(seq 2 $NUMDIRS); do
6649                 for j in $(seq $NUMFILES); do
6650                 check_stripe_count $dir/dir$i/file$j $expected
6651                 done
6652         done
6653 }
6654 run_test 56w "check lfs_migrate -c stripe_count works"
6655
6656 test_56wb() {
6657         local file1=$DIR/$tdir/file1
6658         local create_pool=false
6659         local initial_pool=$($LFS getstripe -p $DIR)
6660         local pool_list=()
6661         local pool=""
6662
6663         echo -n "Creating test dir..."
6664         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6665         echo "done."
6666
6667         echo -n "Creating test file..."
6668         touch $file1 || error "cannot create file"
6669         echo "done."
6670
6671         echo -n "Detecting existing pools..."
6672         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6673
6674         if [ ${#pool_list[@]} -gt 0 ]; then
6675                 echo "${pool_list[@]}"
6676                 for thispool in "${pool_list[@]}"; do
6677                         if [[ -z "$initial_pool" ||
6678                               "$initial_pool" != "$thispool" ]]; then
6679                                 pool="$thispool"
6680                                 echo "Using existing pool '$pool'"
6681                                 break
6682                         fi
6683                 done
6684         else
6685                 echo "none detected."
6686         fi
6687         if [ -z "$pool" ]; then
6688                 pool=${POOL:-testpool}
6689                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6690                 echo -n "Creating pool '$pool'..."
6691                 create_pool=true
6692                 pool_add $pool &> /dev/null ||
6693                         error "pool_add failed"
6694                 echo "done."
6695
6696                 echo -n "Adding target to pool..."
6697                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6698                         error "pool_add_targets failed"
6699                 echo "done."
6700         fi
6701
6702         echo -n "Setting pool using -p option..."
6703         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6704                 error "migrate failed rc = $?"
6705         echo "done."
6706
6707         echo -n "Verifying test file is in pool after migrating..."
6708         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6709                 error "file was not migrated to pool $pool"
6710         echo "done."
6711
6712         echo -n "Removing test file from pool '$pool'..."
6713         # "lfs migrate $file" won't remove the file from the pool
6714         # until some striping information is changed.
6715         $LFS migrate -c 1 $file1 &> /dev/null ||
6716                 error "cannot remove from pool"
6717         [ "$($LFS getstripe -p $file1)" ] &&
6718                 error "pool still set"
6719         echo "done."
6720
6721         echo -n "Setting pool using --pool option..."
6722         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6723                 error "migrate failed rc = $?"
6724         echo "done."
6725
6726         # Clean up
6727         rm -f $file1
6728         if $create_pool; then
6729                 destroy_test_pools 2> /dev/null ||
6730                         error "destroy test pools failed"
6731         fi
6732 }
6733 run_test 56wb "check lfs_migrate pool support"
6734
6735 test_56wc() {
6736         local file1="$DIR/$tdir/file1"
6737         local parent_ssize
6738         local parent_scount
6739         local cur_ssize
6740         local cur_scount
6741         local orig_ssize
6742
6743         echo -n "Creating test dir..."
6744         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6745         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6746                 error "cannot set stripe by '-S 1M -c 1'"
6747         echo "done"
6748
6749         echo -n "Setting initial stripe for test file..."
6750         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6751                 error "cannot set stripe"
6752         cur_ssize=$($LFS getstripe -S "$file1")
6753         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6754         echo "done."
6755
6756         # File currently set to -S 512K -c 1
6757
6758         # Ensure -c and -S options are rejected when -R is set
6759         echo -n "Verifying incompatible options are detected..."
6760         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6761                 error "incompatible -c and -R options not detected"
6762         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6763                 error "incompatible -S and -R options not detected"
6764         echo "done."
6765
6766         # Ensure unrecognized options are passed through to 'lfs migrate'
6767         echo -n "Verifying -S option is passed through to lfs migrate..."
6768         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6769                 error "migration failed"
6770         cur_ssize=$($LFS getstripe -S "$file1")
6771         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6772         echo "done."
6773
6774         # File currently set to -S 1M -c 1
6775
6776         # Ensure long options are supported
6777         echo -n "Verifying long options supported..."
6778         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6779                 error "long option without argument not supported"
6780         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6781                 error "long option with argument not supported"
6782         cur_ssize=$($LFS getstripe -S "$file1")
6783         [ $cur_ssize -eq 524288 ] ||
6784                 error "migrate --stripe-size $cur_ssize != 524288"
6785         echo "done."
6786
6787         # File currently set to -S 512K -c 1
6788
6789         if [ "$OSTCOUNT" -gt 1 ]; then
6790                 echo -n "Verifying explicit stripe count can be set..."
6791                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6792                         error "migrate failed"
6793                 cur_scount=$($LFS getstripe -c "$file1")
6794                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6795                 echo "done."
6796         fi
6797
6798         # File currently set to -S 512K -c 1 or -S 512K -c 2
6799
6800         # Ensure parent striping is used if -R is set, and no stripe
6801         # count or size is specified
6802         echo -n "Setting stripe for parent directory..."
6803         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6804                 error "cannot set stripe '-S 2M -c 1'"
6805         echo "done."
6806
6807         echo -n "Verifying restripe option uses parent stripe settings..."
6808         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6809         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6810         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6811                 error "migrate failed"
6812         cur_ssize=$($LFS getstripe -S "$file1")
6813         [ $cur_ssize -eq $parent_ssize ] ||
6814                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6815         cur_scount=$($LFS getstripe -c "$file1")
6816         [ $cur_scount -eq $parent_scount ] ||
6817                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6818         echo "done."
6819
6820         # File currently set to -S 1M -c 1
6821
6822         # Ensure striping is preserved if -R is not set, and no stripe
6823         # count or size is specified
6824         echo -n "Verifying striping size preserved when not specified..."
6825         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6826         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6827                 error "cannot set stripe on parent directory"
6828         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6829                 error "migrate failed"
6830         cur_ssize=$($LFS getstripe -S "$file1")
6831         [ $cur_ssize -eq $orig_ssize ] ||
6832                 error "migrate by default $cur_ssize != $orig_ssize"
6833         echo "done."
6834
6835         # Ensure file name properly detected when final option has no argument
6836         echo -n "Verifying file name properly detected..."
6837         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6838                 error "file name interpreted as option argument"
6839         echo "done."
6840
6841         # Clean up
6842         rm -f "$file1"
6843 }
6844 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6845
6846 test_56wd() {
6847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6848
6849         local file1=$DIR/$tdir/file1
6850
6851         echo -n "Creating test dir..."
6852         test_mkdir $DIR/$tdir || error "cannot create dir"
6853         echo "done."
6854
6855         echo -n "Creating test file..."
6856         touch $file1
6857         echo "done."
6858
6859         # Ensure 'lfs migrate' will fail by using a non-existent option,
6860         # and make sure rsync is not called to recover
6861         echo -n "Make sure --no-rsync option works..."
6862         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6863                 grep -q 'refusing to fall back to rsync' ||
6864                 error "rsync was called with --no-rsync set"
6865         echo "done."
6866
6867         # Ensure rsync is called without trying 'lfs migrate' first
6868         echo -n "Make sure --rsync option works..."
6869         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6870                 grep -q 'falling back to rsync' &&
6871                 error "lfs migrate was called with --rsync set"
6872         echo "done."
6873
6874         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6875         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6876                 grep -q 'at the same time' ||
6877                 error "--rsync and --no-rsync accepted concurrently"
6878         echo "done."
6879
6880         # Clean up
6881         rm -f $file1
6882 }
6883 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6884
6885 test_56we() {
6886         local td=$DIR/$tdir
6887         local tf=$td/$tfile
6888
6889         test_mkdir $td || error "cannot create $td"
6890         touch $tf || error "cannot touch $tf"
6891
6892         echo -n "Make sure --non-direct|-D works..."
6893         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6894                 grep -q "lfs migrate --non-direct" ||
6895                 error "--non-direct option cannot work correctly"
6896         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6897                 grep -q "lfs migrate -D" ||
6898                 error "-D option cannot work correctly"
6899         echo "done."
6900 }
6901 run_test 56we "check lfs_migrate --non-direct|-D support"
6902
6903 test_56x() {
6904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6905         check_swap_layouts_support
6906
6907         local dir=$DIR/$tdir
6908         local ref1=/etc/passwd
6909         local file1=$dir/file1
6910
6911         test_mkdir $dir || error "creating dir $dir"
6912         $LFS setstripe -c 2 $file1
6913         cp $ref1 $file1
6914         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6915         stripe=$($LFS getstripe -c $file1)
6916         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6917         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6918
6919         # clean up
6920         rm -f $file1
6921 }
6922 run_test 56x "lfs migration support"
6923
6924 test_56xa() {
6925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6926         check_swap_layouts_support
6927
6928         local dir=$DIR/$tdir/$testnum
6929
6930         test_mkdir -p $dir
6931
6932         local ref1=/etc/passwd
6933         local file1=$dir/file1
6934
6935         $LFS setstripe -c 2 $file1
6936         cp $ref1 $file1
6937         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6938
6939         local stripe=$($LFS getstripe -c $file1)
6940
6941         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6942         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6943
6944         # clean up
6945         rm -f $file1
6946 }
6947 run_test 56xa "lfs migration --block support"
6948
6949 check_migrate_links() {
6950         local dir="$1"
6951         local file1="$dir/file1"
6952         local begin="$2"
6953         local count="$3"
6954         local runas="$4"
6955         local total_count=$(($begin + $count - 1))
6956         local symlink_count=10
6957         local uniq_count=10
6958
6959         if [ ! -f "$file1" ]; then
6960                 echo -n "creating initial file..."
6961                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6962                         error "cannot setstripe initial file"
6963                 echo "done"
6964
6965                 echo -n "creating symlinks..."
6966                 for s in $(seq 1 $symlink_count); do
6967                         ln -s "$file1" "$dir/slink$s" ||
6968                                 error "cannot create symlinks"
6969                 done
6970                 echo "done"
6971
6972                 echo -n "creating nonlinked files..."
6973                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6974                         error "cannot create nonlinked files"
6975                 echo "done"
6976         fi
6977
6978         # create hard links
6979         if [ ! -f "$dir/file$total_count" ]; then
6980                 echo -n "creating hard links $begin:$total_count..."
6981                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6982                         /dev/null || error "cannot create hard links"
6983                 echo "done"
6984         fi
6985
6986         echo -n "checking number of hard links listed in xattrs..."
6987         local fid=$($LFS getstripe -F "$file1")
6988         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6989
6990         echo "${#paths[*]}"
6991         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6992                         skip "hard link list has unexpected size, skipping test"
6993         fi
6994         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6995                         error "link names should exceed xattrs size"
6996         fi
6997
6998         echo -n "migrating files..."
6999         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7000         local rc=$?
7001         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7002         echo "done"
7003
7004         # make sure all links have been properly migrated
7005         echo -n "verifying files..."
7006         fid=$($LFS getstripe -F "$file1") ||
7007                 error "cannot get fid for file $file1"
7008         for i in $(seq 2 $total_count); do
7009                 local fid2=$($LFS getstripe -F $dir/file$i)
7010
7011                 [ "$fid2" == "$fid" ] ||
7012                         error "migrated hard link has mismatched FID"
7013         done
7014
7015         # make sure hard links were properly detected, and migration was
7016         # performed only once for the entire link set; nonlinked files should
7017         # also be migrated
7018         local actual=$(grep -c 'done' <<< "$migrate_out")
7019         local expected=$(($uniq_count + 1))
7020
7021         [ "$actual" -eq  "$expected" ] ||
7022                 error "hard links individually migrated ($actual != $expected)"
7023
7024         # make sure the correct number of hard links are present
7025         local hardlinks=$(stat -c '%h' "$file1")
7026
7027         [ $hardlinks -eq $total_count ] ||
7028                 error "num hard links $hardlinks != $total_count"
7029         echo "done"
7030
7031         return 0
7032 }
7033
7034 test_56xb() {
7035         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7036                 skip "Need MDS version at least 2.10.55"
7037
7038         local dir="$DIR/$tdir"
7039
7040         test_mkdir "$dir" || error "cannot create dir $dir"
7041
7042         echo "testing lfs migrate mode when all links fit within xattrs"
7043         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7044
7045         echo "testing rsync mode when all links fit within xattrs"
7046         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7047
7048         echo "testing lfs migrate mode when all links do not fit within xattrs"
7049         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7050
7051         echo "testing rsync mode when all links do not fit within xattrs"
7052         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7053
7054         chown -R $RUNAS_ID $dir
7055         echo "testing non-root lfs migrate mode when not all links are in xattr"
7056         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7057
7058         # clean up
7059         rm -rf $dir
7060 }
7061 run_test 56xb "lfs migration hard link support"
7062
7063 test_56xc() {
7064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7065
7066         local dir="$DIR/$tdir"
7067
7068         test_mkdir "$dir" || error "cannot create dir $dir"
7069
7070         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7071         echo -n "Setting initial stripe for 20MB test file..."
7072         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7073                 error "cannot setstripe 20MB file"
7074         echo "done"
7075         echo -n "Sizing 20MB test file..."
7076         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7077         echo "done"
7078         echo -n "Verifying small file autostripe count is 1..."
7079         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7080                 error "cannot migrate 20MB file"
7081         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7082                 error "cannot get stripe for $dir/20mb"
7083         [ $stripe_count -eq 1 ] ||
7084                 error "unexpected stripe count $stripe_count for 20MB file"
7085         rm -f "$dir/20mb"
7086         echo "done"
7087
7088         # Test 2: File is small enough to fit within the available space on
7089         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7090         # have at least an additional 1KB for each desired stripe for test 3
7091         echo -n "Setting stripe for 1GB test file..."
7092         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7093         echo "done"
7094         echo -n "Sizing 1GB test file..."
7095         # File size is 1GB + 3KB
7096         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7097         echo "done"
7098
7099         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7100         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7101         if (( avail > 524288 * OSTCOUNT )); then
7102                 echo -n "Migrating 1GB file..."
7103                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7104                         error "cannot migrate 1GB file"
7105                 echo "done"
7106                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7107                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7108                         error "cannot getstripe for 1GB file"
7109                 [ $stripe_count -eq 2 ] ||
7110                         error "unexpected stripe count $stripe_count != 2"
7111                 echo "done"
7112         fi
7113
7114         # Test 3: File is too large to fit within the available space on
7115         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7116         if [ $OSTCOUNT -ge 3 ]; then
7117                 # The required available space is calculated as
7118                 # file size (1GB + 3KB) / OST count (3).
7119                 local kb_per_ost=349526
7120
7121                 echo -n "Migrating 1GB file with limit..."
7122                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7123                         error "cannot migrate 1GB file with limit"
7124                 echo "done"
7125
7126                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7127                 echo -n "Verifying 1GB autostripe count with limited space..."
7128                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7129                         error "unexpected stripe count $stripe_count (min 3)"
7130                 echo "done"
7131         fi
7132
7133         # clean up
7134         rm -rf $dir
7135 }
7136 run_test 56xc "lfs migration autostripe"
7137
7138 test_56xd() {
7139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7140
7141         local dir=$DIR/$tdir
7142         local f_mgrt=$dir/$tfile.mgrt
7143         local f_yaml=$dir/$tfile.yaml
7144         local f_copy=$dir/$tfile.copy
7145         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7146         local layout_copy="-c 2 -S 2M -i 1"
7147         local yamlfile=$dir/yamlfile
7148         local layout_before;
7149         local layout_after;
7150
7151         test_mkdir "$dir" || error "cannot create dir $dir"
7152         $LFS setstripe $layout_yaml $f_yaml ||
7153                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7154         $LFS getstripe --yaml $f_yaml > $yamlfile
7155         $LFS setstripe $layout_copy $f_copy ||
7156                 error "cannot setstripe $f_copy with layout $layout_copy"
7157         touch $f_mgrt
7158         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7159
7160         # 1. test option --yaml
7161         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7162                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7163         layout_before=$(get_layout_param $f_yaml)
7164         layout_after=$(get_layout_param $f_mgrt)
7165         [ "$layout_after" == "$layout_before" ] ||
7166                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7167
7168         # 2. test option --copy
7169         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7170                 error "cannot migrate $f_mgrt with --copy $f_copy"
7171         layout_before=$(get_layout_param $f_copy)
7172         layout_after=$(get_layout_param $f_mgrt)
7173         [ "$layout_after" == "$layout_before" ] ||
7174                 error "lfs_migrate --copy: $layout_after != $layout_before"
7175 }
7176 run_test 56xd "check lfs_migrate --yaml and --copy support"
7177
7178 test_56xe() {
7179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7180
7181         local dir=$DIR/$tdir
7182         local f_comp=$dir/$tfile
7183         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7184         local layout_before=""
7185         local layout_after=""
7186
7187         test_mkdir "$dir" || error "cannot create dir $dir"
7188         $LFS setstripe $layout $f_comp ||
7189                 error "cannot setstripe $f_comp with layout $layout"
7190         layout_before=$(get_layout_param $f_comp)
7191         dd if=/dev/zero of=$f_comp bs=1M count=4
7192
7193         # 1. migrate a comp layout file by lfs_migrate
7194         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7195         layout_after=$(get_layout_param $f_comp)
7196         [ "$layout_before" == "$layout_after" ] ||
7197                 error "lfs_migrate: $layout_before != $layout_after"
7198
7199         # 2. migrate a comp layout file by lfs migrate
7200         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7201         layout_after=$(get_layout_param $f_comp)
7202         [ "$layout_before" == "$layout_after" ] ||
7203                 error "lfs migrate: $layout_before != $layout_after"
7204 }
7205 run_test 56xe "migrate a composite layout file"
7206
7207 test_56xf() {
7208         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7209
7210         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7211                 skip "Need server version at least 2.13.53"
7212
7213         local dir=$DIR/$tdir
7214         local f_comp=$dir/$tfile
7215         local layout="-E 1M -c1 -E -1 -c2"
7216         local fid_before=""
7217         local fid_after=""
7218
7219         test_mkdir "$dir" || error "cannot create dir $dir"
7220         $LFS setstripe $layout $f_comp ||
7221                 error "cannot setstripe $f_comp with layout $layout"
7222         fid_before=$($LFS getstripe --fid $f_comp)
7223         dd if=/dev/zero of=$f_comp bs=1M count=4
7224
7225         # 1. migrate a comp layout file to a comp layout
7226         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7227         fid_after=$($LFS getstripe --fid $f_comp)
7228         [ "$fid_before" == "$fid_after" ] ||
7229                 error "comp-to-comp migrate: $fid_before != $fid_after"
7230
7231         # 2. migrate a comp layout file to a plain layout
7232         $LFS migrate -c2 $f_comp ||
7233                 error "cannot migrate $f_comp by lfs migrate"
7234         fid_after=$($LFS getstripe --fid $f_comp)
7235         [ "$fid_before" == "$fid_after" ] ||
7236                 error "comp-to-plain migrate: $fid_before != $fid_after"
7237
7238         # 3. migrate a plain layout file to a comp layout
7239         $LFS migrate $layout $f_comp ||
7240                 error "cannot migrate $f_comp by lfs migrate"
7241         fid_after=$($LFS getstripe --fid $f_comp)
7242         [ "$fid_before" == "$fid_after" ] ||
7243                 error "plain-to-comp migrate: $fid_before != $fid_after"
7244 }
7245 run_test 56xf "FID is not lost during migration of a composite layout file"
7246
7247 test_56y() {
7248         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7249                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7250
7251         local res=""
7252         local dir=$DIR/$tdir
7253         local f1=$dir/file1
7254         local f2=$dir/file2
7255
7256         test_mkdir -p $dir || error "creating dir $dir"
7257         touch $f1 || error "creating std file $f1"
7258         $MULTIOP $f2 H2c || error "creating released file $f2"
7259
7260         # a directory can be raid0, so ask only for files
7261         res=$($LFS find $dir -L raid0 -type f | wc -l)
7262         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7263
7264         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7265         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7266
7267         # only files can be released, so no need to force file search
7268         res=$($LFS find $dir -L released)
7269         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7270
7271         res=$($LFS find $dir -type f \! -L released)
7272         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7273 }
7274 run_test 56y "lfs find -L raid0|released"
7275
7276 test_56z() { # LU-4824
7277         # This checks to make sure 'lfs find' continues after errors
7278         # There are two classes of errors that should be caught:
7279         # - If multiple paths are provided, all should be searched even if one
7280         #   errors out
7281         # - If errors are encountered during the search, it should not terminate
7282         #   early
7283         local dir=$DIR/$tdir
7284         local i
7285
7286         test_mkdir $dir
7287         for i in d{0..9}; do
7288                 test_mkdir $dir/$i
7289                 touch $dir/$i/$tfile
7290         done
7291         $LFS find $DIR/non_existent_dir $dir &&
7292                 error "$LFS find did not return an error"
7293         # Make a directory unsearchable. This should NOT be the last entry in
7294         # directory order.  Arbitrarily pick the 6th entry
7295         chmod 700 $($LFS find $dir -type d | sed '6!d')
7296
7297         $RUNAS $LFS find $DIR/non_existent $dir
7298         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7299
7300         # The user should be able to see 10 directories and 9 files
7301         (( count == 19 )) ||
7302                 error "$LFS find found $count != 19 entries after error"
7303 }
7304 run_test 56z "lfs find should continue after an error"
7305
7306 test_56aa() { # LU-5937
7307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7308
7309         local dir=$DIR/$tdir
7310
7311         mkdir $dir
7312         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7313
7314         createmany -o $dir/striped_dir/${tfile}- 1024
7315         local dirs=$($LFS find --size +8k $dir/)
7316
7317         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7318 }
7319 run_test 56aa "lfs find --size under striped dir"
7320
7321 test_56ab() { # LU-10705
7322         test_mkdir $DIR/$tdir
7323         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7324         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7325         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7326         # Flush writes to ensure valid blocks.  Need to be more thorough for
7327         # ZFS, since blocks are not allocated/returned to client immediately.
7328         sync_all_data
7329         wait_zfs_commit ost1 2
7330         cancel_lru_locks osc
7331         ls -ls $DIR/$tdir
7332
7333         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7334
7335         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7336
7337         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7338         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7339
7340         rm -f $DIR/$tdir/$tfile.[123]
7341 }
7342 run_test 56ab "lfs find --blocks"
7343
7344 test_56ba() {
7345         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7346                 skip "Need MDS version at least 2.10.50"
7347
7348         # Create composite files with one component
7349         local dir=$DIR/$tdir
7350
7351         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7352         # Create composite files with three components
7353         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7354         # Create non-composite files
7355         createmany -o $dir/${tfile}- 10
7356
7357         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7358
7359         [[ $nfiles == 10 ]] ||
7360                 error "lfs find -E 1M found $nfiles != 10 files"
7361
7362         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7363         [[ $nfiles == 25 ]] ||
7364                 error "lfs find ! -E 1M found $nfiles != 25 files"
7365
7366         # All files have a component that starts at 0
7367         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7368         [[ $nfiles == 35 ]] ||
7369                 error "lfs find --component-start 0 - $nfiles != 35 files"
7370
7371         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7372         [[ $nfiles == 15 ]] ||
7373                 error "lfs find --component-start 2M - $nfiles != 15 files"
7374
7375         # All files created here have a componenet that does not starts at 2M
7376         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7377         [[ $nfiles == 35 ]] ||
7378                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7379
7380         # Find files with a specified number of components
7381         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7382         [[ $nfiles == 15 ]] ||
7383                 error "lfs find --component-count 3 - $nfiles != 15 files"
7384
7385         # Remember non-composite files have a component count of zero
7386         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7387         [[ $nfiles == 10 ]] ||
7388                 error "lfs find --component-count 0 - $nfiles != 10 files"
7389
7390         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7391         [[ $nfiles == 20 ]] ||
7392                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7393
7394         # All files have a flag called "init"
7395         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7396         [[ $nfiles == 35 ]] ||
7397                 error "lfs find --component-flags init - $nfiles != 35 files"
7398
7399         # Multi-component files will have a component not initialized
7400         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7401         [[ $nfiles == 15 ]] ||
7402                 error "lfs find !--component-flags init - $nfiles != 15 files"
7403
7404         rm -rf $dir
7405
7406 }
7407 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7408
7409 test_56ca() {
7410         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7411                 skip "Need MDS version at least 2.10.57"
7412
7413         local td=$DIR/$tdir
7414         local tf=$td/$tfile
7415         local dir
7416         local nfiles
7417         local cmd
7418         local i
7419         local j
7420
7421         # create mirrored directories and mirrored files
7422         mkdir $td || error "mkdir $td failed"
7423         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7424         createmany -o $tf- 10 || error "create $tf- failed"
7425
7426         for i in $(seq 2); do
7427                 dir=$td/dir$i
7428                 mkdir $dir || error "mkdir $dir failed"
7429                 $LFS mirror create -N$((3 + i)) $dir ||
7430                         error "create mirrored dir $dir failed"
7431                 createmany -o $dir/$tfile- 10 ||
7432                         error "create $dir/$tfile- failed"
7433         done
7434
7435         # change the states of some mirrored files
7436         echo foo > $tf-6
7437         for i in $(seq 2); do
7438                 dir=$td/dir$i
7439                 for j in $(seq 4 9); do
7440                         echo foo > $dir/$tfile-$j
7441                 done
7442         done
7443
7444         # find mirrored files with specific mirror count
7445         cmd="$LFS find --mirror-count 3 --type f $td"
7446         nfiles=$($cmd | wc -l)
7447         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7448
7449         cmd="$LFS find ! --mirror-count 3 --type f $td"
7450         nfiles=$($cmd | wc -l)
7451         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7452
7453         cmd="$LFS find --mirror-count +2 --type f $td"
7454         nfiles=$($cmd | wc -l)
7455         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7456
7457         cmd="$LFS find --mirror-count -6 --type f $td"
7458         nfiles=$($cmd | wc -l)
7459         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7460
7461         # find mirrored files with specific file state
7462         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7463         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7464
7465         cmd="$LFS find --mirror-state=ro --type f $td"
7466         nfiles=$($cmd | wc -l)
7467         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7468
7469         cmd="$LFS find ! --mirror-state=ro --type f $td"
7470         nfiles=$($cmd | wc -l)
7471         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7472
7473         cmd="$LFS find --mirror-state=wp --type f $td"
7474         nfiles=$($cmd | wc -l)
7475         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7476
7477         cmd="$LFS find ! --mirror-state=sp --type f $td"
7478         nfiles=$($cmd | wc -l)
7479         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7480 }
7481 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7482
7483 test_57a() {
7484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7485         # note test will not do anything if MDS is not local
7486         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7487                 skip_env "ldiskfs only test"
7488         fi
7489         remote_mds_nodsh && skip "remote MDS with nodsh"
7490
7491         local MNTDEV="osd*.*MDT*.mntdev"
7492         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7493         [ -z "$DEV" ] && error "can't access $MNTDEV"
7494         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7495                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7496                         error "can't access $DEV"
7497                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7498                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7499                 rm $TMP/t57a.dump
7500         done
7501 }
7502 run_test 57a "verify MDS filesystem created with large inodes =="
7503
7504 test_57b() {
7505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7506         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7507                 skip_env "ldiskfs only test"
7508         fi
7509         remote_mds_nodsh && skip "remote MDS with nodsh"
7510
7511         local dir=$DIR/$tdir
7512         local filecount=100
7513         local file1=$dir/f1
7514         local fileN=$dir/f$filecount
7515
7516         rm -rf $dir || error "removing $dir"
7517         test_mkdir -c1 $dir
7518         local mdtidx=$($LFS getstripe -m $dir)
7519         local mdtname=MDT$(printf %04x $mdtidx)
7520         local facet=mds$((mdtidx + 1))
7521
7522         echo "mcreating $filecount files"
7523         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7524
7525         # verify that files do not have EAs yet
7526         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7527                 error "$file1 has an EA"
7528         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7529                 error "$fileN has an EA"
7530
7531         sync
7532         sleep 1
7533         df $dir  #make sure we get new statfs data
7534         local mdsfree=$(do_facet $facet \
7535                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7536         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7537         local file
7538
7539         echo "opening files to create objects/EAs"
7540         for file in $(seq -f $dir/f%g 1 $filecount); do
7541                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7542                         error "opening $file"
7543         done
7544
7545         # verify that files have EAs now
7546         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7547         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7548
7549         sleep 1  #make sure we get new statfs data
7550         df $dir
7551         local mdsfree2=$(do_facet $facet \
7552                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7553         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7554
7555         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7556                 if [ "$mdsfree" != "$mdsfree2" ]; then
7557                         error "MDC before $mdcfree != after $mdcfree2"
7558                 else
7559                         echo "MDC before $mdcfree != after $mdcfree2"
7560                         echo "unable to confirm if MDS has large inodes"
7561                 fi
7562         fi
7563         rm -rf $dir
7564 }
7565 run_test 57b "default LOV EAs are stored inside large inodes ==="
7566
7567 test_58() {
7568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7569         [ -z "$(which wiretest 2>/dev/null)" ] &&
7570                         skip_env "could not find wiretest"
7571
7572         wiretest
7573 }
7574 run_test 58 "verify cross-platform wire constants =============="
7575
7576 test_59() {
7577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7578
7579         echo "touch 130 files"
7580         createmany -o $DIR/f59- 130
7581         echo "rm 130 files"
7582         unlinkmany $DIR/f59- 130
7583         sync
7584         # wait for commitment of removal
7585         wait_delete_completed
7586 }
7587 run_test 59 "verify cancellation of llog records async ========="
7588
7589 TEST60_HEAD="test_60 run $RANDOM"
7590 test_60a() {
7591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7592         remote_mgs_nodsh && skip "remote MGS with nodsh"
7593         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7594                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7595                         skip_env "missing subtest run-llog.sh"
7596
7597         log "$TEST60_HEAD - from kernel mode"
7598         do_facet mgs "$LCTL dk > /dev/null"
7599         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7600         do_facet mgs $LCTL dk > $TMP/$tfile
7601
7602         # LU-6388: test llog_reader
7603         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7604         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7605         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7606                         skip_env "missing llog_reader"
7607         local fstype=$(facet_fstype mgs)
7608         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7609                 skip_env "Only for ldiskfs or zfs type mgs"
7610
7611         local mntpt=$(facet_mntpt mgs)
7612         local mgsdev=$(mgsdevname 1)
7613         local fid_list
7614         local fid
7615         local rec_list
7616         local rec
7617         local rec_type
7618         local obj_file
7619         local path
7620         local seq
7621         local oid
7622         local pass=true
7623
7624         #get fid and record list
7625         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7626                 tail -n 4))
7627         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7628                 tail -n 4))
7629         #remount mgs as ldiskfs or zfs type
7630         stop mgs || error "stop mgs failed"
7631         mount_fstype mgs || error "remount mgs failed"
7632         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7633                 fid=${fid_list[i]}
7634                 rec=${rec_list[i]}
7635                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7636                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7637                 oid=$((16#$oid))
7638
7639                 case $fstype in
7640                         ldiskfs )
7641                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7642                         zfs )
7643                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7644                 esac
7645                 echo "obj_file is $obj_file"
7646                 do_facet mgs $llog_reader $obj_file
7647
7648                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7649                         awk '{ print $3 }' | sed -e "s/^type=//g")
7650                 if [ $rec_type != $rec ]; then
7651                         echo "FAILED test_60a wrong record type $rec_type," \
7652                               "should be $rec"
7653                         pass=false
7654                         break
7655                 fi
7656
7657                 #check obj path if record type is LLOG_LOGID_MAGIC
7658                 if [ "$rec" == "1064553b" ]; then
7659                         path=$(do_facet mgs $llog_reader $obj_file |
7660                                 grep "path=" | awk '{ print $NF }' |
7661                                 sed -e "s/^path=//g")
7662                         if [ $obj_file != $mntpt/$path ]; then
7663                                 echo "FAILED test_60a wrong obj path" \
7664                                       "$montpt/$path, should be $obj_file"
7665                                 pass=false
7666                                 break
7667                         fi
7668                 fi
7669         done
7670         rm -f $TMP/$tfile
7671         #restart mgs before "error", otherwise it will block the next test
7672         stop mgs || error "stop mgs failed"
7673         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7674         $pass || error "test failed, see FAILED test_60a messages for specifics"
7675 }
7676 run_test 60a "llog_test run from kernel module and test llog_reader"
7677
7678 test_60b() { # bug 6411
7679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7680
7681         dmesg > $DIR/$tfile
7682         LLOG_COUNT=$(do_facet mgs dmesg |
7683                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7684                           /llog_[a-z]*.c:[0-9]/ {
7685                                 if (marker)
7686                                         from_marker++
7687                                 from_begin++
7688                           }
7689                           END {
7690                                 if (marker)
7691                                         print from_marker
7692                                 else
7693                                         print from_begin
7694                           }")
7695
7696         [[ $LLOG_COUNT -gt 120 ]] &&
7697                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7698 }
7699 run_test 60b "limit repeated messages from CERROR/CWARN"
7700
7701 test_60c() {
7702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7703
7704         echo "create 5000 files"
7705         createmany -o $DIR/f60c- 5000
7706 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7707         lctl set_param fail_loc=0x80000137
7708         unlinkmany $DIR/f60c- 5000
7709         lctl set_param fail_loc=0
7710 }
7711 run_test 60c "unlink file when mds full"
7712
7713 test_60d() {
7714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7715
7716         SAVEPRINTK=$(lctl get_param -n printk)
7717         # verify "lctl mark" is even working"
7718         MESSAGE="test message ID $RANDOM $$"
7719         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7720         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7721
7722         lctl set_param printk=0 || error "set lnet.printk failed"
7723         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7724         MESSAGE="new test message ID $RANDOM $$"
7725         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7726         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7727         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7728
7729         lctl set_param -n printk="$SAVEPRINTK"
7730 }
7731 run_test 60d "test printk console message masking"
7732
7733 test_60e() {
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735         remote_mds_nodsh && skip "remote MDS with nodsh"
7736
7737         touch $DIR/$tfile
7738 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7739         do_facet mds1 lctl set_param fail_loc=0x15b
7740         rm $DIR/$tfile
7741 }
7742 run_test 60e "no space while new llog is being created"
7743
7744 test_60g() {
7745         local pid
7746         local i
7747
7748         test_mkdir -c $MDSCOUNT $DIR/$tdir
7749
7750         (
7751                 local index=0
7752                 while true; do
7753                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7754                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7755                                 2>/dev/null
7756                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7757                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7758                         index=$((index + 1))
7759                 done
7760         ) &
7761
7762         pid=$!
7763
7764         for i in {0..100}; do
7765                 # define OBD_FAIL_OSD_TXN_START    0x19a
7766                 local index=$((i % MDSCOUNT + 1))
7767
7768                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7769                         > /dev/null
7770                 sleep 0.01
7771         done
7772
7773         kill -9 $pid
7774
7775         for i in $(seq $MDSCOUNT); do
7776                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7777         done
7778
7779         mkdir $DIR/$tdir/new || error "mkdir failed"
7780         rmdir $DIR/$tdir/new || error "rmdir failed"
7781
7782         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7783                 -t namespace
7784         for i in $(seq $MDSCOUNT); do
7785                 wait_update_facet mds$i "$LCTL get_param -n \
7786                         mdd.$(facet_svc mds$i).lfsck_namespace |
7787                         awk '/^status/ { print \\\$2 }'" "completed"
7788         done
7789
7790         ls -R $DIR/$tdir || error "ls failed"
7791         rm -rf $DIR/$tdir || error "rmdir failed"
7792 }
7793 run_test 60g "transaction abort won't cause MDT hung"
7794
7795 test_60h() {
7796         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7797                 skip "Need MDS version at least 2.12.52"
7798         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7799
7800         local f
7801
7802         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7803         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7804         for fail_loc in 0x80000188 0x80000189; do
7805                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7806                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7807                         error "mkdir $dir-$fail_loc failed"
7808                 for i in {0..10}; do
7809                         # create may fail on missing stripe
7810                         echo $i > $DIR/$tdir-$fail_loc/$i
7811                 done
7812                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7813                         error "getdirstripe $tdir-$fail_loc failed"
7814                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7815                         error "migrate $tdir-$fail_loc failed"
7816                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7817                         error "getdirstripe $tdir-$fail_loc failed"
7818                 pushd $DIR/$tdir-$fail_loc
7819                 for f in *; do
7820                         echo $f | cmp $f - || error "$f data mismatch"
7821                 done
7822                 popd
7823                 rm -rf $DIR/$tdir-$fail_loc
7824         done
7825 }
7826 run_test 60h "striped directory with missing stripes can be accessed"
7827
7828 test_61a() {
7829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7830
7831         f="$DIR/f61"
7832         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7833         cancel_lru_locks osc
7834         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7835         sync
7836 }
7837 run_test 61a "mmap() writes don't make sync hang ================"
7838
7839 test_61b() {
7840         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7841 }
7842 run_test 61b "mmap() of unstriped file is successful"
7843
7844 # bug 2330 - insufficient obd_match error checking causes LBUG
7845 test_62() {
7846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7847
7848         f="$DIR/f62"
7849         echo foo > $f
7850         cancel_lru_locks osc
7851         lctl set_param fail_loc=0x405
7852         cat $f && error "cat succeeded, expect -EIO"
7853         lctl set_param fail_loc=0
7854 }
7855 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7856 # match every page all of the time.
7857 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7858
7859 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7860 # Though this test is irrelevant anymore, it helped to reveal some
7861 # other grant bugs (LU-4482), let's keep it.
7862 test_63a() {   # was test_63
7863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7864
7865         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7866
7867         for i in `seq 10` ; do
7868                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7869                 sleep 5
7870                 kill $!
7871                 sleep 1
7872         done
7873
7874         rm -f $DIR/f63 || true
7875 }
7876 run_test 63a "Verify oig_wait interruption does not crash ======="
7877
7878 # bug 2248 - async write errors didn't return to application on sync
7879 # bug 3677 - async write errors left page locked
7880 test_63b() {
7881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7882
7883         debugsave
7884         lctl set_param debug=-1
7885
7886         # ensure we have a grant to do async writes
7887         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7888         rm $DIR/$tfile
7889
7890         sync    # sync lest earlier test intercept the fail_loc
7891
7892         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7893         lctl set_param fail_loc=0x80000406
7894         $MULTIOP $DIR/$tfile Owy && \
7895                 error "sync didn't return ENOMEM"
7896         sync; sleep 2; sync     # do a real sync this time to flush page
7897         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7898                 error "locked page left in cache after async error" || true
7899         debugrestore
7900 }
7901 run_test 63b "async write errors should be returned to fsync ==="
7902
7903 test_64a () {
7904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7905
7906         lfs df $DIR
7907         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7908 }
7909 run_test 64a "verify filter grant calculations (in kernel) ====="
7910
7911 test_64b () {
7912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7913
7914         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7915 }
7916 run_test 64b "check out-of-space detection on client"
7917
7918 test_64c() {
7919         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7920 }
7921 run_test 64c "verify grant shrink"
7922
7923 import_param() {
7924         local tgt=$1
7925         local param=$2
7926
7927         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7928 }
7929
7930 # this does exactly what osc_request.c:osc_announce_cached() does in
7931 # order to calculate max amount of grants to ask from server
7932 want_grant() {
7933         local tgt=$1
7934
7935         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7936         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7937
7938         ((rpc_in_flight++));
7939         nrpages=$((nrpages * rpc_in_flight))
7940
7941         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7942
7943         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7944
7945         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7946         local undirty=$((nrpages * PAGE_SIZE))
7947
7948         local max_extent_pages
7949         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7950         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7951         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7952         local grant_extent_tax
7953         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7954
7955         undirty=$((undirty + nrextents * grant_extent_tax))
7956
7957         echo $undirty
7958 }
7959
7960 # this is size of unit for grant allocation. It should be equal to
7961 # what tgt_grant.c:tgt_grant_chunk() calculates
7962 grant_chunk() {
7963         local tgt=$1
7964         local max_brw_size
7965         local grant_extent_tax
7966
7967         max_brw_size=$(import_param $tgt max_brw_size)
7968
7969         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7970
7971         echo $(((max_brw_size + grant_extent_tax) * 2))
7972 }
7973
7974 test_64d() {
7975         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7976                 skip "OST < 2.10.55 doesn't limit grants enough"
7977
7978         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7979
7980         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7981                 skip "no grant_param connect flag"
7982
7983         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7984
7985         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7986         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7987
7988
7989         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7990         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7991
7992         $LFS setstripe $DIR/$tfile -i 0 -c 1
7993         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7994         ddpid=$!
7995
7996         while kill -0 $ddpid; do
7997                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7998
7999                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8000                         kill $ddpid
8001                         error "cur_grant $cur_grant > $max_cur_granted"
8002                 fi
8003
8004                 sleep 1
8005         done
8006 }
8007 run_test 64d "check grant limit exceed"
8008
8009 check_grants() {
8010         local tgt=$1
8011         local expected=$2
8012         local msg=$3
8013         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8014
8015         ((cur_grants == expected)) ||
8016                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8017 }
8018
8019 round_up_p2() {
8020         echo $((($1 + $2 - 1) & ~($2 - 1)))
8021 }
8022
8023 test_64e() {
8024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8025         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8026                 skip "Need OSS version at least 2.11.56"
8027
8028         # Remount client to reset grant
8029         remount_client $MOUNT || error "failed to remount client"
8030         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8031
8032         local init_grants=$(import_param $osc_tgt initial_grant)
8033
8034         check_grants $osc_tgt $init_grants "init grants"
8035
8036         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8037         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8038         local gbs=$(import_param $osc_tgt grant_block_size)
8039
8040         # write random number of bytes from max_brw_size / 4 to max_brw_size
8041         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8042         # align for direct io
8043         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8044         # round to grant consumption unit
8045         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8046
8047         local grants=$((wb_round_up + extent_tax))
8048
8049         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8050
8051         # define OBD_FAIL_TGT_NO_GRANT 0x725
8052         # make the server not grant more back
8053         do_facet ost1 $LCTL set_param fail_loc=0x725
8054         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8055
8056         do_facet ost1 $LCTL set_param fail_loc=0
8057
8058         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8059
8060         rm -f $DIR/$tfile || error "rm failed"
8061
8062         # Remount client to reset grant
8063         remount_client $MOUNT || error "failed to remount client"
8064         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8065
8066         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8067
8068         # define OBD_FAIL_TGT_NO_GRANT 0x725
8069         # make the server not grant more back
8070         do_facet ost1 $LCTL set_param fail_loc=0x725
8071         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8072         do_facet ost1 $LCTL set_param fail_loc=0
8073
8074         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8075 }
8076 run_test 64e "check grant consumption (no grant allocation)"
8077
8078 test_64f() {
8079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8080
8081         # Remount client to reset grant
8082         remount_client $MOUNT || error "failed to remount client"
8083         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8084
8085         local init_grants=$(import_param $osc_tgt initial_grant)
8086         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8087         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8088         local gbs=$(import_param $osc_tgt grant_block_size)
8089         local chunk=$(grant_chunk $osc_tgt)
8090
8091         # write random number of bytes from max_brw_size / 4 to max_brw_size
8092         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8093         # align for direct io
8094         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8095         # round to grant consumption unit
8096         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8097
8098         local grants=$((wb_round_up + extent_tax))
8099
8100         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8101         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8102                 error "error writing to $DIR/$tfile"
8103
8104         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8105                 "direct io with grant allocation"
8106
8107         rm -f $DIR/$tfile || error "rm failed"
8108
8109         # Remount client to reset grant
8110         remount_client $MOUNT || error "failed to remount client"
8111         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8112
8113         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8114
8115         local cmd="oO_WRONLY:w${write_bytes}_yc"
8116
8117         $MULTIOP $DIR/$tfile $cmd &
8118         MULTIPID=$!
8119         sleep 1
8120
8121         check_grants $osc_tgt $((init_grants - grants)) \
8122                 "buffered io, not write rpc"
8123
8124         kill -USR1 $MULTIPID
8125         wait
8126
8127         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8128                 "buffered io, one RPC"
8129 }
8130 run_test 64f "check grant consumption (with grant allocation)"
8131
8132 # bug 1414 - set/get directories' stripe info
8133 test_65a() {
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         test_mkdir $DIR/$tdir
8137         touch $DIR/$tdir/f1
8138         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8139 }
8140 run_test 65a "directory with no stripe info"
8141
8142 test_65b() {
8143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8144
8145         test_mkdir $DIR/$tdir
8146         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8147
8148         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8149                                                 error "setstripe"
8150         touch $DIR/$tdir/f2
8151         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8152 }
8153 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8154
8155 test_65c() {
8156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8157         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8158
8159         test_mkdir $DIR/$tdir
8160         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8161
8162         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8163                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8164         touch $DIR/$tdir/f3
8165         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8166 }
8167 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8168
8169 test_65d() {
8170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8171
8172         test_mkdir $DIR/$tdir
8173         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8174         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8175
8176         if [[ $STRIPECOUNT -le 0 ]]; then
8177                 sc=1
8178         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8179                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8180                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8181         else
8182                 sc=$(($STRIPECOUNT - 1))
8183         fi
8184         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8185         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8186         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8187                 error "lverify failed"
8188 }
8189 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8190
8191 test_65e() {
8192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8193
8194         test_mkdir $DIR/$tdir
8195
8196         $LFS setstripe $DIR/$tdir || error "setstripe"
8197         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8198                                         error "no stripe info failed"
8199         touch $DIR/$tdir/f6
8200         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8201 }
8202 run_test 65e "directory setstripe defaults"
8203
8204 test_65f() {
8205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8206
8207         test_mkdir $DIR/${tdir}f
8208         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8209                 error "setstripe succeeded" || true
8210 }
8211 run_test 65f "dir setstripe permission (should return error) ==="
8212
8213 test_65g() {
8214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8215
8216         test_mkdir $DIR/$tdir
8217         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8218
8219         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8220                 error "setstripe -S failed"
8221         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8222         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8223                 error "delete default stripe failed"
8224 }
8225 run_test 65g "directory setstripe -d"
8226
8227 test_65h() {
8228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8229
8230         test_mkdir $DIR/$tdir
8231         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8232
8233         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8234                 error "setstripe -S failed"
8235         test_mkdir $DIR/$tdir/dd1
8236         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8237                 error "stripe info inherit failed"
8238 }
8239 run_test 65h "directory stripe info inherit ===================="
8240
8241 test_65i() {
8242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8243
8244         save_layout_restore_at_exit $MOUNT
8245
8246         # bug6367: set non-default striping on root directory
8247         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8248
8249         # bug12836: getstripe on -1 default directory striping
8250         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8251
8252         # bug12836: getstripe -v on -1 default directory striping
8253         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8254
8255         # bug12836: new find on -1 default directory striping
8256         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8257 }
8258 run_test 65i "various tests to set root directory striping"
8259
8260 test_65j() { # bug6367
8261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8262
8263         sync; sleep 1
8264
8265         # if we aren't already remounting for each test, do so for this test
8266         if [ "$I_MOUNTED" = "yes" ]; then
8267                 cleanup || error "failed to unmount"
8268                 setup
8269         fi
8270
8271         save_layout_restore_at_exit $MOUNT
8272
8273         $LFS setstripe -d $MOUNT || error "setstripe failed"
8274 }
8275 run_test 65j "set default striping on root directory (bug 6367)="
8276
8277 cleanup_65k() {
8278         rm -rf $DIR/$tdir
8279         wait_delete_completed
8280         do_facet $SINGLEMDS "lctl set_param -n \
8281                 osp.$ost*MDT0000.max_create_count=$max_count"
8282         do_facet $SINGLEMDS "lctl set_param -n \
8283                 osp.$ost*MDT0000.create_count=$count"
8284         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8285         echo $INACTIVE_OSC "is Activate"
8286
8287         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8288 }
8289
8290 test_65k() { # bug11679
8291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8292         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8293         remote_mds_nodsh && skip "remote MDS with nodsh"
8294
8295         local disable_precreate=true
8296         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8297                 disable_precreate=false
8298
8299         echo "Check OST status: "
8300         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8301                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8302
8303         for OSC in $MDS_OSCS; do
8304                 echo $OSC "is active"
8305                 do_facet $SINGLEMDS lctl --device %$OSC activate
8306         done
8307
8308         for INACTIVE_OSC in $MDS_OSCS; do
8309                 local ost=$(osc_to_ost $INACTIVE_OSC)
8310                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8311                                lov.*md*.target_obd |
8312                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8313
8314                 mkdir -p $DIR/$tdir
8315                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8316                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8317
8318                 echo "Deactivate: " $INACTIVE_OSC
8319                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8320
8321                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8322                               osp.$ost*MDT0000.create_count")
8323                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8324                                   osp.$ost*MDT0000.max_create_count")
8325                 $disable_precreate &&
8326                         do_facet $SINGLEMDS "lctl set_param -n \
8327                                 osp.$ost*MDT0000.max_create_count=0"
8328
8329                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8330                         [ -f $DIR/$tdir/$idx ] && continue
8331                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8332                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8333                                 { cleanup_65k;
8334                                   error "setstripe $idx should succeed"; }
8335                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8336                 done
8337                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8338                 rmdir $DIR/$tdir
8339
8340                 do_facet $SINGLEMDS "lctl set_param -n \
8341                         osp.$ost*MDT0000.max_create_count=$max_count"
8342                 do_facet $SINGLEMDS "lctl set_param -n \
8343                         osp.$ost*MDT0000.create_count=$count"
8344                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8345                 echo $INACTIVE_OSC "is Activate"
8346
8347                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8348         done
8349 }
8350 run_test 65k "validate manual striping works properly with deactivated OSCs"
8351
8352 test_65l() { # bug 12836
8353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8354
8355         test_mkdir -p $DIR/$tdir/test_dir
8356         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8357         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8358 }
8359 run_test 65l "lfs find on -1 stripe dir ========================"
8360
8361 test_65m() {
8362         local layout=$(save_layout $MOUNT)
8363         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8364                 restore_layout $MOUNT $layout
8365                 error "setstripe should fail by non-root users"
8366         }
8367         true
8368 }
8369 run_test 65m "normal user can't set filesystem default stripe"
8370
8371 test_65n() {
8372         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8373         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8374                 skip "Need MDS version at least 2.12.50"
8375         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8376
8377         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8378         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8379         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8380
8381         local root_layout=$(save_layout $MOUNT)
8382         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8383
8384         # new subdirectory under root directory should not inherit
8385         # the default layout from root
8386         local dir1=$MOUNT/$tdir-1
8387         mkdir $dir1 || error "mkdir $dir1 failed"
8388         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8389                 error "$dir1 shouldn't have LOV EA"
8390
8391         # delete the default layout on root directory
8392         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8393
8394         local dir2=$MOUNT/$tdir-2
8395         mkdir $dir2 || error "mkdir $dir2 failed"
8396         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8397                 error "$dir2 shouldn't have LOV EA"
8398
8399         # set a new striping pattern on root directory
8400         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8401         local new_def_stripe_size=$((def_stripe_size * 2))
8402         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8403                 error "set stripe size on $MOUNT failed"
8404
8405         # new file created in $dir2 should inherit the new stripe size from
8406         # the filesystem default
8407         local file2=$dir2/$tfile-2
8408         touch $file2 || error "touch $file2 failed"
8409
8410         local file2_stripe_size=$($LFS getstripe -S $file2)
8411         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8412         {
8413                 echo "file2_stripe_size: '$file2_stripe_size'"
8414                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8415                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8416         }
8417
8418         local dir3=$MOUNT/$tdir-3
8419         mkdir $dir3 || error "mkdir $dir3 failed"
8420         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8421         # the root layout, which is the actual default layout that will be used
8422         # when new files are created in $dir3.
8423         local dir3_layout=$(get_layout_param $dir3)
8424         local root_dir_layout=$(get_layout_param $MOUNT)
8425         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8426         {
8427                 echo "dir3_layout: '$dir3_layout'"
8428                 echo "root_dir_layout: '$root_dir_layout'"
8429                 error "$dir3 should show the default layout from $MOUNT"
8430         }
8431
8432         # set OST pool on root directory
8433         local pool=$TESTNAME
8434         pool_add $pool || error "add $pool failed"
8435         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8436                 error "add targets to $pool failed"
8437
8438         $LFS setstripe -p $pool $MOUNT ||
8439                 error "set OST pool on $MOUNT failed"
8440
8441         # new file created in $dir3 should inherit the pool from
8442         # the filesystem default
8443         local file3=$dir3/$tfile-3
8444         touch $file3 || error "touch $file3 failed"
8445
8446         local file3_pool=$($LFS getstripe -p $file3)
8447         [[ "$file3_pool" = "$pool" ]] ||
8448                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8449
8450         local dir4=$MOUNT/$tdir-4
8451         mkdir $dir4 || error "mkdir $dir4 failed"
8452         local dir4_layout=$(get_layout_param $dir4)
8453         root_dir_layout=$(get_layout_param $MOUNT)
8454         echo "$LFS getstripe -d $dir4"
8455         $LFS getstripe -d $dir4
8456         echo "$LFS getstripe -d $MOUNT"
8457         $LFS getstripe -d $MOUNT
8458         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8459         {
8460                 echo "dir4_layout: '$dir4_layout'"
8461                 echo "root_dir_layout: '$root_dir_layout'"
8462                 error "$dir4 should show the default layout from $MOUNT"
8463         }
8464
8465         # new file created in $dir4 should inherit the pool from
8466         # the filesystem default
8467         local file4=$dir4/$tfile-4
8468         touch $file4 || error "touch $file4 failed"
8469
8470         local file4_pool=$($LFS getstripe -p $file4)
8471         [[ "$file4_pool" = "$pool" ]] ||
8472                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8473
8474         # new subdirectory under non-root directory should inherit
8475         # the default layout from its parent directory
8476         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8477                 error "set directory layout on $dir4 failed"
8478
8479         local dir5=$dir4/$tdir-5
8480         mkdir $dir5 || error "mkdir $dir5 failed"
8481
8482         dir4_layout=$(get_layout_param $dir4)
8483         local dir5_layout=$(get_layout_param $dir5)
8484         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8485         {
8486                 echo "dir4_layout: '$dir4_layout'"
8487                 echo "dir5_layout: '$dir5_layout'"
8488                 error "$dir5 should inherit the default layout from $dir4"
8489         }
8490
8491         # though subdir under ROOT doesn't inherit default layout, but
8492         # its sub dir/file should be created with default layout.
8493         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8494         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8495                 skip "Need MDS version at least 2.12.59"
8496
8497         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8498         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8499         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8500
8501         if [ $default_lmv_hash == "none" ]; then
8502                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8503         else
8504                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8505                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8506         fi
8507
8508         $LFS setdirstripe -D -c 2 $MOUNT ||
8509                 error "setdirstripe -D -c 2 failed"
8510         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8511         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8512         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8513 }
8514 run_test 65n "don't inherit default layout from root for new subdirectories"
8515
8516 # bug 2543 - update blocks count on client
8517 test_66() {
8518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8519
8520         COUNT=${COUNT:-8}
8521         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8522         sync; sync_all_data; sync; sync_all_data
8523         cancel_lru_locks osc
8524         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8525         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8526 }
8527 run_test 66 "update inode blocks count on client ==============="
8528
8529 meminfo() {
8530         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8531 }
8532
8533 swap_used() {
8534         swapon -s | awk '($1 == "'$1'") { print $4 }'
8535 }
8536
8537 # bug5265, obdfilter oa2dentry return -ENOENT
8538 # #define OBD_FAIL_SRV_ENOENT 0x217
8539 test_69() {
8540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8541         remote_ost_nodsh && skip "remote OST with nodsh"
8542
8543         f="$DIR/$tfile"
8544         $LFS setstripe -c 1 -i 0 $f
8545
8546         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8547
8548         do_facet ost1 lctl set_param fail_loc=0x217
8549         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8550         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8551
8552         do_facet ost1 lctl set_param fail_loc=0
8553         $DIRECTIO write $f 0 2 || error "write error"
8554
8555         cancel_lru_locks osc
8556         $DIRECTIO read $f 0 1 || error "read error"
8557
8558         do_facet ost1 lctl set_param fail_loc=0x217
8559         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8560
8561         do_facet ost1 lctl set_param fail_loc=0
8562         rm -f $f
8563 }
8564 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8565
8566 test_71() {
8567         test_mkdir $DIR/$tdir
8568         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8569         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8570 }
8571 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8572
8573 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8575         [ "$RUNAS_ID" = "$UID" ] &&
8576                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8577         # Check that testing environment is properly set up. Skip if not
8578         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8579                 skip_env "User $RUNAS_ID does not exist - skipping"
8580
8581         touch $DIR/$tfile
8582         chmod 777 $DIR/$tfile
8583         chmod ug+s $DIR/$tfile
8584         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8585                 error "$RUNAS dd $DIR/$tfile failed"
8586         # See if we are still setuid/sgid
8587         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8588                 error "S/gid is not dropped on write"
8589         # Now test that MDS is updated too
8590         cancel_lru_locks mdc
8591         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8592                 error "S/gid is not dropped on MDS"
8593         rm -f $DIR/$tfile
8594 }
8595 run_test 72a "Test that remove suid works properly (bug5695) ===="
8596
8597 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8598         local perm
8599
8600         [ "$RUNAS_ID" = "$UID" ] &&
8601                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8602         [ "$RUNAS_ID" -eq 0 ] &&
8603                 skip_env "RUNAS_ID = 0 -- skipping"
8604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8605         # Check that testing environment is properly set up. Skip if not
8606         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8607                 skip_env "User $RUNAS_ID does not exist - skipping"
8608
8609         touch $DIR/${tfile}-f{g,u}
8610         test_mkdir $DIR/${tfile}-dg
8611         test_mkdir $DIR/${tfile}-du
8612         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8613         chmod g+s $DIR/${tfile}-{f,d}g
8614         chmod u+s $DIR/${tfile}-{f,d}u
8615         for perm in 777 2777 4777; do
8616                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8617                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8618                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8619                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8620         done
8621         true
8622 }
8623 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8624
8625 # bug 3462 - multiple simultaneous MDC requests
8626 test_73() {
8627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8628
8629         test_mkdir $DIR/d73-1
8630         test_mkdir $DIR/d73-2
8631         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8632         pid1=$!
8633
8634         lctl set_param fail_loc=0x80000129
8635         $MULTIOP $DIR/d73-1/f73-2 Oc &
8636         sleep 1
8637         lctl set_param fail_loc=0
8638
8639         $MULTIOP $DIR/d73-2/f73-3 Oc &
8640         pid3=$!
8641
8642         kill -USR1 $pid1
8643         wait $pid1 || return 1
8644
8645         sleep 25
8646
8647         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8648         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8649         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8650
8651         rm -rf $DIR/d73-*
8652 }
8653 run_test 73 "multiple MDC requests (should not deadlock)"
8654
8655 test_74a() { # bug 6149, 6184
8656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8657
8658         touch $DIR/f74a
8659         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8660         #
8661         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8662         # will spin in a tight reconnection loop
8663         $LCTL set_param fail_loc=0x8000030e
8664         # get any lock that won't be difficult - lookup works.
8665         ls $DIR/f74a
8666         $LCTL set_param fail_loc=0
8667         rm -f $DIR/f74a
8668         true
8669 }
8670 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8671
8672 test_74b() { # bug 13310
8673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8674
8675         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8676         #
8677         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8678         # will spin in a tight reconnection loop
8679         $LCTL set_param fail_loc=0x8000030e
8680         # get a "difficult" lock
8681         touch $DIR/f74b
8682         $LCTL set_param fail_loc=0
8683         rm -f $DIR/f74b
8684         true
8685 }
8686 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8687
8688 test_74c() {
8689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8690
8691         #define OBD_FAIL_LDLM_NEW_LOCK
8692         $LCTL set_param fail_loc=0x319
8693         touch $DIR/$tfile && error "touch successful"
8694         $LCTL set_param fail_loc=0
8695         true
8696 }
8697 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8698
8699 slab_lic=/sys/kernel/slab/lustre_inode_cache
8700 num_objects() {
8701         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8702         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8703                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8704 }
8705
8706 test_76a() { # Now for b=20433, added originally in b=1443
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         cancel_lru_locks osc
8710         # there may be some slab objects cached per core
8711         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8712         local before=$(num_objects)
8713         local count=$((512 * cpus))
8714         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8715         local margin=$((count / 10))
8716         if [[ -f $slab_lic/aliases ]]; then
8717                 local aliases=$(cat $slab_lic/aliases)
8718                 (( aliases > 0 )) && margin=$((margin * aliases))
8719         fi
8720
8721         echo "before slab objects: $before"
8722         for i in $(seq $count); do
8723                 touch $DIR/$tfile
8724                 rm -f $DIR/$tfile
8725         done
8726         cancel_lru_locks osc
8727         local after=$(num_objects)
8728         echo "created: $count, after slab objects: $after"
8729         # shared slab counts are not very accurate, allow significant margin
8730         # the main goal is that the cache growth is not permanently > $count
8731         while (( after > before + margin )); do
8732                 sleep 1
8733                 after=$(num_objects)
8734                 wait=$((wait + 1))
8735                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8736                 if (( wait > 60 )); then
8737                         error "inode slab grew from $before+$margin to $after"
8738                 fi
8739         done
8740 }
8741 run_test 76a "confirm clients recycle inodes properly ===="
8742
8743 test_76b() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8746
8747         local count=512
8748         local before=$(num_objects)
8749
8750         for i in $(seq $count); do
8751                 mkdir $DIR/$tdir
8752                 rmdir $DIR/$tdir
8753         done
8754
8755         local after=$(num_objects)
8756         local wait=0
8757
8758         while (( after > before )); do
8759                 sleep 1
8760                 after=$(num_objects)
8761                 wait=$((wait + 1))
8762                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8763                 if (( wait > 60 )); then
8764                         error "inode slab grew from $before to $after"
8765                 fi
8766         done
8767
8768         echo "slab objects before: $before, after: $after"
8769 }
8770 run_test 76b "confirm clients recycle directory inodes properly ===="
8771
8772 export ORIG_CSUM=""
8773 set_checksums()
8774 {
8775         # Note: in sptlrpc modes which enable its own bulk checksum, the
8776         # original crc32_le bulk checksum will be automatically disabled,
8777         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8778         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8779         # In this case set_checksums() will not be no-op, because sptlrpc
8780         # bulk checksum will be enabled all through the test.
8781
8782         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8783         lctl set_param -n osc.*.checksums $1
8784         return 0
8785 }
8786
8787 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8788                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8789 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8790                              tr -d [] | head -n1)}
8791 set_checksum_type()
8792 {
8793         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8794         rc=$?
8795         log "set checksum type to $1, rc = $rc"
8796         return $rc
8797 }
8798
8799 get_osc_checksum_type()
8800 {
8801         # arugment 1: OST name, like OST0000
8802         ost=$1
8803         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8804                         sed 's/.*\[\(.*\)\].*/\1/g')
8805         rc=$?
8806         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8807         echo $checksum_type
8808 }
8809
8810 F77_TMP=$TMP/f77-temp
8811 F77SZ=8
8812 setup_f77() {
8813         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8814                 error "error writing to $F77_TMP"
8815 }
8816
8817 test_77a() { # bug 10889
8818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8819         $GSS && skip_env "could not run with gss"
8820
8821         [ ! -f $F77_TMP ] && setup_f77
8822         set_checksums 1
8823         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8824         set_checksums 0
8825         rm -f $DIR/$tfile
8826 }
8827 run_test 77a "normal checksum read/write operation"
8828
8829 test_77b() { # bug 10889
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831         $GSS && skip_env "could not run with gss"
8832
8833         [ ! -f $F77_TMP ] && setup_f77
8834         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8835         $LCTL set_param fail_loc=0x80000409
8836         set_checksums 1
8837
8838         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8839                 error "dd error: $?"
8840         $LCTL set_param fail_loc=0
8841
8842         for algo in $CKSUM_TYPES; do
8843                 cancel_lru_locks osc
8844                 set_checksum_type $algo
8845                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8846                 $LCTL set_param fail_loc=0x80000408
8847                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8848                 $LCTL set_param fail_loc=0
8849         done
8850         set_checksums 0
8851         set_checksum_type $ORIG_CSUM_TYPE
8852         rm -f $DIR/$tfile
8853 }
8854 run_test 77b "checksum error on client write, read"
8855
8856 cleanup_77c() {
8857         trap 0
8858         set_checksums 0
8859         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8860         $check_ost &&
8861                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8862         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8863         $check_ost && [ -n "$ost_file_prefix" ] &&
8864                 do_facet ost1 rm -f ${ost_file_prefix}\*
8865 }
8866
8867 test_77c() {
8868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8869         $GSS && skip_env "could not run with gss"
8870         remote_ost_nodsh && skip "remote OST with nodsh"
8871
8872         local bad1
8873         local osc_file_prefix
8874         local osc_file
8875         local check_ost=false
8876         local ost_file_prefix
8877         local ost_file
8878         local orig_cksum
8879         local dump_cksum
8880         local fid
8881
8882         # ensure corruption will occur on first OSS/OST
8883         $LFS setstripe -i 0 $DIR/$tfile
8884
8885         [ ! -f $F77_TMP ] && setup_f77
8886         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8887                 error "dd write error: $?"
8888         fid=$($LFS path2fid $DIR/$tfile)
8889
8890         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8891         then
8892                 check_ost=true
8893                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8894                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8895         else
8896                 echo "OSS do not support bulk pages dump upon error"
8897         fi
8898
8899         osc_file_prefix=$($LCTL get_param -n debug_path)
8900         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8901
8902         trap cleanup_77c EXIT
8903
8904         set_checksums 1
8905         # enable bulk pages dump upon error on Client
8906         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8907         # enable bulk pages dump upon error on OSS
8908         $check_ost &&
8909                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8910
8911         # flush Client cache to allow next read to reach OSS
8912         cancel_lru_locks osc
8913
8914         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8915         $LCTL set_param fail_loc=0x80000408
8916         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8917         $LCTL set_param fail_loc=0
8918
8919         rm -f $DIR/$tfile
8920
8921         # check cksum dump on Client
8922         osc_file=$(ls ${osc_file_prefix}*)
8923         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8924         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8925         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8926         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8927         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8928                      cksum)
8929         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8930         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8931                 error "dump content does not match on Client"
8932
8933         $check_ost || skip "No need to check cksum dump on OSS"
8934
8935         # check cksum dump on OSS
8936         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8937         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8938         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8939         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8940         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8941                 error "dump content does not match on OSS"
8942
8943         cleanup_77c
8944 }
8945 run_test 77c "checksum error on client read with debug"
8946
8947 test_77d() { # bug 10889
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949         $GSS && skip_env "could not run with gss"
8950
8951         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8952         $LCTL set_param fail_loc=0x80000409
8953         set_checksums 1
8954         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8955                 error "direct write: rc=$?"
8956         $LCTL set_param fail_loc=0
8957         set_checksums 0
8958
8959         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8960         $LCTL set_param fail_loc=0x80000408
8961         set_checksums 1
8962         cancel_lru_locks osc
8963         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8964                 error "direct read: rc=$?"
8965         $LCTL set_param fail_loc=0
8966         set_checksums 0
8967 }
8968 run_test 77d "checksum error on OST direct write, read"
8969
8970 test_77f() { # bug 10889
8971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8972         $GSS && skip_env "could not run with gss"
8973
8974         set_checksums 1
8975         for algo in $CKSUM_TYPES; do
8976                 cancel_lru_locks osc
8977                 set_checksum_type $algo
8978                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8979                 $LCTL set_param fail_loc=0x409
8980                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8981                         error "direct write succeeded"
8982                 $LCTL set_param fail_loc=0
8983         done
8984         set_checksum_type $ORIG_CSUM_TYPE
8985         set_checksums 0
8986 }
8987 run_test 77f "repeat checksum error on write (expect error)"
8988
8989 test_77g() { # bug 10889
8990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8991         $GSS && skip_env "could not run with gss"
8992         remote_ost_nodsh && skip "remote OST with nodsh"
8993
8994         [ ! -f $F77_TMP ] && setup_f77
8995
8996         local file=$DIR/$tfile
8997         stack_trap "rm -f $file" EXIT
8998
8999         $LFS setstripe -c 1 -i 0 $file
9000         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9001         do_facet ost1 lctl set_param fail_loc=0x8000021a
9002         set_checksums 1
9003         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9004                 error "write error: rc=$?"
9005         do_facet ost1 lctl set_param fail_loc=0
9006         set_checksums 0
9007
9008         cancel_lru_locks osc
9009         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9010         do_facet ost1 lctl set_param fail_loc=0x8000021b
9011         set_checksums 1
9012         cmp $F77_TMP $file || error "file compare failed"
9013         do_facet ost1 lctl set_param fail_loc=0
9014         set_checksums 0
9015 }
9016 run_test 77g "checksum error on OST write, read"
9017
9018 test_77k() { # LU-10906
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020         $GSS && skip_env "could not run with gss"
9021
9022         local cksum_param="osc.$FSNAME*.checksums"
9023         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9024         local checksum
9025         local i
9026
9027         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9028         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9029         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9030
9031         for i in 0 1; do
9032                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9033                         error "failed to set checksum=$i on MGS"
9034                 wait_update $HOSTNAME "$get_checksum" $i
9035                 #remount
9036                 echo "remount client, checksum should be $i"
9037                 remount_client $MOUNT || error "failed to remount client"
9038                 checksum=$(eval $get_checksum)
9039                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9040         done
9041         # remove persistent param to avoid races with checksum mountopt below
9042         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9043                 error "failed to delete checksum on MGS"
9044
9045         for opt in "checksum" "nochecksum"; do
9046                 #remount with mount option
9047                 echo "remount client with option $opt, checksum should be $i"
9048                 umount_client $MOUNT || error "failed to umount client"
9049                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9050                         error "failed to mount client with option '$opt'"
9051                 checksum=$(eval $get_checksum)
9052                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9053                 i=$((i - 1))
9054         done
9055
9056         remount_client $MOUNT || error "failed to remount client"
9057 }
9058 run_test 77k "enable/disable checksum correctly"
9059
9060 test_77l() {
9061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9062         $GSS && skip_env "could not run with gss"
9063
9064         set_checksums 1
9065         stack_trap "set_checksums $ORIG_CSUM" EXIT
9066         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9067
9068         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9069
9070         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9071         for algo in $CKSUM_TYPES; do
9072                 set_checksum_type $algo || error "fail to set checksum type $algo"
9073                 osc_algo=$(get_osc_checksum_type OST0000)
9074                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9075
9076                 # no locks, no reqs to let the connection idle
9077                 cancel_lru_locks osc
9078                 lru_resize_disable osc
9079                 wait_osc_import_state client ost1 IDLE
9080
9081                 # ensure ost1 is connected
9082                 stat $DIR/$tfile >/dev/null || error "can't stat"
9083                 wait_osc_import_state client ost1 FULL
9084
9085                 osc_algo=$(get_osc_checksum_type OST0000)
9086                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9087         done
9088         return 0
9089 }
9090 run_test 77l "preferred checksum type is remembered after reconnected"
9091
9092 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9093 rm -f $F77_TMP
9094 unset F77_TMP
9095
9096 cleanup_test_78() {
9097         trap 0
9098         rm -f $DIR/$tfile
9099 }
9100
9101 test_78() { # bug 10901
9102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9103         remote_ost || skip_env "local OST"
9104
9105         NSEQ=5
9106         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9107         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9108         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9109         echo "MemTotal: $MEMTOTAL"
9110
9111         # reserve 256MB of memory for the kernel and other running processes,
9112         # and then take 1/2 of the remaining memory for the read/write buffers.
9113         if [ $MEMTOTAL -gt 512 ] ;then
9114                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9115         else
9116                 # for those poor memory-starved high-end clusters...
9117                 MEMTOTAL=$((MEMTOTAL / 2))
9118         fi
9119         echo "Mem to use for directio: $MEMTOTAL"
9120
9121         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9122         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9123         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9124         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9125                 head -n1)
9126         echo "Smallest OST: $SMALLESTOST"
9127         [[ $SMALLESTOST -lt 10240 ]] &&
9128                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9129
9130         trap cleanup_test_78 EXIT
9131
9132         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9133                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9134
9135         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9136         echo "File size: $F78SIZE"
9137         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9138         for i in $(seq 1 $NSEQ); do
9139                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9140                 echo directIO rdwr round $i of $NSEQ
9141                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9142         done
9143
9144         cleanup_test_78
9145 }
9146 run_test 78 "handle large O_DIRECT writes correctly ============"
9147
9148 test_79() { # bug 12743
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150
9151         wait_delete_completed
9152
9153         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9154         BKFREE=$(calc_osc_kbytes kbytesfree)
9155         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9156
9157         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9158         DFTOTAL=`echo $STRING | cut -d, -f1`
9159         DFUSED=`echo $STRING  | cut -d, -f2`
9160         DFAVAIL=`echo $STRING | cut -d, -f3`
9161         DFFREE=$(($DFTOTAL - $DFUSED))
9162
9163         ALLOWANCE=$((64 * $OSTCOUNT))
9164
9165         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9166            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9167                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9168         fi
9169         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9170            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9171                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9172         fi
9173         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9174            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9175                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9176         fi
9177 }
9178 run_test 79 "df report consistency check ======================="
9179
9180 test_80() { # bug 10718
9181         remote_ost_nodsh && skip "remote OST with nodsh"
9182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9183
9184         # relax strong synchronous semantics for slow backends like ZFS
9185         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9186                 local soc="obdfilter.*.sync_lock_cancel"
9187                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9188
9189                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9190                 if [ -z "$save" ]; then
9191                         soc="obdfilter.*.sync_on_lock_cancel"
9192                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9193                 fi
9194
9195                 if [ "$save" != "never" ]; then
9196                         local hosts=$(comma_list $(osts_nodes))
9197
9198                         do_nodes $hosts $LCTL set_param $soc=never
9199                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9200                 fi
9201         fi
9202
9203         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9204         sync; sleep 1; sync
9205         local before=$(date +%s)
9206         cancel_lru_locks osc
9207         local after=$(date +%s)
9208         local diff=$((after - before))
9209         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9210
9211         rm -f $DIR/$tfile
9212 }
9213 run_test 80 "Page eviction is equally fast at high offsets too"
9214
9215 test_81a() { # LU-456
9216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9217         remote_ost_nodsh && skip "remote OST with nodsh"
9218
9219         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9220         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9221         do_facet ost1 lctl set_param fail_loc=0x80000228
9222
9223         # write should trigger a retry and success
9224         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9226         RC=$?
9227         if [ $RC -ne 0 ] ; then
9228                 error "write should success, but failed for $RC"
9229         fi
9230 }
9231 run_test 81a "OST should retry write when get -ENOSPC ==============="
9232
9233 test_81b() { # LU-456
9234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9235         remote_ost_nodsh && skip "remote OST with nodsh"
9236
9237         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9238         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9239         do_facet ost1 lctl set_param fail_loc=0x228
9240
9241         # write should retry several times and return -ENOSPC finally
9242         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9243         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9244         RC=$?
9245         ENOSPC=28
9246         if [ $RC -ne $ENOSPC ] ; then
9247                 error "dd should fail for -ENOSPC, but succeed."
9248         fi
9249 }
9250 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9251
9252 test_99() {
9253         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9254
9255         test_mkdir $DIR/$tdir.cvsroot
9256         chown $RUNAS_ID $DIR/$tdir.cvsroot
9257
9258         cd $TMP
9259         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9260
9261         cd /etc/init.d
9262         # some versions of cvs import exit(1) when asked to import links or
9263         # files they can't read.  ignore those files.
9264         local toignore=$(find . -type l -printf '-I %f\n' -o \
9265                          ! -perm /4 -printf '-I %f\n')
9266         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9267                 $tdir.reposname vtag rtag
9268
9269         cd $DIR
9270         test_mkdir $DIR/$tdir.reposname
9271         chown $RUNAS_ID $DIR/$tdir.reposname
9272         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9273
9274         cd $DIR/$tdir.reposname
9275         $RUNAS touch foo99
9276         $RUNAS cvs add -m 'addmsg' foo99
9277         $RUNAS cvs update
9278         $RUNAS cvs commit -m 'nomsg' foo99
9279         rm -fr $DIR/$tdir.cvsroot
9280 }
9281 run_test 99 "cvs strange file/directory operations"
9282
9283 test_100() {
9284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9285         [[ "$NETTYPE" =~ tcp ]] ||
9286                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9287         remote_ost_nodsh && skip "remote OST with nodsh"
9288         remote_mds_nodsh && skip "remote MDS with nodsh"
9289         remote_servers ||
9290                 skip "useless for local single node setup"
9291
9292         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9293                 [ "$PROT" != "tcp" ] && continue
9294                 RPORT=$(echo $REMOTE | cut -d: -f2)
9295                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9296
9297                 rc=0
9298                 LPORT=`echo $LOCAL | cut -d: -f2`
9299                 if [ $LPORT -ge 1024 ]; then
9300                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9301                         netstat -tna
9302                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9303                 fi
9304         done
9305         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9306 }
9307 run_test 100 "check local port using privileged port ==========="
9308
9309 function get_named_value()
9310 {
9311     local tag
9312
9313     tag=$1
9314     while read ;do
9315         line=$REPLY
9316         case $line in
9317         $tag*)
9318             echo $line | sed "s/^$tag[ ]*//"
9319             break
9320             ;;
9321         esac
9322     done
9323 }
9324
9325 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9326                    awk '/^max_cached_mb/ { print $2 }')
9327
9328 cleanup_101a() {
9329         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9330         trap 0
9331 }
9332
9333 test_101a() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         local s
9337         local discard
9338         local nreads=10000
9339         local cache_limit=32
9340
9341         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9342         trap cleanup_101a EXIT
9343         $LCTL set_param -n llite.*.read_ahead_stats 0
9344         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9345
9346         #
9347         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9348         #
9349         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9350         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9351
9352         discard=0
9353         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9354                 get_named_value 'read but discarded' | cut -d" " -f1); do
9355                         discard=$(($discard + $s))
9356         done
9357         cleanup_101a
9358
9359         $LCTL get_param osc.*-osc*.rpc_stats
9360         $LCTL get_param llite.*.read_ahead_stats
9361
9362         # Discard is generally zero, but sometimes a few random reads line up
9363         # and trigger larger readahead, which is wasted & leads to discards.
9364         if [[ $(($discard)) -gt $nreads ]]; then
9365                 error "too many ($discard) discarded pages"
9366         fi
9367         rm -f $DIR/$tfile || true
9368 }
9369 run_test 101a "check read-ahead for random reads"
9370
9371 setup_test101bc() {
9372         test_mkdir $DIR/$tdir
9373         local ssize=$1
9374         local FILE_LENGTH=$2
9375         STRIPE_OFFSET=0
9376
9377         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9378
9379         local list=$(comma_list $(osts_nodes))
9380         set_osd_param $list '' read_cache_enable 0
9381         set_osd_param $list '' writethrough_cache_enable 0
9382
9383         trap cleanup_test101bc EXIT
9384         # prepare the read-ahead file
9385         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9386
9387         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9388                                 count=$FILE_SIZE_MB 2> /dev/null
9389
9390 }
9391
9392 cleanup_test101bc() {
9393         trap 0
9394         rm -rf $DIR/$tdir
9395         rm -f $DIR/$tfile
9396
9397         local list=$(comma_list $(osts_nodes))
9398         set_osd_param $list '' read_cache_enable 1
9399         set_osd_param $list '' writethrough_cache_enable 1
9400 }
9401
9402 calc_total() {
9403         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9404 }
9405
9406 ra_check_101() {
9407         local READ_SIZE=$1
9408         local STRIPE_SIZE=$2
9409         local FILE_LENGTH=$3
9410         local RA_INC=1048576
9411         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9412         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9413                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9414         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9415                         get_named_value 'read but discarded' |
9416                         cut -d" " -f1 | calc_total)
9417         if [[ $DISCARD -gt $discard_limit ]]; then
9418                 $LCTL get_param llite.*.read_ahead_stats
9419                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9420         else
9421                 echo "Read-ahead success for size ${READ_SIZE}"
9422         fi
9423 }
9424
9425 test_101b() {
9426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9427         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9428
9429         local STRIPE_SIZE=1048576
9430         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9431
9432         if [ $SLOW == "yes" ]; then
9433                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9434         else
9435                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9436         fi
9437
9438         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9439
9440         # prepare the read-ahead file
9441         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9442         cancel_lru_locks osc
9443         for BIDX in 2 4 8 16 32 64 128 256
9444         do
9445                 local BSIZE=$((BIDX*4096))
9446                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9447                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9448                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9449                 $LCTL set_param -n llite.*.read_ahead_stats 0
9450                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9451                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9452                 cancel_lru_locks osc
9453                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9454         done
9455         cleanup_test101bc
9456         true
9457 }
9458 run_test 101b "check stride-io mode read-ahead ================="
9459
9460 test_101c() {
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462
9463         local STRIPE_SIZE=1048576
9464         local FILE_LENGTH=$((STRIPE_SIZE*100))
9465         local nreads=10000
9466         local rsize=65536
9467         local osc_rpc_stats
9468
9469         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9470
9471         cancel_lru_locks osc
9472         $LCTL set_param osc.*.rpc_stats 0
9473         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9474         $LCTL get_param osc.*.rpc_stats
9475         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9476                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9477                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9478                 local size
9479
9480                 if [ $lines -le 20 ]; then
9481                         echo "continue debug"
9482                         continue
9483                 fi
9484                 for size in 1 2 4 8; do
9485                         local rpc=$(echo "$stats" |
9486                                     awk '($1 == "'$size':") {print $2; exit; }')
9487                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9488                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9489                 done
9490                 echo "$osc_rpc_stats check passed!"
9491         done
9492         cleanup_test101bc
9493         true
9494 }
9495 run_test 101c "check stripe_size aligned read-ahead ================="
9496
9497 test_101d() {
9498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9499
9500         local file=$DIR/$tfile
9501         local sz_MB=${FILESIZE_101d:-80}
9502         local ra_MB=${READAHEAD_MB:-40}
9503
9504         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9505         [ $free_MB -lt $sz_MB ] &&
9506                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9507
9508         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9509         $LFS setstripe -c -1 $file || error "setstripe failed"
9510
9511         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9512         echo Cancel LRU locks on lustre client to flush the client cache
9513         cancel_lru_locks osc
9514
9515         echo Disable read-ahead
9516         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9517         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9518         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9519         $LCTL get_param -n llite.*.max_read_ahead_mb
9520
9521         echo "Reading the test file $file with read-ahead disabled"
9522         local sz_KB=$((sz_MB * 1024 / 4))
9523         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9524         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9525         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9526                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9527
9528         echo "Cancel LRU locks on lustre client to flush the client cache"
9529         cancel_lru_locks osc
9530         echo Enable read-ahead with ${ra_MB}MB
9531         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9532
9533         echo "Reading the test file $file with read-ahead enabled"
9534         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9535                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9536
9537         echo "read-ahead disabled time read $raOFF"
9538         echo "read-ahead enabled time read $raON"
9539
9540         rm -f $file
9541         wait_delete_completed
9542
9543         # use awk for this check instead of bash because it handles decimals
9544         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9545                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9546 }
9547 run_test 101d "file read with and without read-ahead enabled"
9548
9549 test_101e() {
9550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9551
9552         local file=$DIR/$tfile
9553         local size_KB=500  #KB
9554         local count=100
9555         local bsize=1024
9556
9557         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9558         local need_KB=$((count * size_KB))
9559         [[ $free_KB -le $need_KB ]] &&
9560                 skip_env "Need free space $need_KB, have $free_KB"
9561
9562         echo "Creating $count ${size_KB}K test files"
9563         for ((i = 0; i < $count; i++)); do
9564                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9565         done
9566
9567         echo "Cancel LRU locks on lustre client to flush the client cache"
9568         cancel_lru_locks $OSC
9569
9570         echo "Reset readahead stats"
9571         $LCTL set_param -n llite.*.read_ahead_stats 0
9572
9573         for ((i = 0; i < $count; i++)); do
9574                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9575         done
9576
9577         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9578                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9579
9580         for ((i = 0; i < $count; i++)); do
9581                 rm -rf $file.$i 2>/dev/null
9582         done
9583
9584         #10000 means 20% reads are missing in readahead
9585         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9586 }
9587 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9588
9589 test_101f() {
9590         which iozone || skip_env "no iozone installed"
9591
9592         local old_debug=$($LCTL get_param debug)
9593         old_debug=${old_debug#*=}
9594         $LCTL set_param debug="reada mmap"
9595
9596         # create a test file
9597         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9598
9599         echo Cancel LRU locks on lustre client to flush the client cache
9600         cancel_lru_locks osc
9601
9602         echo Reset readahead stats
9603         $LCTL set_param -n llite.*.read_ahead_stats 0
9604
9605         echo mmap read the file with small block size
9606         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9607                 > /dev/null 2>&1
9608
9609         echo checking missing pages
9610         $LCTL get_param llite.*.read_ahead_stats
9611         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9612                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9613
9614         $LCTL set_param debug="$old_debug"
9615         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9616         rm -f $DIR/$tfile
9617 }
9618 run_test 101f "check mmap read performance"
9619
9620 test_101g_brw_size_test() {
9621         local mb=$1
9622         local pages=$((mb * 1048576 / PAGE_SIZE))
9623         local file=$DIR/$tfile
9624
9625         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9626                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9627         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9628                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9629                         return 2
9630         done
9631
9632         stack_trap "rm -f $file" EXIT
9633         $LCTL set_param -n osc.*.rpc_stats=0
9634
9635         # 10 RPCs should be enough for the test
9636         local count=10
9637         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9638                 { error "dd write ${mb} MB blocks failed"; return 3; }
9639         cancel_lru_locks osc
9640         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9641                 { error "dd write ${mb} MB blocks failed"; return 4; }
9642
9643         # calculate number of full-sized read and write RPCs
9644         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9645                 sed -n '/pages per rpc/,/^$/p' |
9646                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9647                 END { print reads,writes }'))
9648         # allow one extra full-sized read RPC for async readahead
9649         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9650                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9651         [[ ${rpcs[1]} == $count ]] ||
9652                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9653 }
9654
9655 test_101g() {
9656         remote_ost_nodsh && skip "remote OST with nodsh"
9657
9658         local rpcs
9659         local osts=$(get_facets OST)
9660         local list=$(comma_list $(osts_nodes))
9661         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9662         local brw_size="obdfilter.*.brw_size"
9663
9664         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9665
9666         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9667
9668         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9669                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9670                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9671            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9672                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9673                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9674
9675                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9676                         suffix="M"
9677
9678                 if [[ $orig_mb -lt 16 ]]; then
9679                         save_lustre_params $osts "$brw_size" > $p
9680                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9681                                 error "set 16MB RPC size failed"
9682
9683                         echo "remount client to enable new RPC size"
9684                         remount_client $MOUNT || error "remount_client failed"
9685                 fi
9686
9687                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9688                 # should be able to set brw_size=12, but no rpc_stats for that
9689                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9690         fi
9691
9692         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9693
9694         if [[ $orig_mb -lt 16 ]]; then
9695                 restore_lustre_params < $p
9696                 remount_client $MOUNT || error "remount_client restore failed"
9697         fi
9698
9699         rm -f $p $DIR/$tfile
9700 }
9701 run_test 101g "Big bulk(4/16 MiB) readahead"
9702
9703 test_101h() {
9704         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9705
9706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9707                 error "dd 70M file failed"
9708         echo Cancel LRU locks on lustre client to flush the client cache
9709         cancel_lru_locks osc
9710
9711         echo "Reset readahead stats"
9712         $LCTL set_param -n llite.*.read_ahead_stats 0
9713
9714         echo "Read 10M of data but cross 64M bundary"
9715         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9716         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9717                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9718         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9719         rm -f $p $DIR/$tfile
9720 }
9721 run_test 101h "Readahead should cover current read window"
9722
9723 test_101i() {
9724         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9725                 error "dd 10M file failed"
9726
9727         local max_per_file_mb=$($LCTL get_param -n \
9728                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9729         cancel_lru_locks osc
9730         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9731         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9732                 error "set max_read_ahead_per_file_mb to 1 failed"
9733
9734         echo "Reset readahead stats"
9735         $LCTL set_param llite.*.read_ahead_stats=0
9736
9737         dd if=$DIR/$tfile of=/dev/null bs=2M
9738
9739         $LCTL get_param llite.*.read_ahead_stats
9740         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9741                      awk '/misses/ { print $2 }')
9742         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9743         rm -f $DIR/$tfile
9744 }
9745 run_test 101i "allow current readahead to exceed reservation"
9746
9747 test_101j() {
9748         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9749                 error "setstripe $DIR/$tfile failed"
9750         local file_size=$((1048576 * 16))
9751         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9752         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9753
9754         echo Disable read-ahead
9755         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9756
9757         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9758         for blk in $PAGE_SIZE 1048576 $file_size; do
9759                 cancel_lru_locks osc
9760                 echo "Reset readahead stats"
9761                 $LCTL set_param -n llite.*.read_ahead_stats=0
9762                 local count=$(($file_size / $blk))
9763                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9764                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9765                              get_named_value 'failed to fast read' |
9766                              cut -d" " -f1 | calc_total)
9767                 $LCTL get_param -n llite.*.read_ahead_stats
9768                 [ $miss -eq $count ] || error "expected $count got $miss"
9769         done
9770
9771         rm -f $p $DIR/$tfile
9772 }
9773 run_test 101j "A complete read block should be submitted when no RA"
9774
9775 setup_test102() {
9776         test_mkdir $DIR/$tdir
9777         chown $RUNAS_ID $DIR/$tdir
9778         STRIPE_SIZE=65536
9779         STRIPE_OFFSET=1
9780         STRIPE_COUNT=$OSTCOUNT
9781         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9782
9783         trap cleanup_test102 EXIT
9784         cd $DIR
9785         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9786         cd $DIR/$tdir
9787         for num in 1 2 3 4; do
9788                 for count in $(seq 1 $STRIPE_COUNT); do
9789                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9790                                 local size=`expr $STRIPE_SIZE \* $num`
9791                                 local file=file"$num-$idx-$count"
9792                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9793                         done
9794                 done
9795         done
9796
9797         cd $DIR
9798         $1 tar cf $TMP/f102.tar $tdir --xattrs
9799 }
9800
9801 cleanup_test102() {
9802         trap 0
9803         rm -f $TMP/f102.tar
9804         rm -rf $DIR/d0.sanity/d102
9805 }
9806
9807 test_102a() {
9808         [ "$UID" != 0 ] && skip "must run as root"
9809         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9810                 skip_env "must have user_xattr"
9811
9812         [ -z "$(which setfattr 2>/dev/null)" ] &&
9813                 skip_env "could not find setfattr"
9814
9815         local testfile=$DIR/$tfile
9816
9817         touch $testfile
9818         echo "set/get xattr..."
9819         setfattr -n trusted.name1 -v value1 $testfile ||
9820                 error "setfattr -n trusted.name1=value1 $testfile failed"
9821         getfattr -n trusted.name1 $testfile 2> /dev/null |
9822           grep "trusted.name1=.value1" ||
9823                 error "$testfile missing trusted.name1=value1"
9824
9825         setfattr -n user.author1 -v author1 $testfile ||
9826                 error "setfattr -n user.author1=author1 $testfile failed"
9827         getfattr -n user.author1 $testfile 2> /dev/null |
9828           grep "user.author1=.author1" ||
9829                 error "$testfile missing trusted.author1=author1"
9830
9831         echo "listxattr..."
9832         setfattr -n trusted.name2 -v value2 $testfile ||
9833                 error "$testfile unable to set trusted.name2"
9834         setfattr -n trusted.name3 -v value3 $testfile ||
9835                 error "$testfile unable to set trusted.name3"
9836         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9837             grep "trusted.name" | wc -l) -eq 3 ] ||
9838                 error "$testfile missing 3 trusted.name xattrs"
9839
9840         setfattr -n user.author2 -v author2 $testfile ||
9841                 error "$testfile unable to set user.author2"
9842         setfattr -n user.author3 -v author3 $testfile ||
9843                 error "$testfile unable to set user.author3"
9844         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9845             grep "user.author" | wc -l) -eq 3 ] ||
9846                 error "$testfile missing 3 user.author xattrs"
9847
9848         echo "remove xattr..."
9849         setfattr -x trusted.name1 $testfile ||
9850                 error "$testfile error deleting trusted.name1"
9851         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9852                 error "$testfile did not delete trusted.name1 xattr"
9853
9854         setfattr -x user.author1 $testfile ||
9855                 error "$testfile error deleting user.author1"
9856         echo "set lustre special xattr ..."
9857         $LFS setstripe -c1 $testfile
9858         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9859                 awk -F "=" '/trusted.lov/ { print $2 }' )
9860         setfattr -n "trusted.lov" -v $lovea $testfile ||
9861                 error "$testfile doesn't ignore setting trusted.lov again"
9862         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9863                 error "$testfile allow setting invalid trusted.lov"
9864         rm -f $testfile
9865 }
9866 run_test 102a "user xattr test =================================="
9867
9868 check_102b_layout() {
9869         local layout="$*"
9870         local testfile=$DIR/$tfile
9871
9872         echo "test layout '$layout'"
9873         $LFS setstripe $layout $testfile || error "setstripe failed"
9874         $LFS getstripe -y $testfile
9875
9876         echo "get/set/list trusted.lov xattr ..." # b=10930
9877         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9878         [[ "$value" =~ "trusted.lov" ]] ||
9879                 error "can't get trusted.lov from $testfile"
9880         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9881                 error "getstripe failed"
9882
9883         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9884
9885         value=$(cut -d= -f2 <<<$value)
9886         # LU-13168: truncated xattr should fail if short lov_user_md header
9887         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9888                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9889         for len in $lens; do
9890                 echo "setfattr $len $testfile.2"
9891                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9892                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9893         done
9894         local stripe_size=$($LFS getstripe -S $testfile.2)
9895         local stripe_count=$($LFS getstripe -c $testfile.2)
9896         [[ $stripe_size -eq 65536 ]] ||
9897                 error "stripe size $stripe_size != 65536"
9898         [[ $stripe_count -eq $stripe_count_orig ]] ||
9899                 error "stripe count $stripe_count != $stripe_count_orig"
9900         rm $testfile $testfile.2
9901 }
9902
9903 test_102b() {
9904         [ -z "$(which setfattr 2>/dev/null)" ] &&
9905                 skip_env "could not find setfattr"
9906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9907
9908         # check plain layout
9909         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9910
9911         # and also check composite layout
9912         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9913
9914 }
9915 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9916
9917 test_102c() {
9918         [ -z "$(which setfattr 2>/dev/null)" ] &&
9919                 skip_env "could not find setfattr"
9920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9921
9922         # b10930: get/set/list lustre.lov xattr
9923         echo "get/set/list lustre.lov xattr ..."
9924         test_mkdir $DIR/$tdir
9925         chown $RUNAS_ID $DIR/$tdir
9926         local testfile=$DIR/$tdir/$tfile
9927         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9928                 error "setstripe failed"
9929         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9930                 error "getstripe failed"
9931         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9932         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9933
9934         local testfile2=${testfile}2
9935         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9936                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9937
9938         $RUNAS $MCREATE $testfile2
9939         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9940         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9941         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9942         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9943         [ $stripe_count -eq $STRIPECOUNT ] ||
9944                 error "stripe count $stripe_count != $STRIPECOUNT"
9945 }
9946 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9947
9948 compare_stripe_info1() {
9949         local stripe_index_all_zero=true
9950
9951         for num in 1 2 3 4; do
9952                 for count in $(seq 1 $STRIPE_COUNT); do
9953                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9954                                 local size=$((STRIPE_SIZE * num))
9955                                 local file=file"$num-$offset-$count"
9956                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9957                                 [[ $stripe_size -ne $size ]] &&
9958                                     error "$file: size $stripe_size != $size"
9959                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9960                                 # allow fewer stripes to be created, ORI-601
9961                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9962                                     error "$file: count $stripe_count != $count"
9963                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9964                                 [[ $stripe_index -ne 0 ]] &&
9965                                         stripe_index_all_zero=false
9966                         done
9967                 done
9968         done
9969         $stripe_index_all_zero &&
9970                 error "all files are being extracted starting from OST index 0"
9971         return 0
9972 }
9973
9974 have_xattrs_include() {
9975         tar --help | grep -q xattrs-include &&
9976                 echo --xattrs-include="lustre.*"
9977 }
9978
9979 test_102d() {
9980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9981         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9982
9983         XINC=$(have_xattrs_include)
9984         setup_test102
9985         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9986         cd $DIR/$tdir/$tdir
9987         compare_stripe_info1
9988 }
9989 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9990
9991 test_102f() {
9992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9993         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9994
9995         XINC=$(have_xattrs_include)
9996         setup_test102
9997         test_mkdir $DIR/$tdir.restore
9998         cd $DIR
9999         tar cf - --xattrs $tdir | tar xf - \
10000                 -C $DIR/$tdir.restore --xattrs $XINC
10001         cd $DIR/$tdir.restore/$tdir
10002         compare_stripe_info1
10003 }
10004 run_test 102f "tar copy files, not keep osts"
10005
10006 grow_xattr() {
10007         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10008                 skip "must have user_xattr"
10009         [ -z "$(which setfattr 2>/dev/null)" ] &&
10010                 skip_env "could not find setfattr"
10011         [ -z "$(which getfattr 2>/dev/null)" ] &&
10012                 skip_env "could not find getfattr"
10013
10014         local xsize=${1:-1024}  # in bytes
10015         local file=$DIR/$tfile
10016         local value="$(generate_string $xsize)"
10017         local xbig=trusted.big
10018         local toobig=$2
10019
10020         touch $file
10021         log "save $xbig on $file"
10022         if [ -z "$toobig" ]
10023         then
10024                 setfattr -n $xbig -v $value $file ||
10025                         error "saving $xbig on $file failed"
10026         else
10027                 setfattr -n $xbig -v $value $file &&
10028                         error "saving $xbig on $file succeeded"
10029                 return 0
10030         fi
10031
10032         local orig=$(get_xattr_value $xbig $file)
10033         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10034
10035         local xsml=trusted.sml
10036         log "save $xsml on $file"
10037         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10038
10039         local new=$(get_xattr_value $xbig $file)
10040         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10041
10042         log "grow $xsml on $file"
10043         setfattr -n $xsml -v "$value" $file ||
10044                 error "growing $xsml on $file failed"
10045
10046         new=$(get_xattr_value $xbig $file)
10047         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10048         log "$xbig still valid after growing $xsml"
10049
10050         rm -f $file
10051 }
10052
10053 test_102h() { # bug 15777
10054         grow_xattr 1024
10055 }
10056 run_test 102h "grow xattr from inside inode to external block"
10057
10058 test_102ha() {
10059         large_xattr_enabled || skip_env "ea_inode feature disabled"
10060
10061         echo "setting xattr of max xattr size: $(max_xattr_size)"
10062         grow_xattr $(max_xattr_size)
10063
10064         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10065         echo "This should fail:"
10066         grow_xattr $(($(max_xattr_size) + 10)) 1
10067 }
10068 run_test 102ha "grow xattr from inside inode to external inode"
10069
10070 test_102i() { # bug 17038
10071         [ -z "$(which getfattr 2>/dev/null)" ] &&
10072                 skip "could not find getfattr"
10073
10074         touch $DIR/$tfile
10075         ln -s $DIR/$tfile $DIR/${tfile}link
10076         getfattr -n trusted.lov $DIR/$tfile ||
10077                 error "lgetxattr on $DIR/$tfile failed"
10078         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10079                 grep -i "no such attr" ||
10080                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10081         rm -f $DIR/$tfile $DIR/${tfile}link
10082 }
10083 run_test 102i "lgetxattr test on symbolic link ============"
10084
10085 test_102j() {
10086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10087         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10088
10089         XINC=$(have_xattrs_include)
10090         setup_test102 "$RUNAS"
10091         chown $RUNAS_ID $DIR/$tdir
10092         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10093         cd $DIR/$tdir/$tdir
10094         compare_stripe_info1 "$RUNAS"
10095 }
10096 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10097
10098 test_102k() {
10099         [ -z "$(which setfattr 2>/dev/null)" ] &&
10100                 skip "could not find setfattr"
10101
10102         touch $DIR/$tfile
10103         # b22187 just check that does not crash for regular file.
10104         setfattr -n trusted.lov $DIR/$tfile
10105         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10106         local test_kdir=$DIR/$tdir
10107         test_mkdir $test_kdir
10108         local default_size=$($LFS getstripe -S $test_kdir)
10109         local default_count=$($LFS getstripe -c $test_kdir)
10110         local default_offset=$($LFS getstripe -i $test_kdir)
10111         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10112                 error 'dir setstripe failed'
10113         setfattr -n trusted.lov $test_kdir
10114         local stripe_size=$($LFS getstripe -S $test_kdir)
10115         local stripe_count=$($LFS getstripe -c $test_kdir)
10116         local stripe_offset=$($LFS getstripe -i $test_kdir)
10117         [ $stripe_size -eq $default_size ] ||
10118                 error "stripe size $stripe_size != $default_size"
10119         [ $stripe_count -eq $default_count ] ||
10120                 error "stripe count $stripe_count != $default_count"
10121         [ $stripe_offset -eq $default_offset ] ||
10122                 error "stripe offset $stripe_offset != $default_offset"
10123         rm -rf $DIR/$tfile $test_kdir
10124 }
10125 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10126
10127 test_102l() {
10128         [ -z "$(which getfattr 2>/dev/null)" ] &&
10129                 skip "could not find getfattr"
10130
10131         # LU-532 trusted. xattr is invisible to non-root
10132         local testfile=$DIR/$tfile
10133
10134         touch $testfile
10135
10136         echo "listxattr as user..."
10137         chown $RUNAS_ID $testfile
10138         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10139             grep -q "trusted" &&
10140                 error "$testfile trusted xattrs are user visible"
10141
10142         return 0;
10143 }
10144 run_test 102l "listxattr size test =================================="
10145
10146 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10147         local path=$DIR/$tfile
10148         touch $path
10149
10150         listxattr_size_check $path || error "listattr_size_check $path failed"
10151 }
10152 run_test 102m "Ensure listxattr fails on small bufffer ========"
10153
10154 cleanup_test102
10155
10156 getxattr() { # getxattr path name
10157         # Return the base64 encoding of the value of xattr name on path.
10158         local path=$1
10159         local name=$2
10160
10161         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10162         # file: $path
10163         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10164         #
10165         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10166
10167         getfattr --absolute-names --encoding=base64 --name=$name $path |
10168                 awk -F= -v name=$name '$1 == name {
10169                         print substr($0, index($0, "=") + 1);
10170         }'
10171 }
10172
10173 test_102n() { # LU-4101 mdt: protect internal xattrs
10174         [ -z "$(which setfattr 2>/dev/null)" ] &&
10175                 skip "could not find setfattr"
10176         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10177         then
10178                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10179         fi
10180
10181         local file0=$DIR/$tfile.0
10182         local file1=$DIR/$tfile.1
10183         local xattr0=$TMP/$tfile.0
10184         local xattr1=$TMP/$tfile.1
10185         local namelist="lov lma lmv link fid version som hsm"
10186         local name
10187         local value
10188
10189         rm -rf $file0 $file1 $xattr0 $xattr1
10190         touch $file0 $file1
10191
10192         # Get 'before' xattrs of $file1.
10193         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10194
10195         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10196                 namelist+=" lfsck_namespace"
10197         for name in $namelist; do
10198                 # Try to copy xattr from $file0 to $file1.
10199                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10200
10201                 setfattr --name=trusted.$name --value="$value" $file1 ||
10202                         error "setxattr 'trusted.$name' failed"
10203
10204                 # Try to set a garbage xattr.
10205                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10206
10207                 if [[ x$name == "xlov" ]]; then
10208                         setfattr --name=trusted.lov --value="$value" $file1 &&
10209                         error "setxattr invalid 'trusted.lov' success"
10210                 else
10211                         setfattr --name=trusted.$name --value="$value" $file1 ||
10212                                 error "setxattr invalid 'trusted.$name' failed"
10213                 fi
10214
10215                 # Try to remove the xattr from $file1. We don't care if this
10216                 # appears to succeed or fail, we just don't want there to be
10217                 # any changes or crashes.
10218                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10219         done
10220
10221         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10222         then
10223                 name="lfsck_ns"
10224                 # Try to copy xattr from $file0 to $file1.
10225                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10226
10227                 setfattr --name=trusted.$name --value="$value" $file1 ||
10228                         error "setxattr 'trusted.$name' failed"
10229
10230                 # Try to set a garbage xattr.
10231                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10232
10233                 setfattr --name=trusted.$name --value="$value" $file1 ||
10234                         error "setxattr 'trusted.$name' failed"
10235
10236                 # Try to remove the xattr from $file1. We don't care if this
10237                 # appears to succeed or fail, we just don't want there to be
10238                 # any changes or crashes.
10239                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10240         fi
10241
10242         # Get 'after' xattrs of file1.
10243         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10244
10245         if ! diff $xattr0 $xattr1; then
10246                 error "before and after xattrs of '$file1' differ"
10247         fi
10248
10249         rm -rf $file0 $file1 $xattr0 $xattr1
10250
10251         return 0
10252 }
10253 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10254
10255 test_102p() { # LU-4703 setxattr did not check ownership
10256         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10257                 skip "MDS needs to be at least 2.5.56"
10258
10259         local testfile=$DIR/$tfile
10260
10261         touch $testfile
10262
10263         echo "setfacl as user..."
10264         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10265         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10266
10267         echo "setfattr as user..."
10268         setfacl -m "u:$RUNAS_ID:---" $testfile
10269         $RUNAS setfattr -x system.posix_acl_access $testfile
10270         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10271 }
10272 run_test 102p "check setxattr(2) correctly fails without permission"
10273
10274 test_102q() {
10275         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10276                 skip "MDS needs to be at least 2.6.92"
10277
10278         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10279 }
10280 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10281
10282 test_102r() {
10283         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10284                 skip "MDS needs to be at least 2.6.93"
10285
10286         touch $DIR/$tfile || error "touch"
10287         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10288         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10289         rm $DIR/$tfile || error "rm"
10290
10291         #normal directory
10292         mkdir -p $DIR/$tdir || error "mkdir"
10293         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10294         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10295         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10296                 error "$testfile error deleting user.author1"
10297         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10298                 grep "user.$(basename $tdir)" &&
10299                 error "$tdir did not delete user.$(basename $tdir)"
10300         rmdir $DIR/$tdir || error "rmdir"
10301
10302         #striped directory
10303         test_mkdir $DIR/$tdir
10304         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10305         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10306         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10307                 error "$testfile error deleting user.author1"
10308         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10309                 grep "user.$(basename $tdir)" &&
10310                 error "$tdir did not delete user.$(basename $tdir)"
10311         rmdir $DIR/$tdir || error "rm striped dir"
10312 }
10313 run_test 102r "set EAs with empty values"
10314
10315 test_102s() {
10316         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10317                 skip "MDS needs to be at least 2.11.52"
10318
10319         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10320
10321         save_lustre_params client "llite.*.xattr_cache" > $save
10322
10323         for cache in 0 1; do
10324                 lctl set_param llite.*.xattr_cache=$cache
10325
10326                 rm -f $DIR/$tfile
10327                 touch $DIR/$tfile || error "touch"
10328                 for prefix in lustre security system trusted user; do
10329                         # Note getxattr() may fail with 'Operation not
10330                         # supported' or 'No such attribute' depending
10331                         # on prefix and cache.
10332                         getfattr -n $prefix.n102s $DIR/$tfile &&
10333                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10334                 done
10335         done
10336
10337         restore_lustre_params < $save
10338 }
10339 run_test 102s "getting nonexistent xattrs should fail"
10340
10341 test_102t() {
10342         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10343                 skip "MDS needs to be at least 2.11.52"
10344
10345         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10346
10347         save_lustre_params client "llite.*.xattr_cache" > $save
10348
10349         for cache in 0 1; do
10350                 lctl set_param llite.*.xattr_cache=$cache
10351
10352                 for buf_size in 0 256; do
10353                         rm -f $DIR/$tfile
10354                         touch $DIR/$tfile || error "touch"
10355                         setfattr -n user.multiop $DIR/$tfile
10356                         $MULTIOP $DIR/$tfile oa$buf_size ||
10357                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10358                 done
10359         done
10360
10361         restore_lustre_params < $save
10362 }
10363 run_test 102t "zero length xattr values handled correctly"
10364
10365 run_acl_subtest()
10366 {
10367     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10368     return $?
10369 }
10370
10371 test_103a() {
10372         [ "$UID" != 0 ] && skip "must run as root"
10373         $GSS && skip_env "could not run under gss"
10374         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10375                 skip_env "must have acl enabled"
10376         [ -z "$(which setfacl 2>/dev/null)" ] &&
10377                 skip_env "could not find setfacl"
10378         remote_mds_nodsh && skip "remote MDS with nodsh"
10379
10380         gpasswd -a daemon bin                           # LU-5641
10381         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10382
10383         declare -a identity_old
10384
10385         for num in $(seq $MDSCOUNT); do
10386                 switch_identity $num true || identity_old[$num]=$?
10387         done
10388
10389         SAVE_UMASK=$(umask)
10390         umask 0022
10391         mkdir -p $DIR/$tdir
10392         cd $DIR/$tdir
10393
10394         echo "performing cp ..."
10395         run_acl_subtest cp || error "run_acl_subtest cp failed"
10396         echo "performing getfacl-noacl..."
10397         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10398         echo "performing misc..."
10399         run_acl_subtest misc || error  "misc test failed"
10400         echo "performing permissions..."
10401         run_acl_subtest permissions || error "permissions failed"
10402         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10403         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10404                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10405                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10406         then
10407                 echo "performing permissions xattr..."
10408                 run_acl_subtest permissions_xattr ||
10409                         error "permissions_xattr failed"
10410         fi
10411         echo "performing setfacl..."
10412         run_acl_subtest setfacl || error  "setfacl test failed"
10413
10414         # inheritance test got from HP
10415         echo "performing inheritance..."
10416         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10417         chmod +x make-tree || error "chmod +x failed"
10418         run_acl_subtest inheritance || error "inheritance test failed"
10419         rm -f make-tree
10420
10421         echo "LU-974 ignore umask when acl is enabled..."
10422         run_acl_subtest 974 || error "LU-974 umask test failed"
10423         if [ $MDSCOUNT -ge 2 ]; then
10424                 run_acl_subtest 974_remote ||
10425                         error "LU-974 umask test failed under remote dir"
10426         fi
10427
10428         echo "LU-2561 newly created file is same size as directory..."
10429         if [ "$mds1_FSTYPE" != "zfs" ]; then
10430                 run_acl_subtest 2561 || error "LU-2561 test failed"
10431         else
10432                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10433         fi
10434
10435         run_acl_subtest 4924 || error "LU-4924 test failed"
10436
10437         cd $SAVE_PWD
10438         umask $SAVE_UMASK
10439
10440         for num in $(seq $MDSCOUNT); do
10441                 if [ "${identity_old[$num]}" = 1 ]; then
10442                         switch_identity $num false || identity_old[$num]=$?
10443                 fi
10444         done
10445 }
10446 run_test 103a "acl test"
10447
10448 test_103b() {
10449         declare -a pids
10450         local U
10451
10452         for U in {0..511}; do
10453                 {
10454                 local O=$(printf "%04o" $U)
10455
10456                 umask $(printf "%04o" $((511 ^ $O)))
10457                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10458                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10459
10460                 (( $S == ($O & 0666) )) ||
10461                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10462
10463                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10464                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10465                 (( $S == ($O & 0666) )) ||
10466                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10467
10468                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10469                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10470                 (( $S == ($O & 0666) )) ||
10471                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10472                 rm -f $DIR/$tfile.[smp]$0
10473                 } &
10474                 local pid=$!
10475
10476                 # limit the concurrently running threads to 64. LU-11878
10477                 local idx=$((U % 64))
10478                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10479                 pids[idx]=$pid
10480         done
10481         wait
10482 }
10483 run_test 103b "umask lfs setstripe"
10484
10485 test_103c() {
10486         mkdir -p $DIR/$tdir
10487         cp -rp $DIR/$tdir $DIR/$tdir.bak
10488
10489         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10490                 error "$DIR/$tdir shouldn't contain default ACL"
10491         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10492                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10493         true
10494 }
10495 run_test 103c "'cp -rp' won't set empty acl"
10496
10497 test_104a() {
10498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10499
10500         touch $DIR/$tfile
10501         lfs df || error "lfs df failed"
10502         lfs df -ih || error "lfs df -ih failed"
10503         lfs df -h $DIR || error "lfs df -h $DIR failed"
10504         lfs df -i $DIR || error "lfs df -i $DIR failed"
10505         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10506         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10507
10508         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10509         lctl --device %$OSC deactivate
10510         lfs df || error "lfs df with deactivated OSC failed"
10511         lctl --device %$OSC activate
10512         # wait the osc back to normal
10513         wait_osc_import_ready client ost
10514
10515         lfs df || error "lfs df with reactivated OSC failed"
10516         rm -f $DIR/$tfile
10517 }
10518 run_test 104a "lfs df [-ih] [path] test ========================="
10519
10520 test_104b() {
10521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10522         [ $RUNAS_ID -eq $UID ] &&
10523                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10524
10525         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10526                         grep "Permission denied" | wc -l)))
10527         if [ $denied_cnt -ne 0 ]; then
10528                 error "lfs check servers test failed"
10529         fi
10530 }
10531 run_test 104b "$RUNAS lfs check servers test ===================="
10532
10533 test_105a() {
10534         # doesn't work on 2.4 kernels
10535         touch $DIR/$tfile
10536         if $(flock_is_enabled); then
10537                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10538         else
10539                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10540         fi
10541         rm -f $DIR/$tfile
10542 }
10543 run_test 105a "flock when mounted without -o flock test ========"
10544
10545 test_105b() {
10546         touch $DIR/$tfile
10547         if $(flock_is_enabled); then
10548                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10549         else
10550                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10551         fi
10552         rm -f $DIR/$tfile
10553 }
10554 run_test 105b "fcntl when mounted without -o flock test ========"
10555
10556 test_105c() {
10557         touch $DIR/$tfile
10558         if $(flock_is_enabled); then
10559                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10560         else
10561                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10562         fi
10563         rm -f $DIR/$tfile
10564 }
10565 run_test 105c "lockf when mounted without -o flock test"
10566
10567 test_105d() { # bug 15924
10568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10569
10570         test_mkdir $DIR/$tdir
10571         flock_is_enabled || skip_env "mount w/o flock enabled"
10572         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10573         $LCTL set_param fail_loc=0x80000315
10574         flocks_test 2 $DIR/$tdir
10575 }
10576 run_test 105d "flock race (should not freeze) ========"
10577
10578 test_105e() { # bug 22660 && 22040
10579         flock_is_enabled || skip_env "mount w/o flock enabled"
10580
10581         touch $DIR/$tfile
10582         flocks_test 3 $DIR/$tfile
10583 }
10584 run_test 105e "Two conflicting flocks from same process"
10585
10586 test_106() { #bug 10921
10587         test_mkdir $DIR/$tdir
10588         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10589         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10590 }
10591 run_test 106 "attempt exec of dir followed by chown of that dir"
10592
10593 test_107() {
10594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10595
10596         CDIR=`pwd`
10597         local file=core
10598
10599         cd $DIR
10600         rm -f $file
10601
10602         local save_pattern=$(sysctl -n kernel.core_pattern)
10603         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10604         sysctl -w kernel.core_pattern=$file
10605         sysctl -w kernel.core_uses_pid=0
10606
10607         ulimit -c unlimited
10608         sleep 60 &
10609         SLEEPPID=$!
10610
10611         sleep 1
10612
10613         kill -s 11 $SLEEPPID
10614         wait $SLEEPPID
10615         if [ -e $file ]; then
10616                 size=`stat -c%s $file`
10617                 [ $size -eq 0 ] && error "Fail to create core file $file"
10618         else
10619                 error "Fail to create core file $file"
10620         fi
10621         rm -f $file
10622         sysctl -w kernel.core_pattern=$save_pattern
10623         sysctl -w kernel.core_uses_pid=$save_uses_pid
10624         cd $CDIR
10625 }
10626 run_test 107 "Coredump on SIG"
10627
10628 test_110() {
10629         test_mkdir $DIR/$tdir
10630         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10631         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10632                 error "mkdir with 256 char should fail, but did not"
10633         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10634                 error "create with 255 char failed"
10635         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10636                 error "create with 256 char should fail, but did not"
10637
10638         ls -l $DIR/$tdir
10639         rm -rf $DIR/$tdir
10640 }
10641 run_test 110 "filename length checking"
10642
10643 #
10644 # Purpose: To verify dynamic thread (OSS) creation.
10645 #
10646 test_115() {
10647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10648         remote_ost_nodsh && skip "remote OST with nodsh"
10649
10650         # Lustre does not stop service threads once they are started.
10651         # Reset number of running threads to default.
10652         stopall
10653         setupall
10654
10655         local OSTIO_pre
10656         local save_params="$TMP/sanity-$TESTNAME.parameters"
10657
10658         # Get ll_ost_io count before I/O
10659         OSTIO_pre=$(do_facet ost1 \
10660                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10661         # Exit if lustre is not running (ll_ost_io not running).
10662         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10663
10664         echo "Starting with $OSTIO_pre threads"
10665         local thread_max=$((OSTIO_pre * 2))
10666         local rpc_in_flight=$((thread_max * 2))
10667         # Number of I/O Process proposed to be started.
10668         local nfiles
10669         local facets=$(get_facets OST)
10670
10671         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10672         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10673
10674         # Set in_flight to $rpc_in_flight
10675         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10676                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10677         nfiles=${rpc_in_flight}
10678         # Set ost thread_max to $thread_max
10679         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10680
10681         # 5 Minutes should be sufficient for max number of OSS
10682         # threads(thread_max) to be created.
10683         local timeout=300
10684
10685         # Start I/O.
10686         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10687         test_mkdir $DIR/$tdir
10688         for i in $(seq $nfiles); do
10689                 local file=$DIR/$tdir/${tfile}-$i
10690                 $LFS setstripe -c -1 -i 0 $file
10691                 ($WTL $file $timeout)&
10692         done
10693
10694         # I/O Started - Wait for thread_started to reach thread_max or report
10695         # error if thread_started is more than thread_max.
10696         echo "Waiting for thread_started to reach thread_max"
10697         local thread_started=0
10698         local end_time=$((SECONDS + timeout))
10699
10700         while [ $SECONDS -le $end_time ] ; do
10701                 echo -n "."
10702                 # Get ost i/o thread_started count.
10703                 thread_started=$(do_facet ost1 \
10704                         "$LCTL get_param \
10705                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10706                 # Break out if thread_started is equal/greater than thread_max
10707                 if [[ $thread_started -ge $thread_max ]]; then
10708                         echo ll_ost_io thread_started $thread_started, \
10709                                 equal/greater than thread_max $thread_max
10710                         break
10711                 fi
10712                 sleep 1
10713         done
10714
10715         # Cleanup - We have the numbers, Kill i/o jobs if running.
10716         jobcount=($(jobs -p))
10717         for i in $(seq 0 $((${#jobcount[@]}-1)))
10718         do
10719                 kill -9 ${jobcount[$i]}
10720                 if [ $? -ne 0 ] ; then
10721                         echo Warning: \
10722                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10723                 fi
10724         done
10725
10726         # Cleanup files left by WTL binary.
10727         for i in $(seq $nfiles); do
10728                 local file=$DIR/$tdir/${tfile}-$i
10729                 rm -rf $file
10730                 if [ $? -ne 0 ] ; then
10731                         echo "Warning: Failed to delete file $file"
10732                 fi
10733         done
10734
10735         restore_lustre_params <$save_params
10736         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10737
10738         # Error out if no new thread has started or Thread started is greater
10739         # than thread max.
10740         if [[ $thread_started -le $OSTIO_pre ||
10741                         $thread_started -gt $thread_max ]]; then
10742                 error "ll_ost_io: thread_started $thread_started" \
10743                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10744                       "No new thread started or thread started greater " \
10745                       "than thread_max."
10746         fi
10747 }
10748 run_test 115 "verify dynamic thread creation===================="
10749
10750 free_min_max () {
10751         wait_delete_completed
10752         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10753         echo "OST kbytes available: ${AVAIL[@]}"
10754         MAXV=${AVAIL[0]}
10755         MAXI=0
10756         MINV=${AVAIL[0]}
10757         MINI=0
10758         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10759                 #echo OST $i: ${AVAIL[i]}kb
10760                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10761                         MAXV=${AVAIL[i]}
10762                         MAXI=$i
10763                 fi
10764                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10765                         MINV=${AVAIL[i]}
10766                         MINI=$i
10767                 fi
10768         done
10769         echo "Min free space: OST $MINI: $MINV"
10770         echo "Max free space: OST $MAXI: $MAXV"
10771 }
10772
10773 test_116a() { # was previously test_116()
10774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10775         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10776         remote_mds_nodsh && skip "remote MDS with nodsh"
10777
10778         echo -n "Free space priority "
10779         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10780                 head -n1
10781         declare -a AVAIL
10782         free_min_max
10783
10784         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10785         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10786         trap simple_cleanup_common EXIT
10787
10788         # Check if we need to generate uneven OSTs
10789         test_mkdir -p $DIR/$tdir/OST${MINI}
10790         local FILL=$((MINV / 4))
10791         local DIFF=$((MAXV - MINV))
10792         local DIFF2=$((DIFF * 100 / MINV))
10793
10794         local threshold=$(do_facet $SINGLEMDS \
10795                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10796         threshold=${threshold%%%}
10797         echo -n "Check for uneven OSTs: "
10798         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10799
10800         if [[ $DIFF2 -gt $threshold ]]; then
10801                 echo "ok"
10802                 echo "Don't need to fill OST$MINI"
10803         else
10804                 # generate uneven OSTs. Write 2% over the QOS threshold value
10805                 echo "no"
10806                 DIFF=$((threshold - DIFF2 + 2))
10807                 DIFF2=$((MINV * DIFF / 100))
10808                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10809                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10810                         error "setstripe failed"
10811                 DIFF=$((DIFF2 / 2048))
10812                 i=0
10813                 while [ $i -lt $DIFF ]; do
10814                         i=$((i + 1))
10815                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10816                                 bs=2M count=1 2>/dev/null
10817                         echo -n .
10818                 done
10819                 echo .
10820                 sync
10821                 sleep_maxage
10822                 free_min_max
10823         fi
10824
10825         DIFF=$((MAXV - MINV))
10826         DIFF2=$((DIFF * 100 / MINV))
10827         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10828         if [ $DIFF2 -gt $threshold ]; then
10829                 echo "ok"
10830         else
10831                 echo "failed - QOS mode won't be used"
10832                 simple_cleanup_common
10833                 skip "QOS imbalance criteria not met"
10834         fi
10835
10836         MINI1=$MINI
10837         MINV1=$MINV
10838         MAXI1=$MAXI
10839         MAXV1=$MAXV
10840
10841         # now fill using QOS
10842         $LFS setstripe -c 1 $DIR/$tdir
10843         FILL=$((FILL / 200))
10844         if [ $FILL -gt 600 ]; then
10845                 FILL=600
10846         fi
10847         echo "writing $FILL files to QOS-assigned OSTs"
10848         i=0
10849         while [ $i -lt $FILL ]; do
10850                 i=$((i + 1))
10851                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10852                         count=1 2>/dev/null
10853                 echo -n .
10854         done
10855         echo "wrote $i 200k files"
10856         sync
10857         sleep_maxage
10858
10859         echo "Note: free space may not be updated, so measurements might be off"
10860         free_min_max
10861         DIFF2=$((MAXV - MINV))
10862         echo "free space delta: orig $DIFF final $DIFF2"
10863         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10864         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10865         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10866         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10867         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10868         if [[ $DIFF -gt 0 ]]; then
10869                 FILL=$((DIFF2 * 100 / DIFF - 100))
10870                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10871         fi
10872
10873         # Figure out which files were written where
10874         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10875                awk '/'$MINI1': / {print $2; exit}')
10876         echo $UUID
10877         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10878         echo "$MINC files created on smaller OST $MINI1"
10879         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10880                awk '/'$MAXI1': / {print $2; exit}')
10881         echo $UUID
10882         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10883         echo "$MAXC files created on larger OST $MAXI1"
10884         if [[ $MINC -gt 0 ]]; then
10885                 FILL=$((MAXC * 100 / MINC - 100))
10886                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10887         fi
10888         [[ $MAXC -gt $MINC ]] ||
10889                 error_ignore LU-9 "stripe QOS didn't balance free space"
10890         simple_cleanup_common
10891 }
10892 run_test 116a "stripe QOS: free space balance ==================="
10893
10894 test_116b() { # LU-2093
10895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10896         remote_mds_nodsh && skip "remote MDS with nodsh"
10897
10898 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10899         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10900                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10901         [ -z "$old_rr" ] && skip "no QOS"
10902         do_facet $SINGLEMDS lctl set_param \
10903                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10904         mkdir -p $DIR/$tdir
10905         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10906         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10907         do_facet $SINGLEMDS lctl set_param fail_loc=0
10908         rm -rf $DIR/$tdir
10909         do_facet $SINGLEMDS lctl set_param \
10910                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10911 }
10912 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10913
10914 test_117() # bug 10891
10915 {
10916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10917
10918         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10919         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10920         lctl set_param fail_loc=0x21e
10921         > $DIR/$tfile || error "truncate failed"
10922         lctl set_param fail_loc=0
10923         echo "Truncate succeeded."
10924         rm -f $DIR/$tfile
10925 }
10926 run_test 117 "verify osd extend =========="
10927
10928 NO_SLOW_RESENDCOUNT=4
10929 export OLD_RESENDCOUNT=""
10930 set_resend_count () {
10931         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10932         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10933         lctl set_param -n $PROC_RESENDCOUNT $1
10934         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10935 }
10936
10937 # for reduce test_118* time (b=14842)
10938 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10939
10940 # Reset async IO behavior after error case
10941 reset_async() {
10942         FILE=$DIR/reset_async
10943
10944         # Ensure all OSCs are cleared
10945         $LFS setstripe -c -1 $FILE
10946         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10947         sync
10948         rm $FILE
10949 }
10950
10951 test_118a() #bug 11710
10952 {
10953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10954
10955         reset_async
10956
10957         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10958         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10959         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10960
10961         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10962                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10963                 return 1;
10964         fi
10965         rm -f $DIR/$tfile
10966 }
10967 run_test 118a "verify O_SYNC works =========="
10968
10969 test_118b()
10970 {
10971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10972         remote_ost_nodsh && skip "remote OST with nodsh"
10973
10974         reset_async
10975
10976         #define OBD_FAIL_SRV_ENOENT 0x217
10977         set_nodes_failloc "$(osts_nodes)" 0x217
10978         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10979         RC=$?
10980         set_nodes_failloc "$(osts_nodes)" 0
10981         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10982         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10983                     grep -c writeback)
10984
10985         if [[ $RC -eq 0 ]]; then
10986                 error "Must return error due to dropped pages, rc=$RC"
10987                 return 1;
10988         fi
10989
10990         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10991                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10992                 return 1;
10993         fi
10994
10995         echo "Dirty pages not leaked on ENOENT"
10996
10997         # Due to the above error the OSC will issue all RPCs syncronously
10998         # until a subsequent RPC completes successfully without error.
10999         $MULTIOP $DIR/$tfile Ow4096yc
11000         rm -f $DIR/$tfile
11001
11002         return 0
11003 }
11004 run_test 118b "Reclaim dirty pages on fatal error =========="
11005
11006 test_118c()
11007 {
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009
11010         # for 118c, restore the original resend count, LU-1940
11011         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11012                                 set_resend_count $OLD_RESENDCOUNT
11013         remote_ost_nodsh && skip "remote OST with nodsh"
11014
11015         reset_async
11016
11017         #define OBD_FAIL_OST_EROFS               0x216
11018         set_nodes_failloc "$(osts_nodes)" 0x216
11019
11020         # multiop should block due to fsync until pages are written
11021         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11022         MULTIPID=$!
11023         sleep 1
11024
11025         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11026                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11027         fi
11028
11029         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11030                     grep -c writeback)
11031         if [[ $WRITEBACK -eq 0 ]]; then
11032                 error "No page in writeback, writeback=$WRITEBACK"
11033         fi
11034
11035         set_nodes_failloc "$(osts_nodes)" 0
11036         wait $MULTIPID
11037         RC=$?
11038         if [[ $RC -ne 0 ]]; then
11039                 error "Multiop fsync failed, rc=$RC"
11040         fi
11041
11042         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11043         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11044                     grep -c writeback)
11045         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11046                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11047         fi
11048
11049         rm -f $DIR/$tfile
11050         echo "Dirty pages flushed via fsync on EROFS"
11051         return 0
11052 }
11053 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11054
11055 # continue to use small resend count to reduce test_118* time (b=14842)
11056 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11057
11058 test_118d()
11059 {
11060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11061         remote_ost_nodsh && skip "remote OST with nodsh"
11062
11063         reset_async
11064
11065         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11066         set_nodes_failloc "$(osts_nodes)" 0x214
11067         # multiop should block due to fsync until pages are written
11068         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11069         MULTIPID=$!
11070         sleep 1
11071
11072         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11073                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11074         fi
11075
11076         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11077                     grep -c writeback)
11078         if [[ $WRITEBACK -eq 0 ]]; then
11079                 error "No page in writeback, writeback=$WRITEBACK"
11080         fi
11081
11082         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11083         set_nodes_failloc "$(osts_nodes)" 0
11084
11085         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11086         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11087                     grep -c writeback)
11088         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11089                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11090         fi
11091
11092         rm -f $DIR/$tfile
11093         echo "Dirty pages gaurenteed flushed via fsync"
11094         return 0
11095 }
11096 run_test 118d "Fsync validation inject a delay of the bulk =========="
11097
11098 test_118f() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100
11101         reset_async
11102
11103         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11104         lctl set_param fail_loc=0x8000040a
11105
11106         # Should simulate EINVAL error which is fatal
11107         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11108         RC=$?
11109         if [[ $RC -eq 0 ]]; then
11110                 error "Must return error due to dropped pages, rc=$RC"
11111         fi
11112
11113         lctl set_param fail_loc=0x0
11114
11115         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11116         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11117         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11118                     grep -c writeback)
11119         if [[ $LOCKED -ne 0 ]]; then
11120                 error "Locked pages remain in cache, locked=$LOCKED"
11121         fi
11122
11123         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11124                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11125         fi
11126
11127         rm -f $DIR/$tfile
11128         echo "No pages locked after fsync"
11129
11130         reset_async
11131         return 0
11132 }
11133 run_test 118f "Simulate unrecoverable OSC side error =========="
11134
11135 test_118g() {
11136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11137
11138         reset_async
11139
11140         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11141         lctl set_param fail_loc=0x406
11142
11143         # simulate local -ENOMEM
11144         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11145         RC=$?
11146
11147         lctl set_param fail_loc=0
11148         if [[ $RC -eq 0 ]]; then
11149                 error "Must return error due to dropped pages, rc=$RC"
11150         fi
11151
11152         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11153         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11154         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11155                         grep -c writeback)
11156         if [[ $LOCKED -ne 0 ]]; then
11157                 error "Locked pages remain in cache, locked=$LOCKED"
11158         fi
11159
11160         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11161                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11162         fi
11163
11164         rm -f $DIR/$tfile
11165         echo "No pages locked after fsync"
11166
11167         reset_async
11168         return 0
11169 }
11170 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11171
11172 test_118h() {
11173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11174         remote_ost_nodsh && skip "remote OST with nodsh"
11175
11176         reset_async
11177
11178         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11179         set_nodes_failloc "$(osts_nodes)" 0x20e
11180         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11181         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11182         RC=$?
11183
11184         set_nodes_failloc "$(osts_nodes)" 0
11185         if [[ $RC -eq 0 ]]; then
11186                 error "Must return error due to dropped pages, 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 |
11192                     grep -c writeback)
11193         if [[ $LOCKED -ne 0 ]]; then
11194                 error "Locked pages remain in cache, locked=$LOCKED"
11195         fi
11196
11197         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11198                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11199         fi
11200
11201         rm -f $DIR/$tfile
11202         echo "No pages locked after fsync"
11203
11204         return 0
11205 }
11206 run_test 118h "Verify timeout in handling recoverables errors  =========="
11207
11208 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11209
11210 test_118i() {
11211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11212         remote_ost_nodsh && skip "remote OST with nodsh"
11213
11214         reset_async
11215
11216         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11217         set_nodes_failloc "$(osts_nodes)" 0x20e
11218
11219         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11220         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11221         PID=$!
11222         sleep 5
11223         set_nodes_failloc "$(osts_nodes)" 0
11224
11225         wait $PID
11226         RC=$?
11227         if [[ $RC -ne 0 ]]; then
11228                 error "got error, but should be not, rc=$RC"
11229         fi
11230
11231         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11232         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11233         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11234         if [[ $LOCKED -ne 0 ]]; then
11235                 error "Locked pages remain in cache, locked=$LOCKED"
11236         fi
11237
11238         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11239                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11240         fi
11241
11242         rm -f $DIR/$tfile
11243         echo "No pages locked after fsync"
11244
11245         return 0
11246 }
11247 run_test 118i "Fix error before timeout in recoverable error  =========="
11248
11249 [ "$SLOW" = "no" ] && set_resend_count 4
11250
11251 test_118j() {
11252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11253         remote_ost_nodsh && skip "remote OST with nodsh"
11254
11255         reset_async
11256
11257         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11258         set_nodes_failloc "$(osts_nodes)" 0x220
11259
11260         # return -EIO from OST
11261         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11262         RC=$?
11263         set_nodes_failloc "$(osts_nodes)" 0x0
11264         if [[ $RC -eq 0 ]]; then
11265                 error "Must return error due to dropped pages, rc=$RC"
11266         fi
11267
11268         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11269         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11270         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11271         if [[ $LOCKED -ne 0 ]]; then
11272                 error "Locked pages remain in cache, locked=$LOCKED"
11273         fi
11274
11275         # in recoverable error on OST we want resend and stay until it finished
11276         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11277                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11278         fi
11279
11280         rm -f $DIR/$tfile
11281         echo "No pages locked after fsync"
11282
11283         return 0
11284 }
11285 run_test 118j "Simulate unrecoverable OST side error =========="
11286
11287 test_118k()
11288 {
11289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11290         remote_ost_nodsh && skip "remote OSTs with nodsh"
11291
11292         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11293         set_nodes_failloc "$(osts_nodes)" 0x20e
11294         test_mkdir $DIR/$tdir
11295
11296         for ((i=0;i<10;i++)); do
11297                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11298                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11299                 SLEEPPID=$!
11300                 sleep 0.500s
11301                 kill $SLEEPPID
11302                 wait $SLEEPPID
11303         done
11304
11305         set_nodes_failloc "$(osts_nodes)" 0
11306         rm -rf $DIR/$tdir
11307 }
11308 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11309
11310 test_118l() # LU-646
11311 {
11312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11313
11314         test_mkdir $DIR/$tdir
11315         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11316         rm -rf $DIR/$tdir
11317 }
11318 run_test 118l "fsync dir"
11319
11320 test_118m() # LU-3066
11321 {
11322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11323
11324         test_mkdir $DIR/$tdir
11325         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11326         rm -rf $DIR/$tdir
11327 }
11328 run_test 118m "fdatasync dir ========="
11329
11330 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11331
11332 test_118n()
11333 {
11334         local begin
11335         local end
11336
11337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11338         remote_ost_nodsh && skip "remote OSTs with nodsh"
11339
11340         # Sleep to avoid a cached response.
11341         #define OBD_STATFS_CACHE_SECONDS 1
11342         sleep 2
11343
11344         # Inject a 10 second delay in the OST_STATFS handler.
11345         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11346         set_nodes_failloc "$(osts_nodes)" 0x242
11347
11348         begin=$SECONDS
11349         stat --file-system $MOUNT > /dev/null
11350         end=$SECONDS
11351
11352         set_nodes_failloc "$(osts_nodes)" 0
11353
11354         if ((end - begin > 20)); then
11355             error "statfs took $((end - begin)) seconds, expected 10"
11356         fi
11357 }
11358 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11359
11360 test_119a() # bug 11737
11361 {
11362         BSIZE=$((512 * 1024))
11363         directio write $DIR/$tfile 0 1 $BSIZE
11364         # We ask to read two blocks, which is more than a file size.
11365         # directio will indicate an error when requested and actual
11366         # sizes aren't equeal (a normal situation in this case) and
11367         # print actual read amount.
11368         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11369         if [ "$NOB" != "$BSIZE" ]; then
11370                 error "read $NOB bytes instead of $BSIZE"
11371         fi
11372         rm -f $DIR/$tfile
11373 }
11374 run_test 119a "Short directIO read must return actual read amount"
11375
11376 test_119b() # bug 11737
11377 {
11378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11379
11380         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11382         sync
11383         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11384                 error "direct read failed"
11385         rm -f $DIR/$tfile
11386 }
11387 run_test 119b "Sparse directIO read must return actual read amount"
11388
11389 test_119c() # bug 13099
11390 {
11391         BSIZE=1048576
11392         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11393         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11394         rm -f $DIR/$tfile
11395 }
11396 run_test 119c "Testing for direct read hitting hole"
11397
11398 test_119d() # bug 15950
11399 {
11400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11401
11402         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11403         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11404         BSIZE=1048576
11405         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11406         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11407         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11408         lctl set_param fail_loc=0x40d
11409         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11410         pid_dio=$!
11411         sleep 1
11412         cat $DIR/$tfile > /dev/null &
11413         lctl set_param fail_loc=0
11414         pid_reads=$!
11415         wait $pid_dio
11416         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11417         sleep 2
11418         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11419         error "the read rpcs have not completed in 2s"
11420         rm -f $DIR/$tfile
11421         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11422 }
11423 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11424
11425 test_120a() {
11426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428         test_mkdir -i0 -c1 $DIR/$tdir
11429         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11430                 skip_env "no early lock cancel on server"
11431
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         cancel_lru_locks mdc
11435         # asynchronous object destroy at MDT could cause bl ast to client
11436         cancel_lru_locks osc
11437
11438         stat $DIR/$tdir > /dev/null
11439         can1=$(do_facet mds1 \
11440                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11441                awk '/ldlm_cancel/ {print $2}')
11442         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11443                awk '/ldlm_bl_callback/ {print $2}')
11444         test_mkdir -i0 -c1 $DIR/$tdir/d1
11445         can2=$(do_facet mds1 \
11446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11447                awk '/ldlm_cancel/ {print $2}')
11448         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11449                awk '/ldlm_bl_callback/ {print $2}')
11450         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11451         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11452         lru_resize_enable mdc
11453         lru_resize_enable osc
11454 }
11455 run_test 120a "Early Lock Cancel: mkdir test"
11456
11457 test_120b() {
11458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11459         remote_mds_nodsh && skip "remote MDS with nodsh"
11460         test_mkdir $DIR/$tdir
11461         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11462                 skip_env "no early lock cancel on server"
11463
11464         lru_resize_disable mdc
11465         lru_resize_disable osc
11466         cancel_lru_locks mdc
11467         stat $DIR/$tdir > /dev/null
11468         can1=$(do_facet $SINGLEMDS \
11469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11470                awk '/ldlm_cancel/ {print $2}')
11471         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11472                awk '/ldlm_bl_callback/ {print $2}')
11473         touch $DIR/$tdir/f1
11474         can2=$(do_facet $SINGLEMDS \
11475                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11476                awk '/ldlm_cancel/ {print $2}')
11477         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11478                awk '/ldlm_bl_callback/ {print $2}')
11479         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11480         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11481         lru_resize_enable mdc
11482         lru_resize_enable osc
11483 }
11484 run_test 120b "Early Lock Cancel: create test"
11485
11486 test_120c() {
11487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11488         remote_mds_nodsh && skip "remote MDS with nodsh"
11489         test_mkdir -i0 -c1 $DIR/$tdir
11490         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11491                 skip "no early lock cancel on server"
11492
11493         lru_resize_disable mdc
11494         lru_resize_disable osc
11495         test_mkdir -i0 -c1 $DIR/$tdir/d1
11496         test_mkdir -i0 -c1 $DIR/$tdir/d2
11497         touch $DIR/$tdir/d1/f1
11498         cancel_lru_locks mdc
11499         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11500         can1=$(do_facet mds1 \
11501                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11502                awk '/ldlm_cancel/ {print $2}')
11503         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11504                awk '/ldlm_bl_callback/ {print $2}')
11505         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11506         can2=$(do_facet mds1 \
11507                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11508                awk '/ldlm_cancel/ {print $2}')
11509         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11510                awk '/ldlm_bl_callback/ {print $2}')
11511         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11512         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11513         lru_resize_enable mdc
11514         lru_resize_enable osc
11515 }
11516 run_test 120c "Early Lock Cancel: link test"
11517
11518 test_120d() {
11519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11520         remote_mds_nodsh && skip "remote MDS with nodsh"
11521         test_mkdir -i0 -c1 $DIR/$tdir
11522         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11523                 skip_env "no early lock cancel on server"
11524
11525         lru_resize_disable mdc
11526         lru_resize_disable osc
11527         touch $DIR/$tdir
11528         cancel_lru_locks mdc
11529         stat $DIR/$tdir > /dev/null
11530         can1=$(do_facet mds1 \
11531                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11532                awk '/ldlm_cancel/ {print $2}')
11533         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11534                awk '/ldlm_bl_callback/ {print $2}')
11535         chmod a+x $DIR/$tdir
11536         can2=$(do_facet mds1 \
11537                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11538                awk '/ldlm_cancel/ {print $2}')
11539         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11540                awk '/ldlm_bl_callback/ {print $2}')
11541         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11542         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11543         lru_resize_enable mdc
11544         lru_resize_enable osc
11545 }
11546 run_test 120d "Early Lock Cancel: setattr test"
11547
11548 test_120e() {
11549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11550         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11551                 skip_env "no early lock cancel on server"
11552         remote_mds_nodsh && skip "remote MDS with nodsh"
11553
11554         local dlmtrace_set=false
11555
11556         test_mkdir -i0 -c1 $DIR/$tdir
11557         lru_resize_disable mdc
11558         lru_resize_disable osc
11559         ! $LCTL get_param debug | grep -q dlmtrace &&
11560                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11561         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11562         cancel_lru_locks mdc
11563         cancel_lru_locks osc
11564         dd if=$DIR/$tdir/f1 of=/dev/null
11565         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11566         # XXX client can not do early lock cancel of OST lock
11567         # during unlink (LU-4206), so cancel osc lock now.
11568         sleep 2
11569         cancel_lru_locks osc
11570         can1=$(do_facet mds1 \
11571                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11572                awk '/ldlm_cancel/ {print $2}')
11573         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11574                awk '/ldlm_bl_callback/ {print $2}')
11575         unlink $DIR/$tdir/f1
11576         sleep 5
11577         can2=$(do_facet mds1 \
11578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11579                awk '/ldlm_cancel/ {print $2}')
11580         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11581                awk '/ldlm_bl_callback/ {print $2}')
11582         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11583                 $LCTL dk $TMP/cancel.debug.txt
11584         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11585                 $LCTL dk $TMP/blocking.debug.txt
11586         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11587         lru_resize_enable mdc
11588         lru_resize_enable osc
11589 }
11590 run_test 120e "Early Lock Cancel: unlink test"
11591
11592 test_120f() {
11593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11594         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11595                 skip_env "no early lock cancel on server"
11596         remote_mds_nodsh && skip "remote MDS with nodsh"
11597
11598         test_mkdir -i0 -c1 $DIR/$tdir
11599         lru_resize_disable mdc
11600         lru_resize_disable osc
11601         test_mkdir -i0 -c1 $DIR/$tdir/d1
11602         test_mkdir -i0 -c1 $DIR/$tdir/d2
11603         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11604         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11605         cancel_lru_locks mdc
11606         cancel_lru_locks osc
11607         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11608         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11609         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11610         # XXX client can not do early lock cancel of OST lock
11611         # during rename (LU-4206), so cancel osc lock now.
11612         sleep 2
11613         cancel_lru_locks osc
11614         can1=$(do_facet mds1 \
11615                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11616                awk '/ldlm_cancel/ {print $2}')
11617         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11618                awk '/ldlm_bl_callback/ {print $2}')
11619         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11620         sleep 5
11621         can2=$(do_facet mds1 \
11622                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11623                awk '/ldlm_cancel/ {print $2}')
11624         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11625                awk '/ldlm_bl_callback/ {print $2}')
11626         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11627         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11628         lru_resize_enable mdc
11629         lru_resize_enable osc
11630 }
11631 run_test 120f "Early Lock Cancel: rename test"
11632
11633 test_120g() {
11634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11635         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11636                 skip_env "no early lock cancel on server"
11637         remote_mds_nodsh && skip "remote MDS with nodsh"
11638
11639         lru_resize_disable mdc
11640         lru_resize_disable osc
11641         count=10000
11642         echo create $count files
11643         test_mkdir $DIR/$tdir
11644         cancel_lru_locks mdc
11645         cancel_lru_locks osc
11646         t0=$(date +%s)
11647
11648         can0=$(do_facet $SINGLEMDS \
11649                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11650                awk '/ldlm_cancel/ {print $2}')
11651         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11652                awk '/ldlm_bl_callback/ {print $2}')
11653         createmany -o $DIR/$tdir/f $count
11654         sync
11655         can1=$(do_facet $SINGLEMDS \
11656                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11657                awk '/ldlm_cancel/ {print $2}')
11658         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11659                awk '/ldlm_bl_callback/ {print $2}')
11660         t1=$(date +%s)
11661         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11662         echo rm $count files
11663         rm -r $DIR/$tdir
11664         sync
11665         can2=$(do_facet $SINGLEMDS \
11666                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11667                awk '/ldlm_cancel/ {print $2}')
11668         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11669                awk '/ldlm_bl_callback/ {print $2}')
11670         t2=$(date +%s)
11671         echo total: $count removes in $((t2-t1))
11672         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11673         sleep 2
11674         # wait for commitment of removal
11675         lru_resize_enable mdc
11676         lru_resize_enable osc
11677 }
11678 run_test 120g "Early Lock Cancel: performance test"
11679
11680 test_121() { #bug #10589
11681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11682
11683         rm -rf $DIR/$tfile
11684         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11685 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11686         lctl set_param fail_loc=0x310
11687         cancel_lru_locks osc > /dev/null
11688         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11689         lctl set_param fail_loc=0
11690         [[ $reads -eq $writes ]] ||
11691                 error "read $reads blocks, must be $writes blocks"
11692 }
11693 run_test 121 "read cancel race ========="
11694
11695 test_123a_base() { # was test 123, statahead(bug 11401)
11696         local lsx="$1"
11697
11698         SLOWOK=0
11699         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11700                 log "testing UP system. Performance may be lower than expected."
11701                 SLOWOK=1
11702         fi
11703
11704         rm -rf $DIR/$tdir
11705         test_mkdir $DIR/$tdir
11706         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11707         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11708         MULT=10
11709         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11710                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11711
11712                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11713                 lctl set_param -n llite.*.statahead_max 0
11714                 lctl get_param llite.*.statahead_max
11715                 cancel_lru_locks mdc
11716                 cancel_lru_locks osc
11717                 stime=$(date +%s)
11718                 time $lsx $DIR/$tdir | wc -l
11719                 etime=$(date +%s)
11720                 delta=$((etime - stime))
11721                 log "$lsx $i files without statahead: $delta sec"
11722                 lctl set_param llite.*.statahead_max=$max
11723
11724                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11725                         grep "statahead wrong:" | awk '{print $3}')
11726                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11727                 cancel_lru_locks mdc
11728                 cancel_lru_locks osc
11729                 stime=$(date +%s)
11730                 time $lsx $DIR/$tdir | wc -l
11731                 etime=$(date +%s)
11732                 delta_sa=$((etime - stime))
11733                 log "$lsx $i files with statahead: $delta_sa sec"
11734                 lctl get_param -n llite.*.statahead_stats
11735                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11736                         grep "statahead wrong:" | awk '{print $3}')
11737
11738                 [[ $swrong -lt $ewrong ]] &&
11739                         log "statahead was stopped, maybe too many locks held!"
11740                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11741
11742                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11743                         max=$(lctl get_param -n llite.*.statahead_max |
11744                                 head -n 1)
11745                         lctl set_param -n llite.*.statahead_max 0
11746                         lctl get_param llite.*.statahead_max
11747                         cancel_lru_locks mdc
11748                         cancel_lru_locks osc
11749                         stime=$(date +%s)
11750                         time $lsx $DIR/$tdir | wc -l
11751                         etime=$(date +%s)
11752                         delta=$((etime - stime))
11753                         log "$lsx $i files again without statahead: $delta sec"
11754                         lctl set_param llite.*.statahead_max=$max
11755                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11756                                 if [  $SLOWOK -eq 0 ]; then
11757                                         error "$lsx $i files is slower with statahead!"
11758                                 else
11759                                         log "$lsx $i files is slower with statahead!"
11760                                 fi
11761                                 break
11762                         fi
11763                 fi
11764
11765                 [ $delta -gt 20 ] && break
11766                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11767                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11768         done
11769         log "$lsx done"
11770
11771         stime=$(date +%s)
11772         rm -r $DIR/$tdir
11773         sync
11774         etime=$(date +%s)
11775         delta=$((etime - stime))
11776         log "rm -r $DIR/$tdir/: $delta seconds"
11777         log "rm done"
11778         lctl get_param -n llite.*.statahead_stats
11779 }
11780
11781 test_123aa() {
11782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11783
11784         test_123a_base "ls -l"
11785 }
11786 run_test 123aa "verify statahead work"
11787
11788 test_123ab() {
11789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11790
11791         statx_supported || skip_env "Test must be statx() syscall supported"
11792
11793         test_123a_base "$STATX -l"
11794 }
11795 run_test 123ab "verify statahead work by using statx"
11796
11797 test_123ac() {
11798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11799
11800         statx_supported || skip_env "Test must be statx() syscall supported"
11801
11802         local rpcs_before
11803         local rpcs_after
11804         local agl_before
11805         local agl_after
11806
11807         cancel_lru_locks $OSC
11808         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11809         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11810                 awk '/agl.total:/ {print $3}')
11811         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11812         test_123a_base "$STATX --cached=always -D"
11813         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11814                 awk '/agl.total:/ {print $3}')
11815         [ $agl_before -eq $agl_after ] ||
11816                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11817         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11818         [ $rpcs_after -eq $rpcs_before ] ||
11819                 error "$STATX should not send glimpse RPCs to $OSC"
11820 }
11821 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11822
11823 test_123b () { # statahead(bug 15027)
11824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11825
11826         test_mkdir $DIR/$tdir
11827         createmany -o $DIR/$tdir/$tfile-%d 1000
11828
11829         cancel_lru_locks mdc
11830         cancel_lru_locks osc
11831
11832 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11833         lctl set_param fail_loc=0x80000803
11834         ls -lR $DIR/$tdir > /dev/null
11835         log "ls done"
11836         lctl set_param fail_loc=0x0
11837         lctl get_param -n llite.*.statahead_stats
11838         rm -r $DIR/$tdir
11839         sync
11840
11841 }
11842 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11843
11844 test_123c() {
11845         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11846
11847         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11848         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11849         touch $DIR/$tdir.1/{1..3}
11850         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11851
11852         remount_client $MOUNT
11853
11854         $MULTIOP $DIR/$tdir.0 Q
11855
11856         # let statahead to complete
11857         ls -l $DIR/$tdir.0 > /dev/null
11858
11859         testid=$(echo $TESTNAME | tr '_' ' ')
11860         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11861                 error "statahead warning" || true
11862 }
11863 run_test 123c "Can not initialize inode warning on DNE statahead"
11864
11865 test_124a() {
11866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11867         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11868                 skip_env "no lru resize on server"
11869
11870         local NR=2000
11871
11872         test_mkdir $DIR/$tdir
11873
11874         log "create $NR files at $DIR/$tdir"
11875         createmany -o $DIR/$tdir/f $NR ||
11876                 error "failed to create $NR files in $DIR/$tdir"
11877
11878         cancel_lru_locks mdc
11879         ls -l $DIR/$tdir > /dev/null
11880
11881         local NSDIR=""
11882         local LRU_SIZE=0
11883         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11884                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11885                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11886                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11887                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11888                         log "NSDIR=$NSDIR"
11889                         log "NS=$(basename $NSDIR)"
11890                         break
11891                 fi
11892         done
11893
11894         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11895                 skip "Not enough cached locks created!"
11896         fi
11897         log "LRU=$LRU_SIZE"
11898
11899         local SLEEP=30
11900
11901         # We know that lru resize allows one client to hold $LIMIT locks
11902         # for 10h. After that locks begin to be killed by client.
11903         local MAX_HRS=10
11904         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11905         log "LIMIT=$LIMIT"
11906         if [ $LIMIT -lt $LRU_SIZE ]; then
11907                 skip "Limit is too small $LIMIT"
11908         fi
11909
11910         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11911         # killing locks. Some time was spent for creating locks. This means
11912         # that up to the moment of sleep finish we must have killed some of
11913         # them (10-100 locks). This depends on how fast ther were created.
11914         # Many of them were touched in almost the same moment and thus will
11915         # be killed in groups.
11916         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11917
11918         # Use $LRU_SIZE_B here to take into account real number of locks
11919         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11920         local LRU_SIZE_B=$LRU_SIZE
11921         log "LVF=$LVF"
11922         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11923         log "OLD_LVF=$OLD_LVF"
11924         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11925
11926         # Let's make sure that we really have some margin. Client checks
11927         # cached locks every 10 sec.
11928         SLEEP=$((SLEEP+20))
11929         log "Sleep ${SLEEP} sec"
11930         local SEC=0
11931         while ((SEC<$SLEEP)); do
11932                 echo -n "..."
11933                 sleep 5
11934                 SEC=$((SEC+5))
11935                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11936                 echo -n "$LRU_SIZE"
11937         done
11938         echo ""
11939         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11940         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11941
11942         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11943                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11944                 unlinkmany $DIR/$tdir/f $NR
11945                 return
11946         }
11947
11948         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11949         log "unlink $NR files at $DIR/$tdir"
11950         unlinkmany $DIR/$tdir/f $NR
11951 }
11952 run_test 124a "lru resize ======================================="
11953
11954 get_max_pool_limit()
11955 {
11956         local limit=$($LCTL get_param \
11957                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11958         local max=0
11959         for l in $limit; do
11960                 if [[ $l -gt $max ]]; then
11961                         max=$l
11962                 fi
11963         done
11964         echo $max
11965 }
11966
11967 test_124b() {
11968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11969         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11970                 skip_env "no lru resize on server"
11971
11972         LIMIT=$(get_max_pool_limit)
11973
11974         NR=$(($(default_lru_size)*20))
11975         if [[ $NR -gt $LIMIT ]]; then
11976                 log "Limit lock number by $LIMIT locks"
11977                 NR=$LIMIT
11978         fi
11979
11980         IFree=$(mdsrate_inodes_available)
11981         if [ $IFree -lt $NR ]; then
11982                 log "Limit lock number by $IFree inodes"
11983                 NR=$IFree
11984         fi
11985
11986         lru_resize_disable mdc
11987         test_mkdir -p $DIR/$tdir/disable_lru_resize
11988
11989         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11990         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11991         cancel_lru_locks mdc
11992         stime=`date +%s`
11993         PID=""
11994         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11995         PID="$PID $!"
11996         sleep 2
11997         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11998         PID="$PID $!"
11999         sleep 2
12000         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12001         PID="$PID $!"
12002         wait $PID
12003         etime=`date +%s`
12004         nolruresize_delta=$((etime-stime))
12005         log "ls -la time: $nolruresize_delta seconds"
12006         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12007         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12008
12009         lru_resize_enable mdc
12010         test_mkdir -p $DIR/$tdir/enable_lru_resize
12011
12012         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12013         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12014         cancel_lru_locks mdc
12015         stime=`date +%s`
12016         PID=""
12017         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12018         PID="$PID $!"
12019         sleep 2
12020         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12021         PID="$PID $!"
12022         sleep 2
12023         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12024         PID="$PID $!"
12025         wait $PID
12026         etime=`date +%s`
12027         lruresize_delta=$((etime-stime))
12028         log "ls -la time: $lruresize_delta seconds"
12029         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12030
12031         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12032                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12033         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12034                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12035         else
12036                 log "lru resize performs the same with no lru resize"
12037         fi
12038         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12039 }
12040 run_test 124b "lru resize (performance test) ======================="
12041
12042 test_124c() {
12043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12044         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12045                 skip_env "no lru resize on server"
12046
12047         # cache ununsed locks on client
12048         local nr=100
12049         cancel_lru_locks mdc
12050         test_mkdir $DIR/$tdir
12051         createmany -o $DIR/$tdir/f $nr ||
12052                 error "failed to create $nr files in $DIR/$tdir"
12053         ls -l $DIR/$tdir > /dev/null
12054
12055         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12056         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12057         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12058         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12059         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12060
12061         # set lru_max_age to 1 sec
12062         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12063         echo "sleep $((recalc_p * 2)) seconds..."
12064         sleep $((recalc_p * 2))
12065
12066         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12067         # restore lru_max_age
12068         $LCTL set_param -n $nsdir.lru_max_age $max_age
12069         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12070         unlinkmany $DIR/$tdir/f $nr
12071 }
12072 run_test 124c "LRUR cancel very aged locks"
12073
12074 test_124d() {
12075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12076         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12077                 skip_env "no lru resize on server"
12078
12079         # cache ununsed locks on client
12080         local nr=100
12081
12082         lru_resize_disable mdc
12083         stack_trap "lru_resize_enable mdc" EXIT
12084
12085         cancel_lru_locks mdc
12086
12087         # asynchronous object destroy at MDT could cause bl ast to client
12088         test_mkdir $DIR/$tdir
12089         createmany -o $DIR/$tdir/f $nr ||
12090                 error "failed to create $nr files in $DIR/$tdir"
12091         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12092
12093         ls -l $DIR/$tdir > /dev/null
12094
12095         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12096         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12097         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12098         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12099
12100         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12101
12102         # set lru_max_age to 1 sec
12103         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12104         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12105
12106         echo "sleep $((recalc_p * 2)) seconds..."
12107         sleep $((recalc_p * 2))
12108
12109         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12110
12111         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12112 }
12113 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12114
12115 test_125() { # 13358
12116         $LCTL get_param -n llite.*.client_type | grep -q local ||
12117                 skip "must run as local client"
12118         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12119                 skip_env "must have acl enabled"
12120         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12121
12122         test_mkdir $DIR/$tdir
12123         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12124         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12125         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12126 }
12127 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12128
12129 test_126() { # bug 12829/13455
12130         $GSS && skip_env "must run as gss disabled"
12131         $LCTL get_param -n llite.*.client_type | grep -q local ||
12132                 skip "must run as local client"
12133         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12134
12135         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12136         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12137         rm -f $DIR/$tfile
12138         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12139 }
12140 run_test 126 "check that the fsgid provided by the client is taken into account"
12141
12142 test_127a() { # bug 15521
12143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12144         local name count samp unit min max sum sumsq
12145
12146         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12147         echo "stats before reset"
12148         $LCTL get_param osc.*.stats
12149         $LCTL set_param osc.*.stats=0
12150         local fsize=$((2048 * 1024))
12151
12152         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12153         cancel_lru_locks osc
12154         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12155
12156         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12157         stack_trap "rm -f $TMP/$tfile.tmp"
12158         while read name count samp unit min max sum sumsq; do
12159                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12160                 [ ! $min ] && error "Missing min value for $name proc entry"
12161                 eval $name=$count || error "Wrong proc format"
12162
12163                 case $name in
12164                 read_bytes|write_bytes)
12165                         [[ "$unit" =~ "bytes" ]] ||
12166                                 error "unit is not 'bytes': $unit"
12167                         (( $min >= 4096 )) || error "min is too small: $min"
12168                         (( $min <= $fsize )) || error "min is too big: $min"
12169                         (( $max >= 4096 )) || error "max is too small: $max"
12170                         (( $max <= $fsize )) || error "max is too big: $max"
12171                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12172                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12173                                 error "sumsquare is too small: $sumsq"
12174                         (( $sumsq <= $fsize * $fsize )) ||
12175                                 error "sumsquare is too big: $sumsq"
12176                         ;;
12177                 ost_read|ost_write)
12178                         [[ "$unit" =~ "usec" ]] ||
12179                                 error "unit is not 'usec': $unit"
12180                         ;;
12181                 *)      ;;
12182                 esac
12183         done < $DIR/$tfile.tmp
12184
12185         #check that we actually got some stats
12186         [ "$read_bytes" ] || error "Missing read_bytes stats"
12187         [ "$write_bytes" ] || error "Missing write_bytes stats"
12188         [ "$read_bytes" != 0 ] || error "no read done"
12189         [ "$write_bytes" != 0 ] || error "no write done"
12190 }
12191 run_test 127a "verify the client stats are sane"
12192
12193 test_127b() { # bug LU-333
12194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12195         local name count samp unit min max sum sumsq
12196
12197         echo "stats before reset"
12198         $LCTL get_param llite.*.stats
12199         $LCTL set_param llite.*.stats=0
12200
12201         # perform 2 reads and writes so MAX is different from SUM.
12202         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12203         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12204         cancel_lru_locks osc
12205         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12206         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12207
12208         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12209         stack_trap "rm -f $TMP/$tfile.tmp"
12210         while read name count samp unit min max sum sumsq; do
12211                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12212                 eval $name=$count || error "Wrong proc format"
12213
12214                 case $name in
12215                 read_bytes|write_bytes)
12216                         [[ "$unit" =~ "bytes" ]] ||
12217                                 error "unit is not 'bytes': $unit"
12218                         (( $count == 2 )) || error "count is not 2: $count"
12219                         (( $min == $PAGE_SIZE )) ||
12220                                 error "min is not $PAGE_SIZE: $min"
12221                         (( $max == $PAGE_SIZE )) ||
12222                                 error "max is not $PAGE_SIZE: $max"
12223                         (( $sum == $PAGE_SIZE * 2 )) ||
12224                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12225                         ;;
12226                 read|write)
12227                         [[ "$unit" =~ "usec" ]] ||
12228                                 error "unit is not 'usec': $unit"
12229                         ;;
12230                 *)      ;;
12231                 esac
12232         done < $TMP/$tfile.tmp
12233
12234         #check that we actually got some stats
12235         [ "$read_bytes" ] || error "Missing read_bytes stats"
12236         [ "$write_bytes" ] || error "Missing write_bytes stats"
12237         [ "$read_bytes" != 0 ] || error "no read done"
12238         [ "$write_bytes" != 0 ] || error "no write done"
12239 }
12240 run_test 127b "verify the llite client stats are sane"
12241
12242 test_127c() { # LU-12394
12243         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12244         local size
12245         local bsize
12246         local reads
12247         local writes
12248         local count
12249
12250         $LCTL set_param llite.*.extents_stats=1
12251         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12252
12253         # Use two stripes so there is enough space in default config
12254         $LFS setstripe -c 2 $DIR/$tfile
12255
12256         # Extent stats start at 0-4K and go in power of two buckets
12257         # LL_HIST_START = 12 --> 2^12 = 4K
12258         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12259         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12260         # small configs
12261         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12262                 do
12263                 # Write and read, 2x each, second time at a non-zero offset
12264                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12265                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12266                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12267                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12268                 rm -f $DIR/$tfile
12269         done
12270
12271         $LCTL get_param llite.*.extents_stats
12272
12273         count=2
12274         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12275                 do
12276                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12277                                 grep -m 1 $bsize)
12278                 reads=$(echo $bucket | awk '{print $5}')
12279                 writes=$(echo $bucket | awk '{print $9}')
12280                 [ "$reads" -eq $count ] ||
12281                         error "$reads reads in < $bsize bucket, expect $count"
12282                 [ "$writes" -eq $count ] ||
12283                         error "$writes writes in < $bsize bucket, expect $count"
12284         done
12285
12286         # Test mmap write and read
12287         $LCTL set_param llite.*.extents_stats=c
12288         size=512
12289         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12290         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12291         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12292
12293         $LCTL get_param llite.*.extents_stats
12294
12295         count=$(((size*1024) / PAGE_SIZE))
12296
12297         bsize=$((2 * PAGE_SIZE / 1024))K
12298
12299         bucket=$($LCTL get_param -n llite.*.extents_stats |
12300                         grep -m 1 $bsize)
12301         reads=$(echo $bucket | awk '{print $5}')
12302         writes=$(echo $bucket | awk '{print $9}')
12303         # mmap writes fault in the page first, creating an additonal read
12304         [ "$reads" -eq $((2 * count)) ] ||
12305                 error "$reads reads in < $bsize bucket, expect $count"
12306         [ "$writes" -eq $count ] ||
12307                 error "$writes writes in < $bsize bucket, expect $count"
12308 }
12309 run_test 127c "test llite extent stats with regular & mmap i/o"
12310
12311 test_128() { # bug 15212
12312         touch $DIR/$tfile
12313         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12314                 find $DIR/$tfile
12315                 find $DIR/$tfile
12316         EOF
12317
12318         result=$(grep error $TMP/$tfile.log)
12319         rm -f $DIR/$tfile $TMP/$tfile.log
12320         [ -z "$result" ] ||
12321                 error "consecutive find's under interactive lfs failed"
12322 }
12323 run_test 128 "interactive lfs for 2 consecutive find's"
12324
12325 set_dir_limits () {
12326         local mntdev
12327         local canondev
12328         local node
12329
12330         local ldproc=/proc/fs/ldiskfs
12331         local facets=$(get_facets MDS)
12332
12333         for facet in ${facets//,/ }; do
12334                 canondev=$(ldiskfs_canon \
12335                            *.$(convert_facet2label $facet).mntdev $facet)
12336                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12337                         ldproc=/sys/fs/ldiskfs
12338                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12339                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12340         done
12341 }
12342
12343 check_mds_dmesg() {
12344         local facets=$(get_facets MDS)
12345         for facet in ${facets//,/ }; do
12346                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12347         done
12348         return 1
12349 }
12350
12351 test_129() {
12352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12353         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12354                 skip "Need MDS version with at least 2.5.56"
12355         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12356                 skip_env "ldiskfs only test"
12357         fi
12358         remote_mds_nodsh && skip "remote MDS with nodsh"
12359
12360         local ENOSPC=28
12361         local has_warning=false
12362
12363         rm -rf $DIR/$tdir
12364         mkdir -p $DIR/$tdir
12365
12366         # block size of mds1
12367         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12368         set_dir_limits $maxsize $((maxsize * 6 / 8))
12369         stack_trap "set_dir_limits 0 0"
12370         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12371         local dirsize=$(stat -c%s "$DIR/$tdir")
12372         local nfiles=0
12373         while (( $dirsize <= $maxsize )); do
12374                 $MCREATE $DIR/$tdir/file_base_$nfiles
12375                 rc=$?
12376                 # check two errors:
12377                 # ENOSPC for ext4 max_dir_size, which has been used since
12378                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12379                 if (( rc == ENOSPC )); then
12380                         set_dir_limits 0 0
12381                         echo "rc=$rc returned as expected after $nfiles files"
12382
12383                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12384                                 error "create failed w/o dir size limit"
12385
12386                         # messages may be rate limited if test is run repeatedly
12387                         check_mds_dmesg '"is approaching max"' ||
12388                                 echo "warning message should be output"
12389                         check_mds_dmesg '"has reached max"' ||
12390                                 echo "reached message should be output"
12391
12392                         dirsize=$(stat -c%s "$DIR/$tdir")
12393
12394                         [[ $dirsize -ge $maxsize ]] && return 0
12395                         error "dirsize $dirsize < $maxsize after $nfiles files"
12396                 elif (( rc != 0 )); then
12397                         break
12398                 fi
12399                 nfiles=$((nfiles + 1))
12400                 dirsize=$(stat -c%s "$DIR/$tdir")
12401         done
12402
12403         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12404 }
12405 run_test 129 "test directory size limit ========================"
12406
12407 OLDIFS="$IFS"
12408 cleanup_130() {
12409         trap 0
12410         IFS="$OLDIFS"
12411 }
12412
12413 test_130a() {
12414         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12415         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12416
12417         trap cleanup_130 EXIT RETURN
12418
12419         local fm_file=$DIR/$tfile
12420         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12421         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12422                 error "dd failed for $fm_file"
12423
12424         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12425         filefrag -ves $fm_file
12426         RC=$?
12427         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12428                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12429         [ $RC != 0 ] && error "filefrag $fm_file failed"
12430
12431         filefrag_op=$(filefrag -ve -k $fm_file |
12432                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12433         lun=$($LFS getstripe -i $fm_file)
12434
12435         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12436         IFS=$'\n'
12437         tot_len=0
12438         for line in $filefrag_op
12439         do
12440                 frag_lun=`echo $line | cut -d: -f5`
12441                 ext_len=`echo $line | cut -d: -f4`
12442                 if (( $frag_lun != $lun )); then
12443                         cleanup_130
12444                         error "FIEMAP on 1-stripe file($fm_file) failed"
12445                         return
12446                 fi
12447                 (( tot_len += ext_len ))
12448         done
12449
12450         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12451                 cleanup_130
12452                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12453                 return
12454         fi
12455
12456         cleanup_130
12457
12458         echo "FIEMAP on single striped file succeeded"
12459 }
12460 run_test 130a "FIEMAP (1-stripe file)"
12461
12462 test_130b() {
12463         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12464
12465         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12466         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12467
12468         trap cleanup_130 EXIT RETURN
12469
12470         local fm_file=$DIR/$tfile
12471         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12472                         error "setstripe on $fm_file"
12473         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12474                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12475
12476         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12477                 error "dd failed on $fm_file"
12478
12479         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12480         filefrag_op=$(filefrag -ve -k $fm_file |
12481                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12482
12483         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12484                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12485
12486         IFS=$'\n'
12487         tot_len=0
12488         num_luns=1
12489         for line in $filefrag_op
12490         do
12491                 frag_lun=$(echo $line | cut -d: -f5 |
12492                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12493                 ext_len=$(echo $line | cut -d: -f4)
12494                 if (( $frag_lun != $last_lun )); then
12495                         if (( tot_len != 1024 )); then
12496                                 cleanup_130
12497                                 error "FIEMAP on $fm_file failed; returned " \
12498                                 "len $tot_len for OST $last_lun instead of 1024"
12499                                 return
12500                         else
12501                                 (( num_luns += 1 ))
12502                                 tot_len=0
12503                         fi
12504                 fi
12505                 (( tot_len += ext_len ))
12506                 last_lun=$frag_lun
12507         done
12508         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12509                 cleanup_130
12510                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12511                         "luns or wrong len for OST $last_lun"
12512                 return
12513         fi
12514
12515         cleanup_130
12516
12517         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12518 }
12519 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12520
12521 test_130c() {
12522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12523
12524         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12525         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12526
12527         trap cleanup_130 EXIT RETURN
12528
12529         local fm_file=$DIR/$tfile
12530         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12531         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12532                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12533
12534         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12535                         error "dd failed on $fm_file"
12536
12537         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12538         filefrag_op=$(filefrag -ve -k $fm_file |
12539                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12540
12541         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12542                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12543
12544         IFS=$'\n'
12545         tot_len=0
12546         num_luns=1
12547         for line in $filefrag_op
12548         do
12549                 frag_lun=$(echo $line | cut -d: -f5 |
12550                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12551                 ext_len=$(echo $line | cut -d: -f4)
12552                 if (( $frag_lun != $last_lun )); then
12553                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12554                         if (( logical != 512 )); then
12555                                 cleanup_130
12556                                 error "FIEMAP on $fm_file failed; returned " \
12557                                 "logical start for lun $logical instead of 512"
12558                                 return
12559                         fi
12560                         if (( tot_len != 512 )); then
12561                                 cleanup_130
12562                                 error "FIEMAP on $fm_file failed; returned " \
12563                                 "len $tot_len for OST $last_lun instead of 1024"
12564                                 return
12565                         else
12566                                 (( num_luns += 1 ))
12567                                 tot_len=0
12568                         fi
12569                 fi
12570                 (( tot_len += ext_len ))
12571                 last_lun=$frag_lun
12572         done
12573         if (( num_luns != 2 || tot_len != 512 )); then
12574                 cleanup_130
12575                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12576                         "luns or wrong len for OST $last_lun"
12577                 return
12578         fi
12579
12580         cleanup_130
12581
12582         echo "FIEMAP on 2-stripe file with hole succeeded"
12583 }
12584 run_test 130c "FIEMAP (2-stripe file with hole)"
12585
12586 test_130d() {
12587         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12588
12589         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12590         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12591
12592         trap cleanup_130 EXIT RETURN
12593
12594         local fm_file=$DIR/$tfile
12595         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12596                         error "setstripe on $fm_file"
12597         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12598                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12599
12600         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12601         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12602                 error "dd failed on $fm_file"
12603
12604         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12605         filefrag_op=$(filefrag -ve -k $fm_file |
12606                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12607
12608         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12609                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12610
12611         IFS=$'\n'
12612         tot_len=0
12613         num_luns=1
12614         for line in $filefrag_op
12615         do
12616                 frag_lun=$(echo $line | cut -d: -f5 |
12617                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12618                 ext_len=$(echo $line | cut -d: -f4)
12619                 if (( $frag_lun != $last_lun )); then
12620                         if (( tot_len != 1024 )); then
12621                                 cleanup_130
12622                                 error "FIEMAP on $fm_file failed; returned " \
12623                                 "len $tot_len for OST $last_lun instead of 1024"
12624                                 return
12625                         else
12626                                 (( num_luns += 1 ))
12627                                 tot_len=0
12628                         fi
12629                 fi
12630                 (( tot_len += ext_len ))
12631                 last_lun=$frag_lun
12632         done
12633         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12634                 cleanup_130
12635                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12636                         "luns or wrong len for OST $last_lun"
12637                 return
12638         fi
12639
12640         cleanup_130
12641
12642         echo "FIEMAP on N-stripe file succeeded"
12643 }
12644 run_test 130d "FIEMAP (N-stripe file)"
12645
12646 test_130e() {
12647         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12648
12649         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12650         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12651
12652         trap cleanup_130 EXIT RETURN
12653
12654         local fm_file=$DIR/$tfile
12655         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12656         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12657                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12658
12659         NUM_BLKS=512
12660         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12661         for ((i = 0; i < $NUM_BLKS; i++))
12662         do
12663                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12664         done
12665
12666         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12667         filefrag_op=$(filefrag -ve -k $fm_file |
12668                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12669
12670         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12671                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12672
12673         IFS=$'\n'
12674         tot_len=0
12675         num_luns=1
12676         for line in $filefrag_op
12677         do
12678                 frag_lun=$(echo $line | cut -d: -f5 |
12679                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12680                 ext_len=$(echo $line | cut -d: -f4)
12681                 if (( $frag_lun != $last_lun )); then
12682                         if (( tot_len != $EXPECTED_LEN )); then
12683                                 cleanup_130
12684                                 error "FIEMAP on $fm_file failed; returned " \
12685                                 "len $tot_len for OST $last_lun instead " \
12686                                 "of $EXPECTED_LEN"
12687                                 return
12688                         else
12689                                 (( num_luns += 1 ))
12690                                 tot_len=0
12691                         fi
12692                 fi
12693                 (( tot_len += ext_len ))
12694                 last_lun=$frag_lun
12695         done
12696         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12697                 cleanup_130
12698                 error "FIEMAP on $fm_file failed; returned wrong number " \
12699                         "of luns or wrong len for OST $last_lun"
12700                 return
12701         fi
12702
12703         cleanup_130
12704
12705         echo "FIEMAP with continuation calls succeeded"
12706 }
12707 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12708
12709 test_130f() {
12710         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12711         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12712
12713         local fm_file=$DIR/$tfile
12714         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12715                 error "multiop create with lov_delay_create on $fm_file"
12716
12717         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12718         filefrag_extents=$(filefrag -vek $fm_file |
12719                            awk '/extents? found/ { print $2 }')
12720         if [[ "$filefrag_extents" != "0" ]]; then
12721                 error "FIEMAP on $fm_file failed; " \
12722                       "returned $filefrag_extents expected 0"
12723         fi
12724
12725         rm -f $fm_file
12726 }
12727 run_test 130f "FIEMAP (unstriped file)"
12728
12729 # Test for writev/readv
12730 test_131a() {
12731         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12732                 error "writev test failed"
12733         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12734                 error "readv failed"
12735         rm -f $DIR/$tfile
12736 }
12737 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12738
12739 test_131b() {
12740         local fsize=$((524288 + 1048576 + 1572864))
12741         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12742                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12743                         error "append writev test failed"
12744
12745         ((fsize += 1572864 + 1048576))
12746         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12747                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12748                         error "append writev test failed"
12749         rm -f $DIR/$tfile
12750 }
12751 run_test 131b "test append writev"
12752
12753 test_131c() {
12754         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12755         error "NOT PASS"
12756 }
12757 run_test 131c "test read/write on file w/o objects"
12758
12759 test_131d() {
12760         rwv -f $DIR/$tfile -w -n 1 1572864
12761         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12762         if [ "$NOB" != 1572864 ]; then
12763                 error "Short read filed: read $NOB bytes instead of 1572864"
12764         fi
12765         rm -f $DIR/$tfile
12766 }
12767 run_test 131d "test short read"
12768
12769 test_131e() {
12770         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12771         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12772         error "read hitting hole failed"
12773         rm -f $DIR/$tfile
12774 }
12775 run_test 131e "test read hitting hole"
12776
12777 check_stats() {
12778         local facet=$1
12779         local op=$2
12780         local want=${3:-0}
12781         local res
12782
12783         case $facet in
12784         mds*) res=$(do_facet $facet \
12785                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12786                  ;;
12787         ost*) res=$(do_facet $facet \
12788                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12789                  ;;
12790         *) error "Wrong facet '$facet'" ;;
12791         esac
12792         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12793         # if the argument $3 is zero, it means any stat increment is ok.
12794         if [[ $want -gt 0 ]]; then
12795                 local count=$(echo $res | awk '{ print $2 }')
12796                 [[ $count -ne $want ]] &&
12797                         error "The $op counter on $facet is $count, not $want"
12798         fi
12799 }
12800
12801 test_133a() {
12802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12803         remote_ost_nodsh && skip "remote OST with nodsh"
12804         remote_mds_nodsh && skip "remote MDS with nodsh"
12805         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12806                 skip_env "MDS doesn't support rename stats"
12807
12808         local testdir=$DIR/${tdir}/stats_testdir
12809
12810         mkdir -p $DIR/${tdir}
12811
12812         # clear stats.
12813         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12814         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12815
12816         # verify mdt stats first.
12817         mkdir ${testdir} || error "mkdir failed"
12818         check_stats $SINGLEMDS "mkdir" 1
12819         touch ${testdir}/${tfile} || error "touch failed"
12820         check_stats $SINGLEMDS "open" 1
12821         check_stats $SINGLEMDS "close" 1
12822         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12823                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12824                 check_stats $SINGLEMDS "mknod" 2
12825         }
12826         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12827         check_stats $SINGLEMDS "unlink" 1
12828         rm -f ${testdir}/${tfile} || error "file remove failed"
12829         check_stats $SINGLEMDS "unlink" 2
12830
12831         # remove working dir and check mdt stats again.
12832         rmdir ${testdir} || error "rmdir failed"
12833         check_stats $SINGLEMDS "rmdir" 1
12834
12835         local testdir1=$DIR/${tdir}/stats_testdir1
12836         mkdir -p ${testdir}
12837         mkdir -p ${testdir1}
12838         touch ${testdir1}/test1
12839         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12840         check_stats $SINGLEMDS "crossdir_rename" 1
12841
12842         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12843         check_stats $SINGLEMDS "samedir_rename" 1
12844
12845         rm -rf $DIR/${tdir}
12846 }
12847 run_test 133a "Verifying MDT stats ========================================"
12848
12849 test_133b() {
12850         local res
12851
12852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12853         remote_ost_nodsh && skip "remote OST with nodsh"
12854         remote_mds_nodsh && skip "remote MDS with nodsh"
12855
12856         local testdir=$DIR/${tdir}/stats_testdir
12857
12858         mkdir -p ${testdir} || error "mkdir failed"
12859         touch ${testdir}/${tfile} || error "touch failed"
12860         cancel_lru_locks mdc
12861
12862         # clear stats.
12863         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12864         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12865
12866         # extra mdt stats verification.
12867         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12868         check_stats $SINGLEMDS "setattr" 1
12869         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12870         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12871         then            # LU-1740
12872                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12873                 check_stats $SINGLEMDS "getattr" 1
12874         fi
12875         rm -rf $DIR/${tdir}
12876
12877         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12878         # so the check below is not reliable
12879         [ $MDSCOUNT -eq 1 ] || return 0
12880
12881         # Sleep to avoid a cached response.
12882         #define OBD_STATFS_CACHE_SECONDS 1
12883         sleep 2
12884         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12885         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12886         $LFS df || error "lfs failed"
12887         check_stats $SINGLEMDS "statfs" 1
12888
12889         # check aggregated statfs (LU-10018)
12890         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12891                 return 0
12892         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12893                 return 0
12894         sleep 2
12895         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12896         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12897         df $DIR
12898         check_stats $SINGLEMDS "statfs" 1
12899
12900         # We want to check that the client didn't send OST_STATFS to
12901         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12902         # extra care is needed here.
12903         if remote_mds; then
12904                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12905                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12906
12907                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12908                 [ "$res" ] && error "OST got STATFS"
12909         fi
12910
12911         return 0
12912 }
12913 run_test 133b "Verifying extra MDT stats =================================="
12914
12915 test_133c() {
12916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12917         remote_ost_nodsh && skip "remote OST with nodsh"
12918         remote_mds_nodsh && skip "remote MDS with nodsh"
12919
12920         local testdir=$DIR/$tdir/stats_testdir
12921
12922         test_mkdir -p $testdir
12923
12924         # verify obdfilter stats.
12925         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12926         sync
12927         cancel_lru_locks osc
12928         wait_delete_completed
12929
12930         # clear stats.
12931         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12932         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12933
12934         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12935                 error "dd failed"
12936         sync
12937         cancel_lru_locks osc
12938         check_stats ost1 "write" 1
12939
12940         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12941         check_stats ost1 "read" 1
12942
12943         > $testdir/$tfile || error "truncate failed"
12944         check_stats ost1 "punch" 1
12945
12946         rm -f $testdir/$tfile || error "file remove failed"
12947         wait_delete_completed
12948         check_stats ost1 "destroy" 1
12949
12950         rm -rf $DIR/$tdir
12951 }
12952 run_test 133c "Verifying OST stats ========================================"
12953
12954 order_2() {
12955         local value=$1
12956         local orig=$value
12957         local order=1
12958
12959         while [ $value -ge 2 ]; do
12960                 order=$((order*2))
12961                 value=$((value/2))
12962         done
12963
12964         if [ $orig -gt $order ]; then
12965                 order=$((order*2))
12966         fi
12967         echo $order
12968 }
12969
12970 size_in_KMGT() {
12971     local value=$1
12972     local size=('K' 'M' 'G' 'T');
12973     local i=0
12974     local size_string=$value
12975
12976     while [ $value -ge 1024 ]; do
12977         if [ $i -gt 3 ]; then
12978             #T is the biggest unit we get here, if that is bigger,
12979             #just return XXXT
12980             size_string=${value}T
12981             break
12982         fi
12983         value=$((value >> 10))
12984         if [ $value -lt 1024 ]; then
12985             size_string=${value}${size[$i]}
12986             break
12987         fi
12988         i=$((i + 1))
12989     done
12990
12991     echo $size_string
12992 }
12993
12994 get_rename_size() {
12995         local size=$1
12996         local context=${2:-.}
12997         local sample=$(do_facet $SINGLEMDS $LCTL \
12998                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12999                 grep -A1 $context |
13000                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13001         echo $sample
13002 }
13003
13004 test_133d() {
13005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13006         remote_ost_nodsh && skip "remote OST with nodsh"
13007         remote_mds_nodsh && skip "remote MDS with nodsh"
13008         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13009                 skip_env "MDS doesn't support rename stats"
13010
13011         local testdir1=$DIR/${tdir}/stats_testdir1
13012         local testdir2=$DIR/${tdir}/stats_testdir2
13013         mkdir -p $DIR/${tdir}
13014
13015         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13016
13017         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13018         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13019
13020         createmany -o $testdir1/test 512 || error "createmany failed"
13021
13022         # check samedir rename size
13023         mv ${testdir1}/test0 ${testdir1}/test_0
13024
13025         local testdir1_size=$(ls -l $DIR/${tdir} |
13026                 awk '/stats_testdir1/ {print $5}')
13027         local testdir2_size=$(ls -l $DIR/${tdir} |
13028                 awk '/stats_testdir2/ {print $5}')
13029
13030         testdir1_size=$(order_2 $testdir1_size)
13031         testdir2_size=$(order_2 $testdir2_size)
13032
13033         testdir1_size=$(size_in_KMGT $testdir1_size)
13034         testdir2_size=$(size_in_KMGT $testdir2_size)
13035
13036         echo "source rename dir size: ${testdir1_size}"
13037         echo "target rename dir size: ${testdir2_size}"
13038
13039         local cmd="do_facet $SINGLEMDS $LCTL "
13040         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13041
13042         eval $cmd || error "$cmd failed"
13043         local samedir=$($cmd | grep 'same_dir')
13044         local same_sample=$(get_rename_size $testdir1_size)
13045         [ -z "$samedir" ] && error "samedir_rename_size count error"
13046         [[ $same_sample -eq 1 ]] ||
13047                 error "samedir_rename_size error $same_sample"
13048         echo "Check same dir rename stats success"
13049
13050         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13051
13052         # check crossdir rename size
13053         mv ${testdir1}/test_0 ${testdir2}/test_0
13054
13055         testdir1_size=$(ls -l $DIR/${tdir} |
13056                 awk '/stats_testdir1/ {print $5}')
13057         testdir2_size=$(ls -l $DIR/${tdir} |
13058                 awk '/stats_testdir2/ {print $5}')
13059
13060         testdir1_size=$(order_2 $testdir1_size)
13061         testdir2_size=$(order_2 $testdir2_size)
13062
13063         testdir1_size=$(size_in_KMGT $testdir1_size)
13064         testdir2_size=$(size_in_KMGT $testdir2_size)
13065
13066         echo "source rename dir size: ${testdir1_size}"
13067         echo "target rename dir size: ${testdir2_size}"
13068
13069         eval $cmd || error "$cmd failed"
13070         local crossdir=$($cmd | grep 'crossdir')
13071         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13072         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13073         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13074         [[ $src_sample -eq 1 ]] ||
13075                 error "crossdir_rename_size error $src_sample"
13076         [[ $tgt_sample -eq 1 ]] ||
13077                 error "crossdir_rename_size error $tgt_sample"
13078         echo "Check cross dir rename stats success"
13079         rm -rf $DIR/${tdir}
13080 }
13081 run_test 133d "Verifying rename_stats ========================================"
13082
13083 test_133e() {
13084         remote_mds_nodsh && skip "remote MDS with nodsh"
13085         remote_ost_nodsh && skip "remote OST with nodsh"
13086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13087
13088         local testdir=$DIR/${tdir}/stats_testdir
13089         local ctr f0 f1 bs=32768 count=42 sum
13090
13091         mkdir -p ${testdir} || error "mkdir failed"
13092
13093         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13094
13095         for ctr in {write,read}_bytes; do
13096                 sync
13097                 cancel_lru_locks osc
13098
13099                 do_facet ost1 $LCTL set_param -n \
13100                         "obdfilter.*.exports.clear=clear"
13101
13102                 if [ $ctr = write_bytes ]; then
13103                         f0=/dev/zero
13104                         f1=${testdir}/${tfile}
13105                 else
13106                         f0=${testdir}/${tfile}
13107                         f1=/dev/null
13108                 fi
13109
13110                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13111                         error "dd failed"
13112                 sync
13113                 cancel_lru_locks osc
13114
13115                 sum=$(do_facet ost1 $LCTL get_param \
13116                         "obdfilter.*.exports.*.stats" |
13117                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13118                                 $1 == ctr { sum += $7 }
13119                                 END { printf("%0.0f", sum) }')
13120
13121                 if ((sum != bs * count)); then
13122                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13123                 fi
13124         done
13125
13126         rm -rf $DIR/${tdir}
13127 }
13128 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13129
13130 test_133f() {
13131         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13132                 skip "too old lustre for get_param -R ($facet_ver)"
13133
13134         # verifying readability.
13135         $LCTL get_param -R '*' &> /dev/null
13136
13137         # Verifing writability with badarea_io.
13138         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13139                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13140                 error "client badarea_io failed"
13141
13142         # remount the FS in case writes/reads /proc break the FS
13143         cleanup || error "failed to unmount"
13144         setup || error "failed to setup"
13145 }
13146 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13147
13148 test_133g() {
13149         remote_mds_nodsh && skip "remote MDS with nodsh"
13150         remote_ost_nodsh && skip "remote OST with nodsh"
13151
13152         local facet
13153         for facet in mds1 ost1; do
13154                 local facet_ver=$(lustre_version_code $facet)
13155                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13156                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13157                 else
13158                         log "$facet: too old lustre for get_param -R"
13159                 fi
13160                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13161                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13162                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13163                                 xargs badarea_io" ||
13164                                         error "$facet badarea_io failed"
13165                 else
13166                         skip_noexit "$facet: too old lustre for get_param -R"
13167                 fi
13168         done
13169
13170         # remount the FS in case writes/reads /proc break the FS
13171         cleanup || error "failed to unmount"
13172         setup || error "failed to setup"
13173 }
13174 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13175
13176 test_133h() {
13177         remote_mds_nodsh && skip "remote MDS with nodsh"
13178         remote_ost_nodsh && skip "remote OST with nodsh"
13179         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13180                 skip "Need MDS version at least 2.9.54"
13181
13182         local facet
13183         for facet in client mds1 ost1; do
13184                 # Get the list of files that are missing the terminating newline
13185                 local plist=$(do_facet $facet
13186                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13187                 local ent
13188                 for ent in $plist; do
13189                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13190                                 awk -v FS='\v' -v RS='\v\v' \
13191                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13192                                         print FILENAME}'" 2>/dev/null)
13193                         [ -z $missing ] || {
13194                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13195                                 error "file does not end with newline: $facet-$ent"
13196                         }
13197                 done
13198         done
13199 }
13200 run_test 133h "Proc files should end with newlines"
13201
13202 test_134a() {
13203         remote_mds_nodsh && skip "remote MDS with nodsh"
13204         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13205                 skip "Need MDS version at least 2.7.54"
13206
13207         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13208         cancel_lru_locks mdc
13209
13210         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13211         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13212         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13213
13214         local nr=1000
13215         createmany -o $DIR/$tdir/f $nr ||
13216                 error "failed to create $nr files in $DIR/$tdir"
13217         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13218
13219         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13220         do_facet mds1 $LCTL set_param fail_loc=0x327
13221         do_facet mds1 $LCTL set_param fail_val=500
13222         touch $DIR/$tdir/m
13223
13224         echo "sleep 10 seconds ..."
13225         sleep 10
13226         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13227
13228         do_facet mds1 $LCTL set_param fail_loc=0
13229         do_facet mds1 $LCTL set_param fail_val=0
13230         [ $lck_cnt -lt $unused ] ||
13231                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13232
13233         rm $DIR/$tdir/m
13234         unlinkmany $DIR/$tdir/f $nr
13235 }
13236 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13237
13238 test_134b() {
13239         remote_mds_nodsh && skip "remote MDS with nodsh"
13240         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13241                 skip "Need MDS version at least 2.7.54"
13242
13243         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13244         cancel_lru_locks mdc
13245
13246         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13247                         ldlm.lock_reclaim_threshold_mb)
13248         # disable reclaim temporarily
13249         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13250
13251         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13252         do_facet mds1 $LCTL set_param fail_loc=0x328
13253         do_facet mds1 $LCTL set_param fail_val=500
13254
13255         $LCTL set_param debug=+trace
13256
13257         local nr=600
13258         createmany -o $DIR/$tdir/f $nr &
13259         local create_pid=$!
13260
13261         echo "Sleep $TIMEOUT seconds ..."
13262         sleep $TIMEOUT
13263         if ! ps -p $create_pid  > /dev/null 2>&1; then
13264                 do_facet mds1 $LCTL set_param fail_loc=0
13265                 do_facet mds1 $LCTL set_param fail_val=0
13266                 do_facet mds1 $LCTL set_param \
13267                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13268                 error "createmany finished incorrectly!"
13269         fi
13270         do_facet mds1 $LCTL set_param fail_loc=0
13271         do_facet mds1 $LCTL set_param fail_val=0
13272         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13273         wait $create_pid || return 1
13274
13275         unlinkmany $DIR/$tdir/f $nr
13276 }
13277 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13278
13279 test_135() {
13280         remote_mds_nodsh && skip "remote MDS with nodsh"
13281         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13282                 skip "Need MDS version at least 2.13.50"
13283         local fname
13284
13285         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13286
13287 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13288         #set only one record at plain llog
13289         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13290
13291         #fill already existed plain llog each 64767
13292         #wrapping whole catalog
13293         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13294
13295         createmany -o $DIR/$tdir/$tfile_ 64700
13296         for (( i = 0; i < 64700; i = i + 2 ))
13297         do
13298                 rm $DIR/$tdir/$tfile_$i &
13299                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13300                 local pid=$!
13301                 wait $pid
13302         done
13303
13304         #waiting osp synchronization
13305         wait_delete_completed
13306 }
13307 run_test 135 "Race catalog processing"
13308
13309 test_136() {
13310         remote_mds_nodsh && skip "remote MDS with nodsh"
13311         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13312                 skip "Need MDS version at least 2.13.50"
13313         local fname
13314
13315         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13316         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13317         #set only one record at plain llog
13318 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13319         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13320
13321         #fill already existed 2 plain llogs each 64767
13322         #wrapping whole catalog
13323         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13324         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13325         wait_delete_completed
13326
13327         createmany -o $DIR/$tdir/$tfile_ 10
13328         sleep 25
13329
13330         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13331         for (( i = 0; i < 10; i = i + 3 ))
13332         do
13333                 rm $DIR/$tdir/$tfile_$i &
13334                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13335                 local pid=$!
13336                 wait $pid
13337                 sleep 7
13338                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13339         done
13340
13341         #waiting osp synchronization
13342         wait_delete_completed
13343 }
13344 run_test 136 "Race catalog processing 2"
13345
13346 test_140() { #bug-17379
13347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13348
13349         test_mkdir $DIR/$tdir
13350         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13351         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13352
13353         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13354         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13355         local i=0
13356         while i=$((i + 1)); do
13357                 test_mkdir $i
13358                 cd $i || error "Changing to $i"
13359                 ln -s ../stat stat || error "Creating stat symlink"
13360                 # Read the symlink until ELOOP present,
13361                 # not LBUGing the system is considered success,
13362                 # we didn't overrun the stack.
13363                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13364                 if [ $ret -ne 0 ]; then
13365                         if [ $ret -eq 40 ]; then
13366                                 break  # -ELOOP
13367                         else
13368                                 error "Open stat symlink"
13369                                         return
13370                         fi
13371                 fi
13372         done
13373         i=$((i - 1))
13374         echo "The symlink depth = $i"
13375         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13376                 error "Invalid symlink depth"
13377
13378         # Test recursive symlink
13379         ln -s symlink_self symlink_self
13380         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13381         echo "open symlink_self returns $ret"
13382         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13383 }
13384 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13385
13386 test_150a() {
13387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13388
13389         local TF="$TMP/$tfile"
13390
13391         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13392         cp $TF $DIR/$tfile
13393         cancel_lru_locks $OSC
13394         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13395         remount_client $MOUNT
13396         df -P $MOUNT
13397         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13398
13399         $TRUNCATE $TF 6000
13400         $TRUNCATE $DIR/$tfile 6000
13401         cancel_lru_locks $OSC
13402         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13403
13404         echo "12345" >>$TF
13405         echo "12345" >>$DIR/$tfile
13406         cancel_lru_locks $OSC
13407         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13408
13409         echo "12345" >>$TF
13410         echo "12345" >>$DIR/$tfile
13411         cancel_lru_locks $OSC
13412         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13413
13414         rm -f $TF
13415         true
13416 }
13417 run_test 150a "truncate/append tests"
13418
13419 test_150b() {
13420         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13421         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13422                 skip "Need OST version at least 2.13.53"
13423         touch $DIR/$tfile
13424         check_fallocate $DIR/$tfile || error "fallocate failed"
13425 }
13426 run_test 150b "Verify fallocate (prealloc) functionality"
13427
13428 test_150c() {
13429         local bytes
13430         local want
13431
13432         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13433         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13434                 skip "Need OST version at least 2.13.53"
13435
13436         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13437         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13438         sync; sync_all_data
13439         cancel_lru_locks $OSC
13440         sleep 5
13441         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13442         want=$((OSTCOUNT * 1048576))
13443
13444         # Must allocate all requested space, not more than 5% extra
13445         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13446                 error "bytes $bytes is not $want"
13447 }
13448 run_test 150c "Verify fallocate Size and Blocks"
13449
13450 test_150d() {
13451         local bytes
13452         local want
13453
13454         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13455         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13456                 skip "Need OST version at least 2.13.53"
13457
13458         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13459         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13460         sync; sync_all_data
13461         cancel_lru_locks $OSC
13462         sleep 5
13463         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13464         want=$((OSTCOUNT * 1048576))
13465
13466         # Must allocate all requested space, not more than 5% extra
13467         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13468                 error "bytes $bytes is not $want"
13469 }
13470 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13471
13472 test_150e() {
13473         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13474         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13475                 skip "Need OST version at least 2.13.55"
13476
13477         echo "df before:"
13478         $LFS df
13479         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13480                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13481
13482         # Find OST with Minimum Size
13483         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13484                        sort -un | head -1)
13485
13486         # Get 90% of the available space
13487         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13488
13489         fallocate -l${space}k $DIR/$tfile ||
13490                 error "fallocate ${space}k $DIR/$tfile failed"
13491         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13492
13493         # get size immediately after fallocate. This should be correctly
13494         # updated
13495         local size=$(stat -c '%s' $DIR/$tfile)
13496         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13497
13498         # Sleep for a while for statfs to get updated. And not pull from cache.
13499         sleep 2
13500
13501         echo "df after fallocate:"
13502         $LFS df
13503
13504         (( size / 1024 == space )) || error "size $size != requested $space"
13505         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13506                 error "used $used < space $space"
13507
13508         rm $DIR/$tfile || error "rm failed"
13509         sync
13510         wait_delete_completed
13511
13512         echo "df after unlink:"
13513         $LFS df
13514 }
13515 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13516
13517 #LU-2902 roc_hit was not able to read all values from lproc
13518 function roc_hit_init() {
13519         local list=$(comma_list $(osts_nodes))
13520         local dir=$DIR/$tdir-check
13521         local file=$dir/$tfile
13522         local BEFORE
13523         local AFTER
13524         local idx
13525
13526         test_mkdir $dir
13527         #use setstripe to do a write to every ost
13528         for i in $(seq 0 $((OSTCOUNT-1))); do
13529                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13530                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13531                 idx=$(printf %04x $i)
13532                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13533                         awk '$1 == "cache_access" {sum += $7}
13534                                 END { printf("%0.0f", sum) }')
13535
13536                 cancel_lru_locks osc
13537                 cat $file >/dev/null
13538
13539                 AFTER=$(get_osd_param $list *OST*$idx stats |
13540                         awk '$1 == "cache_access" {sum += $7}
13541                                 END { printf("%0.0f", sum) }')
13542
13543                 echo BEFORE:$BEFORE AFTER:$AFTER
13544                 if ! let "AFTER - BEFORE == 4"; then
13545                         rm -rf $dir
13546                         error "roc_hit is not safe to use"
13547                 fi
13548                 rm $file
13549         done
13550
13551         rm -rf $dir
13552 }
13553
13554 function roc_hit() {
13555         local list=$(comma_list $(osts_nodes))
13556         echo $(get_osd_param $list '' stats |
13557                 awk '$1 == "cache_hit" {sum += $7}
13558                         END { printf("%0.0f", sum) }')
13559 }
13560
13561 function set_cache() {
13562         local on=1
13563
13564         if [ "$2" == "off" ]; then
13565                 on=0;
13566         fi
13567         local list=$(comma_list $(osts_nodes))
13568         set_osd_param $list '' $1_cache_enable $on
13569
13570         cancel_lru_locks osc
13571 }
13572
13573 test_151() {
13574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13575         remote_ost_nodsh && skip "remote OST with nodsh"
13576
13577         local CPAGES=3
13578         local list=$(comma_list $(osts_nodes))
13579
13580         # check whether obdfilter is cache capable at all
13581         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13582                 skip "not cache-capable obdfilter"
13583         fi
13584
13585         # check cache is enabled on all obdfilters
13586         if get_osd_param $list '' read_cache_enable | grep 0; then
13587                 skip "oss cache is disabled"
13588         fi
13589
13590         set_osd_param $list '' writethrough_cache_enable 1
13591
13592         # check write cache is enabled on all obdfilters
13593         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13594                 skip "oss write cache is NOT enabled"
13595         fi
13596
13597         roc_hit_init
13598
13599         #define OBD_FAIL_OBD_NO_LRU  0x609
13600         do_nodes $list $LCTL set_param fail_loc=0x609
13601
13602         # pages should be in the case right after write
13603         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13604                 error "dd failed"
13605
13606         local BEFORE=$(roc_hit)
13607         cancel_lru_locks osc
13608         cat $DIR/$tfile >/dev/null
13609         local AFTER=$(roc_hit)
13610
13611         do_nodes $list $LCTL set_param fail_loc=0
13612
13613         if ! let "AFTER - BEFORE == CPAGES"; then
13614                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13615         fi
13616
13617         cancel_lru_locks osc
13618         # invalidates OST cache
13619         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13620         set_osd_param $list '' read_cache_enable 0
13621         cat $DIR/$tfile >/dev/null
13622
13623         # now data shouldn't be found in the cache
13624         BEFORE=$(roc_hit)
13625         cancel_lru_locks osc
13626         cat $DIR/$tfile >/dev/null
13627         AFTER=$(roc_hit)
13628         if let "AFTER - BEFORE != 0"; then
13629                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13630         fi
13631
13632         set_osd_param $list '' read_cache_enable 1
13633         rm -f $DIR/$tfile
13634 }
13635 run_test 151 "test cache on oss and controls ==============================="
13636
13637 test_152() {
13638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13639
13640         local TF="$TMP/$tfile"
13641
13642         # simulate ENOMEM during write
13643 #define OBD_FAIL_OST_NOMEM      0x226
13644         lctl set_param fail_loc=0x80000226
13645         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13646         cp $TF $DIR/$tfile
13647         sync || error "sync failed"
13648         lctl set_param fail_loc=0
13649
13650         # discard client's cache
13651         cancel_lru_locks osc
13652
13653         # simulate ENOMEM during read
13654         lctl set_param fail_loc=0x80000226
13655         cmp $TF $DIR/$tfile || error "cmp failed"
13656         lctl set_param fail_loc=0
13657
13658         rm -f $TF
13659 }
13660 run_test 152 "test read/write with enomem ============================"
13661
13662 test_153() {
13663         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13664 }
13665 run_test 153 "test if fdatasync does not crash ======================="
13666
13667 dot_lustre_fid_permission_check() {
13668         local fid=$1
13669         local ffid=$MOUNT/.lustre/fid/$fid
13670         local test_dir=$2
13671
13672         echo "stat fid $fid"
13673         stat $ffid > /dev/null || error "stat $ffid failed."
13674         echo "touch fid $fid"
13675         touch $ffid || error "touch $ffid failed."
13676         echo "write to fid $fid"
13677         cat /etc/hosts > $ffid || error "write $ffid failed."
13678         echo "read fid $fid"
13679         diff /etc/hosts $ffid || error "read $ffid failed."
13680         echo "append write to fid $fid"
13681         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13682         echo "rename fid $fid"
13683         mv $ffid $test_dir/$tfile.1 &&
13684                 error "rename $ffid to $tfile.1 should fail."
13685         touch $test_dir/$tfile.1
13686         mv $test_dir/$tfile.1 $ffid &&
13687                 error "rename $tfile.1 to $ffid should fail."
13688         rm -f $test_dir/$tfile.1
13689         echo "truncate fid $fid"
13690         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13691         echo "link fid $fid"
13692         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13693         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13694                 echo "setfacl fid $fid"
13695                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13696                 echo "getfacl fid $fid"
13697                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13698         fi
13699         echo "unlink fid $fid"
13700         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13701         echo "mknod fid $fid"
13702         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13703
13704         fid=[0xf00000400:0x1:0x0]
13705         ffid=$MOUNT/.lustre/fid/$fid
13706
13707         echo "stat non-exist fid $fid"
13708         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13709         echo "write to non-exist fid $fid"
13710         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13711         echo "link new fid $fid"
13712         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13713
13714         mkdir -p $test_dir/$tdir
13715         touch $test_dir/$tdir/$tfile
13716         fid=$($LFS path2fid $test_dir/$tdir)
13717         rc=$?
13718         [ $rc -ne 0 ] &&
13719                 error "error: could not get fid for $test_dir/$dir/$tfile."
13720
13721         ffid=$MOUNT/.lustre/fid/$fid
13722
13723         echo "ls $fid"
13724         ls $ffid > /dev/null || error "ls $ffid failed."
13725         echo "touch $fid/$tfile.1"
13726         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13727
13728         echo "touch $MOUNT/.lustre/fid/$tfile"
13729         touch $MOUNT/.lustre/fid/$tfile && \
13730                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13731
13732         echo "setxattr to $MOUNT/.lustre/fid"
13733         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13734
13735         echo "listxattr for $MOUNT/.lustre/fid"
13736         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13737
13738         echo "delxattr from $MOUNT/.lustre/fid"
13739         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13740
13741         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13742         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13743                 error "touch invalid fid should fail."
13744
13745         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13746         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13747                 error "touch non-normal fid should fail."
13748
13749         echo "rename $tdir to $MOUNT/.lustre/fid"
13750         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13751                 error "rename to $MOUNT/.lustre/fid should fail."
13752
13753         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13754         then            # LU-3547
13755                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13756                 local new_obf_mode=777
13757
13758                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13759                 chmod $new_obf_mode $DIR/.lustre/fid ||
13760                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13761
13762                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13763                 [ $obf_mode -eq $new_obf_mode ] ||
13764                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13765
13766                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13767                 chmod $old_obf_mode $DIR/.lustre/fid ||
13768                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13769         fi
13770
13771         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13772         fid=$($LFS path2fid $test_dir/$tfile-2)
13773
13774         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13775         then # LU-5424
13776                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13777                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13778                         error "create lov data thru .lustre failed"
13779         fi
13780         echo "cp /etc/passwd $test_dir/$tfile-2"
13781         cp /etc/passwd $test_dir/$tfile-2 ||
13782                 error "copy to $test_dir/$tfile-2 failed."
13783         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13784         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13785                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13786
13787         rm -rf $test_dir/tfile.lnk
13788         rm -rf $test_dir/$tfile-2
13789 }
13790
13791 test_154A() {
13792         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13793                 skip "Need MDS version at least 2.4.1"
13794
13795         local tf=$DIR/$tfile
13796         touch $tf
13797
13798         local fid=$($LFS path2fid $tf)
13799         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13800
13801         # check that we get the same pathname back
13802         local rootpath
13803         local found
13804         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13805                 echo "$rootpath $fid"
13806                 found=$($LFS fid2path $rootpath "$fid")
13807                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13808                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13809         done
13810
13811         # check wrong root path format
13812         rootpath=$MOUNT"_wrong"
13813         found=$($LFS fid2path $rootpath "$fid")
13814         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13815 }
13816 run_test 154A "lfs path2fid and fid2path basic checks"
13817
13818 test_154B() {
13819         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13820                 skip "Need MDS version at least 2.4.1"
13821
13822         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13823         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13824         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13825         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13826
13827         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13828         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13829
13830         # check that we get the same pathname
13831         echo "PFID: $PFID, name: $name"
13832         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13833         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13834         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13835                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13836
13837         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13838 }
13839 run_test 154B "verify the ll_decode_linkea tool"
13840
13841 test_154a() {
13842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13843         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13844         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13845                 skip "Need MDS version at least 2.2.51"
13846         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13847
13848         cp /etc/hosts $DIR/$tfile
13849
13850         fid=$($LFS path2fid $DIR/$tfile)
13851         rc=$?
13852         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13853
13854         dot_lustre_fid_permission_check "$fid" $DIR ||
13855                 error "dot lustre permission check $fid failed"
13856
13857         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13858
13859         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13860
13861         touch $MOUNT/.lustre/file &&
13862                 error "creation is not allowed under .lustre"
13863
13864         mkdir $MOUNT/.lustre/dir &&
13865                 error "mkdir is not allowed under .lustre"
13866
13867         rm -rf $DIR/$tfile
13868 }
13869 run_test 154a "Open-by-FID"
13870
13871 test_154b() {
13872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13873         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13874         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13875         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13876                 skip "Need MDS version at least 2.2.51"
13877
13878         local remote_dir=$DIR/$tdir/remote_dir
13879         local MDTIDX=1
13880         local rc=0
13881
13882         mkdir -p $DIR/$tdir
13883         $LFS mkdir -i $MDTIDX $remote_dir ||
13884                 error "create remote directory failed"
13885
13886         cp /etc/hosts $remote_dir/$tfile
13887
13888         fid=$($LFS path2fid $remote_dir/$tfile)
13889         rc=$?
13890         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13891
13892         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13893                 error "dot lustre permission check $fid failed"
13894         rm -rf $DIR/$tdir
13895 }
13896 run_test 154b "Open-by-FID for remote directory"
13897
13898 test_154c() {
13899         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13900                 skip "Need MDS version at least 2.4.1"
13901
13902         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13903         local FID1=$($LFS path2fid $DIR/$tfile.1)
13904         local FID2=$($LFS path2fid $DIR/$tfile.2)
13905         local FID3=$($LFS path2fid $DIR/$tfile.3)
13906
13907         local N=1
13908         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13909                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13910                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13911                 local want=FID$N
13912                 [ "$FID" = "${!want}" ] ||
13913                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13914                 N=$((N + 1))
13915         done
13916
13917         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13918         do
13919                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13920                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13921                 N=$((N + 1))
13922         done
13923 }
13924 run_test 154c "lfs path2fid and fid2path multiple arguments"
13925
13926 test_154d() {
13927         remote_mds_nodsh && skip "remote MDS with nodsh"
13928         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13929                 skip "Need MDS version at least 2.5.53"
13930
13931         if remote_mds; then
13932                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13933         else
13934                 nid="0@lo"
13935         fi
13936         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13937         local fd
13938         local cmd
13939
13940         rm -f $DIR/$tfile
13941         touch $DIR/$tfile
13942
13943         local fid=$($LFS path2fid $DIR/$tfile)
13944         # Open the file
13945         fd=$(free_fd)
13946         cmd="exec $fd<$DIR/$tfile"
13947         eval $cmd
13948         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13949         echo "$fid_list" | grep "$fid"
13950         rc=$?
13951
13952         cmd="exec $fd>/dev/null"
13953         eval $cmd
13954         if [ $rc -ne 0 ]; then
13955                 error "FID $fid not found in open files list $fid_list"
13956         fi
13957 }
13958 run_test 154d "Verify open file fid"
13959
13960 test_154e()
13961 {
13962         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13963                 skip "Need MDS version at least 2.6.50"
13964
13965         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13966                 error ".lustre returned by readdir"
13967         fi
13968 }
13969 run_test 154e ".lustre is not returned by readdir"
13970
13971 test_154f() {
13972         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13973
13974         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13975         test_mkdir -p -c1 $DIR/$tdir/d
13976         # test dirs inherit from its stripe
13977         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13978         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13979         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13980         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13981         touch $DIR/f
13982
13983         # get fid of parents
13984         local FID0=$($LFS path2fid $DIR/$tdir/d)
13985         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13986         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13987         local FID3=$($LFS path2fid $DIR)
13988
13989         # check that path2fid --parents returns expected <parent_fid>/name
13990         # 1) test for a directory (single parent)
13991         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13992         [ "$parent" == "$FID0/foo1" ] ||
13993                 error "expected parent: $FID0/foo1, got: $parent"
13994
13995         # 2) test for a file with nlink > 1 (multiple parents)
13996         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13997         echo "$parent" | grep -F "$FID1/$tfile" ||
13998                 error "$FID1/$tfile not returned in parent list"
13999         echo "$parent" | grep -F "$FID2/link" ||
14000                 error "$FID2/link not returned in parent list"
14001
14002         # 3) get parent by fid
14003         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14004         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14005         echo "$parent" | grep -F "$FID1/$tfile" ||
14006                 error "$FID1/$tfile not returned in parent list (by fid)"
14007         echo "$parent" | grep -F "$FID2/link" ||
14008                 error "$FID2/link not returned in parent list (by fid)"
14009
14010         # 4) test for entry in root directory
14011         parent=$($LFS path2fid --parents $DIR/f)
14012         echo "$parent" | grep -F "$FID3/f" ||
14013                 error "$FID3/f not returned in parent list"
14014
14015         # 5) test it on root directory
14016         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14017                 error "$MOUNT should not have parents"
14018
14019         # enable xattr caching and check that linkea is correctly updated
14020         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14021         save_lustre_params client "llite.*.xattr_cache" > $save
14022         lctl set_param llite.*.xattr_cache 1
14023
14024         # 6.1) linkea update on rename
14025         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14026
14027         # get parents by fid
14028         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14029         # foo1 should no longer be returned in parent list
14030         echo "$parent" | grep -F "$FID1" &&
14031                 error "$FID1 should no longer be in parent list"
14032         # the new path should appear
14033         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14034                 error "$FID2/$tfile.moved is not in parent list"
14035
14036         # 6.2) linkea update on unlink
14037         rm -f $DIR/$tdir/d/foo2/link
14038         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14039         # foo2/link should no longer be returned in parent list
14040         echo "$parent" | grep -F "$FID2/link" &&
14041                 error "$FID2/link should no longer be in parent list"
14042         true
14043
14044         rm -f $DIR/f
14045         restore_lustre_params < $save
14046         rm -f $save
14047 }
14048 run_test 154f "get parent fids by reading link ea"
14049
14050 test_154g()
14051 {
14052         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14053         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14054            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14055                 skip "Need MDS version at least 2.6.92"
14056
14057         mkdir -p $DIR/$tdir
14058         llapi_fid_test -d $DIR/$tdir
14059 }
14060 run_test 154g "various llapi FID tests"
14061
14062 test_155_small_load() {
14063     local temp=$TMP/$tfile
14064     local file=$DIR/$tfile
14065
14066     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14067         error "dd of=$temp bs=6096 count=1 failed"
14068     cp $temp $file
14069     cancel_lru_locks $OSC
14070     cmp $temp $file || error "$temp $file differ"
14071
14072     $TRUNCATE $temp 6000
14073     $TRUNCATE $file 6000
14074     cmp $temp $file || error "$temp $file differ (truncate1)"
14075
14076     echo "12345" >>$temp
14077     echo "12345" >>$file
14078     cmp $temp $file || error "$temp $file differ (append1)"
14079
14080     echo "12345" >>$temp
14081     echo "12345" >>$file
14082     cmp $temp $file || error "$temp $file differ (append2)"
14083
14084     rm -f $temp $file
14085     true
14086 }
14087
14088 test_155_big_load() {
14089         remote_ost_nodsh && skip "remote OST with nodsh"
14090
14091         local temp=$TMP/$tfile
14092         local file=$DIR/$tfile
14093
14094         free_min_max
14095         local cache_size=$(do_facet ost$((MAXI+1)) \
14096                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14097         local large_file_size=$((cache_size * 2))
14098
14099         echo "OSS cache size: $cache_size KB"
14100         echo "Large file size: $large_file_size KB"
14101
14102         [ $MAXV -le $large_file_size ] &&
14103                 skip_env "max available OST size needs > $large_file_size KB"
14104
14105         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14106
14107         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14108                 error "dd of=$temp bs=$large_file_size count=1k failed"
14109         cp $temp $file
14110         ls -lh $temp $file
14111         cancel_lru_locks osc
14112         cmp $temp $file || error "$temp $file differ"
14113
14114         rm -f $temp $file
14115         true
14116 }
14117
14118 save_writethrough() {
14119         local facets=$(get_facets OST)
14120
14121         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14122 }
14123
14124 test_155a() {
14125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14126
14127         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14128
14129         save_writethrough $p
14130
14131         set_cache read on
14132         set_cache writethrough on
14133         test_155_small_load
14134         restore_lustre_params < $p
14135         rm -f $p
14136 }
14137 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14138
14139 test_155b() {
14140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14141
14142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14143
14144         save_writethrough $p
14145
14146         set_cache read on
14147         set_cache writethrough off
14148         test_155_small_load
14149         restore_lustre_params < $p
14150         rm -f $p
14151 }
14152 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14153
14154 test_155c() {
14155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14156
14157         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14158
14159         save_writethrough $p
14160
14161         set_cache read off
14162         set_cache writethrough on
14163         test_155_small_load
14164         restore_lustre_params < $p
14165         rm -f $p
14166 }
14167 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14168
14169 test_155d() {
14170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14171
14172         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14173
14174         save_writethrough $p
14175
14176         set_cache read off
14177         set_cache writethrough off
14178         test_155_small_load
14179         restore_lustre_params < $p
14180         rm -f $p
14181 }
14182 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14183
14184 test_155e() {
14185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14186
14187         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14188
14189         save_writethrough $p
14190
14191         set_cache read on
14192         set_cache writethrough on
14193         test_155_big_load
14194         restore_lustre_params < $p
14195         rm -f $p
14196 }
14197 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14198
14199 test_155f() {
14200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14201
14202         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14203
14204         save_writethrough $p
14205
14206         set_cache read on
14207         set_cache writethrough off
14208         test_155_big_load
14209         restore_lustre_params < $p
14210         rm -f $p
14211 }
14212 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14213
14214 test_155g() {
14215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14216
14217         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14218
14219         save_writethrough $p
14220
14221         set_cache read off
14222         set_cache writethrough on
14223         test_155_big_load
14224         restore_lustre_params < $p
14225         rm -f $p
14226 }
14227 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14228
14229 test_155h() {
14230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14231
14232         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14233
14234         save_writethrough $p
14235
14236         set_cache read off
14237         set_cache writethrough off
14238         test_155_big_load
14239         restore_lustre_params < $p
14240         rm -f $p
14241 }
14242 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14243
14244 test_156() {
14245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14246         remote_ost_nodsh && skip "remote OST with nodsh"
14247         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14248                 skip "stats not implemented on old servers"
14249         [ "$ost1_FSTYPE" = "zfs" ] &&
14250                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14251
14252         local CPAGES=3
14253         local BEFORE
14254         local AFTER
14255         local file="$DIR/$tfile"
14256         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14257
14258         save_writethrough $p
14259         roc_hit_init
14260
14261         log "Turn on read and write cache"
14262         set_cache read on
14263         set_cache writethrough on
14264
14265         log "Write data and read it back."
14266         log "Read should be satisfied from the cache."
14267         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14268         BEFORE=$(roc_hit)
14269         cancel_lru_locks osc
14270         cat $file >/dev/null
14271         AFTER=$(roc_hit)
14272         if ! let "AFTER - BEFORE == CPAGES"; then
14273                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14274         else
14275                 log "cache hits: before: $BEFORE, after: $AFTER"
14276         fi
14277
14278         log "Read again; it should be satisfied from the cache."
14279         BEFORE=$AFTER
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 (3): before: $BEFORE, after: $AFTER"
14285         else
14286                 log "cache hits:: before: $BEFORE, after: $AFTER"
14287         fi
14288
14289         log "Turn off the read cache and turn on the write cache"
14290         set_cache read off
14291         set_cache writethrough on
14292
14293         log "Read again; it should be satisfied from the cache."
14294         BEFORE=$(roc_hit)
14295         cancel_lru_locks osc
14296         cat $file >/dev/null
14297         AFTER=$(roc_hit)
14298         if ! let "AFTER - BEFORE == CPAGES"; then
14299                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14300         else
14301                 log "cache hits:: before: $BEFORE, after: $AFTER"
14302         fi
14303
14304         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14305                 # > 2.12.56 uses pagecache if cached
14306                 log "Read again; it should not be satisfied from the cache."
14307                 BEFORE=$AFTER
14308                 cancel_lru_locks osc
14309                 cat $file >/dev/null
14310                 AFTER=$(roc_hit)
14311                 if ! let "AFTER - BEFORE == 0"; then
14312                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14313                 else
14314                         log "cache hits:: before: $BEFORE, after: $AFTER"
14315                 fi
14316         fi
14317
14318         log "Write data and read it back."
14319         log "Read should be satisfied from the cache."
14320         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14321         BEFORE=$(roc_hit)
14322         cancel_lru_locks osc
14323         cat $file >/dev/null
14324         AFTER=$(roc_hit)
14325         if ! let "AFTER - BEFORE == CPAGES"; then
14326                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14327         else
14328                 log "cache hits:: before: $BEFORE, after: $AFTER"
14329         fi
14330
14331         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14332                 # > 2.12.56 uses pagecache if cached
14333                 log "Read again; it should not be satisfied from the cache."
14334                 BEFORE=$AFTER
14335                 cancel_lru_locks osc
14336                 cat $file >/dev/null
14337                 AFTER=$(roc_hit)
14338                 if ! let "AFTER - BEFORE == 0"; then
14339                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14340                 else
14341                         log "cache hits:: before: $BEFORE, after: $AFTER"
14342                 fi
14343         fi
14344
14345         log "Turn off read and write cache"
14346         set_cache read off
14347         set_cache writethrough off
14348
14349         log "Write data and read it back"
14350         log "It should not be satisfied from the cache."
14351         rm -f $file
14352         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14353         cancel_lru_locks osc
14354         BEFORE=$(roc_hit)
14355         cat $file >/dev/null
14356         AFTER=$(roc_hit)
14357         if ! let "AFTER - BEFORE == 0"; then
14358                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14359         else
14360                 log "cache hits:: before: $BEFORE, after: $AFTER"
14361         fi
14362
14363         log "Turn on the read cache and turn off the write cache"
14364         set_cache read on
14365         set_cache writethrough off
14366
14367         log "Write data and read it back"
14368         log "It should not be satisfied from the cache."
14369         rm -f $file
14370         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14371         BEFORE=$(roc_hit)
14372         cancel_lru_locks osc
14373         cat $file >/dev/null
14374         AFTER=$(roc_hit)
14375         if ! let "AFTER - BEFORE == 0"; then
14376                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14377         else
14378                 log "cache hits:: before: $BEFORE, after: $AFTER"
14379         fi
14380
14381         log "Read again; it should be satisfied from the cache."
14382         BEFORE=$(roc_hit)
14383         cancel_lru_locks osc
14384         cat $file >/dev/null
14385         AFTER=$(roc_hit)
14386         if ! let "AFTER - BEFORE == CPAGES"; then
14387                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14388         else
14389                 log "cache hits:: before: $BEFORE, after: $AFTER"
14390         fi
14391
14392         restore_lustre_params < $p
14393         rm -f $p $file
14394 }
14395 run_test 156 "Verification of tunables"
14396
14397 test_160a() {
14398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14399         remote_mds_nodsh && skip "remote MDS with nodsh"
14400         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14401                 skip "Need MDS version at least 2.2.0"
14402
14403         changelog_register || error "changelog_register failed"
14404         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14405         changelog_users $SINGLEMDS | grep -q $cl_user ||
14406                 error "User $cl_user not found in changelog_users"
14407
14408         # change something
14409         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14410         changelog_clear 0 || error "changelog_clear failed"
14411         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14412         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14413         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14414         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14415         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14416         rm $DIR/$tdir/pics/desktop.jpg
14417
14418         changelog_dump | tail -10
14419
14420         echo "verifying changelog mask"
14421         changelog_chmask "-MKDIR"
14422         changelog_chmask "-CLOSE"
14423
14424         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14425         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14426
14427         changelog_chmask "+MKDIR"
14428         changelog_chmask "+CLOSE"
14429
14430         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14431         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14432
14433         changelog_dump | tail -10
14434         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14435         CLOSES=$(changelog_dump | grep -c "CLOSE")
14436         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14437         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14438
14439         # verify contents
14440         echo "verifying target fid"
14441         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14442         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14443         [ "$fidc" == "$fidf" ] ||
14444                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14445         echo "verifying parent fid"
14446         # The FID returned from the Changelog may be the directory shard on
14447         # a different MDT, and not the FID returned by path2fid on the parent.
14448         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14449         # since this is what will matter when recreating this file in the tree.
14450         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14451         local pathp=$($LFS fid2path $MOUNT "$fidp")
14452         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14453                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14454
14455         echo "getting records for $cl_user"
14456         changelog_users $SINGLEMDS
14457         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14458         local nclr=3
14459         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14460                 error "changelog_clear failed"
14461         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14462         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14463         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14464                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14465
14466         local min0_rec=$(changelog_users $SINGLEMDS |
14467                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14468         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14469                           awk '{ print $1; exit; }')
14470
14471         changelog_dump | tail -n 5
14472         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14473         [ $first_rec == $((min0_rec + 1)) ] ||
14474                 error "first index should be $min0_rec + 1 not $first_rec"
14475
14476         # LU-3446 changelog index reset on MDT restart
14477         local cur_rec1=$(changelog_users $SINGLEMDS |
14478                          awk '/^current.index:/ { print $NF }')
14479         changelog_clear 0 ||
14480                 error "clear all changelog records for $cl_user failed"
14481         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14482         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14483                 error "Fail to start $SINGLEMDS"
14484         local cur_rec2=$(changelog_users $SINGLEMDS |
14485                          awk '/^current.index:/ { print $NF }')
14486         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14487         [ $cur_rec1 == $cur_rec2 ] ||
14488                 error "current index should be $cur_rec1 not $cur_rec2"
14489
14490         echo "verifying users from this test are deregistered"
14491         changelog_deregister || error "changelog_deregister failed"
14492         changelog_users $SINGLEMDS | grep -q $cl_user &&
14493                 error "User '$cl_user' still in changelog_users"
14494
14495         # lctl get_param -n mdd.*.changelog_users
14496         # current index: 144
14497         # ID    index (idle seconds)
14498         # cl3   144 (2)
14499         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14500                 # this is the normal case where all users were deregistered
14501                 # make sure no new records are added when no users are present
14502                 local last_rec1=$(changelog_users $SINGLEMDS |
14503                                   awk '/^current.index:/ { print $NF }')
14504                 touch $DIR/$tdir/chloe
14505                 local last_rec2=$(changelog_users $SINGLEMDS |
14506                                   awk '/^current.index:/ { print $NF }')
14507                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14508                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14509         else
14510                 # any changelog users must be leftovers from a previous test
14511                 changelog_users $SINGLEMDS
14512                 echo "other changelog users; can't verify off"
14513         fi
14514 }
14515 run_test 160a "changelog sanity"
14516
14517 test_160b() { # LU-3587
14518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14519         remote_mds_nodsh && skip "remote MDS with nodsh"
14520         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14521                 skip "Need MDS version at least 2.2.0"
14522
14523         changelog_register || error "changelog_register failed"
14524         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14525         changelog_users $SINGLEMDS | grep -q $cl_user ||
14526                 error "User '$cl_user' not found in changelog_users"
14527
14528         local longname1=$(str_repeat a 255)
14529         local longname2=$(str_repeat b 255)
14530
14531         cd $DIR
14532         echo "creating very long named file"
14533         touch $longname1 || error "create of '$longname1' failed"
14534         echo "renaming very long named file"
14535         mv $longname1 $longname2
14536
14537         changelog_dump | grep RENME | tail -n 5
14538         rm -f $longname2
14539 }
14540 run_test 160b "Verify that very long rename doesn't crash in changelog"
14541
14542 test_160c() {
14543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14544         remote_mds_nodsh && skip "remote MDS with nodsh"
14545
14546         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14547                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14548                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14549                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14550
14551         local rc=0
14552
14553         # Registration step
14554         changelog_register || error "changelog_register failed"
14555
14556         rm -rf $DIR/$tdir
14557         mkdir -p $DIR/$tdir
14558         $MCREATE $DIR/$tdir/foo_160c
14559         changelog_chmask "-TRUNC"
14560         $TRUNCATE $DIR/$tdir/foo_160c 200
14561         changelog_chmask "+TRUNC"
14562         $TRUNCATE $DIR/$tdir/foo_160c 199
14563         changelog_dump | tail -n 5
14564         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14565         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14566 }
14567 run_test 160c "verify that changelog log catch the truncate event"
14568
14569 test_160d() {
14570         remote_mds_nodsh && skip "remote MDS with nodsh"
14571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14573         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14574                 skip "Need MDS version at least 2.7.60"
14575
14576         # Registration step
14577         changelog_register || error "changelog_register failed"
14578
14579         mkdir -p $DIR/$tdir/migrate_dir
14580         changelog_clear 0 || error "changelog_clear failed"
14581
14582         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14583         changelog_dump | tail -n 5
14584         local migrates=$(changelog_dump | grep -c "MIGRT")
14585         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14586 }
14587 run_test 160d "verify that changelog log catch the migrate event"
14588
14589 test_160e() {
14590         remote_mds_nodsh && skip "remote MDS with nodsh"
14591
14592         # Create a user
14593         changelog_register || error "changelog_register failed"
14594
14595         # Delete a future user (expect fail)
14596         local MDT0=$(facet_svc $SINGLEMDS)
14597         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14598         local rc=$?
14599
14600         if [ $rc -eq 0 ]; then
14601                 error "Deleted non-existant user cl77"
14602         elif [ $rc -ne 2 ]; then
14603                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14604         fi
14605
14606         # Clear to a bad index (1 billion should be safe)
14607         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14608         rc=$?
14609
14610         if [ $rc -eq 0 ]; then
14611                 error "Successfully cleared to invalid CL index"
14612         elif [ $rc -ne 22 ]; then
14613                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14614         fi
14615 }
14616 run_test 160e "changelog negative testing (should return errors)"
14617
14618 test_160f() {
14619         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14620         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14621                 skip "Need MDS version at least 2.10.56"
14622
14623         local mdts=$(comma_list $(mdts_nodes))
14624
14625         # Create a user
14626         changelog_register || error "first changelog_register failed"
14627         changelog_register || error "second changelog_register failed"
14628         local cl_users
14629         declare -A cl_user1
14630         declare -A cl_user2
14631         local user_rec1
14632         local user_rec2
14633         local i
14634
14635         # generate some changelog records to accumulate on each MDT
14636         # use fnv1a because created files should be evenly distributed
14637         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14638                 error "test_mkdir $tdir failed"
14639         log "$(date +%s): creating first files"
14640         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14641                 error "create $DIR/$tdir/$tfile failed"
14642
14643         # check changelogs have been generated
14644         local start=$SECONDS
14645         local idle_time=$((MDSCOUNT * 5 + 5))
14646         local nbcl=$(changelog_dump | wc -l)
14647         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14648
14649         for param in "changelog_max_idle_time=$idle_time" \
14650                      "changelog_gc=1" \
14651                      "changelog_min_gc_interval=2" \
14652                      "changelog_min_free_cat_entries=3"; do
14653                 local MDT0=$(facet_svc $SINGLEMDS)
14654                 local var="${param%=*}"
14655                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14656
14657                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14658                 do_nodes $mdts $LCTL set_param mdd.*.$param
14659         done
14660
14661         # force cl_user2 to be idle (1st part), but also cancel the
14662         # cl_user1 records so that it is not evicted later in the test.
14663         local sleep1=$((idle_time / 2))
14664         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14665         sleep $sleep1
14666
14667         # simulate changelog catalog almost full
14668         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14669         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14670
14671         for i in $(seq $MDSCOUNT); do
14672                 cl_users=(${CL_USERS[mds$i]})
14673                 cl_user1[mds$i]="${cl_users[0]}"
14674                 cl_user2[mds$i]="${cl_users[1]}"
14675
14676                 [ -n "${cl_user1[mds$i]}" ] ||
14677                         error "mds$i: no user registered"
14678                 [ -n "${cl_user2[mds$i]}" ] ||
14679                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14680
14681                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14682                 [ -n "$user_rec1" ] ||
14683                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14684                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14685                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14686                 [ -n "$user_rec2" ] ||
14687                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14688                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14689                      "$user_rec1 + 2 == $user_rec2"
14690                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14691                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14692                               "$user_rec1 + 2, but is $user_rec2"
14693                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14694                 [ -n "$user_rec2" ] ||
14695                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14696                 [ $user_rec1 == $user_rec2 ] ||
14697                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14698                               "$user_rec1, but is $user_rec2"
14699         done
14700
14701         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14702         local sleep2=$((idle_time - (SECONDS - start) + 1))
14703         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14704         sleep $sleep2
14705
14706         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14707         # cl_user1 should be OK because it recently processed records.
14708         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14709         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14710                 error "create $DIR/$tdir/${tfile}b failed"
14711
14712         # ensure gc thread is done
14713         for i in $(mdts_nodes); do
14714                 wait_update $i \
14715                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14716                         error "$i: GC-thread not done"
14717         done
14718
14719         local first_rec
14720         for i in $(seq $MDSCOUNT); do
14721                 # check cl_user1 still registered
14722                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14723                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14724                 # check cl_user2 unregistered
14725                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14726                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14727
14728                 # check changelogs are present and starting at $user_rec1 + 1
14729                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14730                 [ -n "$user_rec1" ] ||
14731                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14732                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14733                             awk '{ print $1; exit; }')
14734
14735                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14736                 [ $((user_rec1 + 1)) == $first_rec ] ||
14737                         error "mds$i: first index should be $user_rec1 + 1, " \
14738                               "but is $first_rec"
14739         done
14740 }
14741 run_test 160f "changelog garbage collect (timestamped users)"
14742
14743 test_160g() {
14744         remote_mds_nodsh && skip "remote MDS with nodsh"
14745         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14746                 skip "Need MDS version at least 2.10.56"
14747
14748         local mdts=$(comma_list $(mdts_nodes))
14749
14750         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14751         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14752
14753         # Create a user
14754         changelog_register || error "first changelog_register failed"
14755         changelog_register || error "second changelog_register failed"
14756         local cl_users
14757         declare -A cl_user1
14758         declare -A cl_user2
14759         local user_rec1
14760         local user_rec2
14761         local i
14762
14763         # generate some changelog records to accumulate on each MDT
14764         # use fnv1a because created files should be evenly distributed
14765         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14766                 error "mkdir $tdir failed"
14767         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14768                 error "create $DIR/$tdir/$tfile failed"
14769
14770         # check changelogs have been generated
14771         local nbcl=$(changelog_dump | wc -l)
14772         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14773
14774         # reduce the max_idle_indexes value to make sure we exceed it
14775         max_ndx=$((nbcl / 2 - 1))
14776
14777         for param in "changelog_max_idle_indexes=$max_ndx" \
14778                      "changelog_gc=1" \
14779                      "changelog_min_gc_interval=2" \
14780                      "changelog_min_free_cat_entries=3"; do
14781                 local MDT0=$(facet_svc $SINGLEMDS)
14782                 local var="${param%=*}"
14783                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14784
14785                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14786                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14787                         error "unable to set mdd.*.$param"
14788         done
14789
14790         # simulate changelog catalog almost full
14791         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14792         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14793
14794         for i in $(seq $MDSCOUNT); do
14795                 cl_users=(${CL_USERS[mds$i]})
14796                 cl_user1[mds$i]="${cl_users[0]}"
14797                 cl_user2[mds$i]="${cl_users[1]}"
14798
14799                 [ -n "${cl_user1[mds$i]}" ] ||
14800                         error "mds$i: no user registered"
14801                 [ -n "${cl_user2[mds$i]}" ] ||
14802                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14803
14804                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14805                 [ -n "$user_rec1" ] ||
14806                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14807                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14808                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14809                 [ -n "$user_rec2" ] ||
14810                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14811                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14812                      "$user_rec1 + 2 == $user_rec2"
14813                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14814                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14815                               "$user_rec1 + 2, but is $user_rec2"
14816                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14817                 [ -n "$user_rec2" ] ||
14818                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14819                 [ $user_rec1 == $user_rec2 ] ||
14820                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14821                               "$user_rec1, but is $user_rec2"
14822         done
14823
14824         # ensure we are past the previous changelog_min_gc_interval set above
14825         sleep 2
14826
14827         # generate one more changelog to trigger fail_loc
14828         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14829                 error "create $DIR/$tdir/${tfile}bis failed"
14830
14831         # ensure gc thread is done
14832         for i in $(mdts_nodes); do
14833                 wait_update $i \
14834                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14835                         error "$i: GC-thread not done"
14836         done
14837
14838         local first_rec
14839         for i in $(seq $MDSCOUNT); do
14840                 # check cl_user1 still registered
14841                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14842                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14843                 # check cl_user2 unregistered
14844                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14845                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14846
14847                 # check changelogs are present and starting at $user_rec1 + 1
14848                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14849                 [ -n "$user_rec1" ] ||
14850                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14851                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14852                             awk '{ print $1; exit; }')
14853
14854                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14855                 [ $((user_rec1 + 1)) == $first_rec ] ||
14856                         error "mds$i: first index should be $user_rec1 + 1, " \
14857                               "but is $first_rec"
14858         done
14859 }
14860 run_test 160g "changelog garbage collect (old users)"
14861
14862 test_160h() {
14863         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14864         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14865                 skip "Need MDS version at least 2.10.56"
14866
14867         local mdts=$(comma_list $(mdts_nodes))
14868
14869         # Create a user
14870         changelog_register || error "first changelog_register failed"
14871         changelog_register || error "second changelog_register failed"
14872         local cl_users
14873         declare -A cl_user1
14874         declare -A cl_user2
14875         local user_rec1
14876         local user_rec2
14877         local i
14878
14879         # generate some changelog records to accumulate on each MDT
14880         # use fnv1a because created files should be evenly distributed
14881         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14882                 error "test_mkdir $tdir failed"
14883         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14884                 error "create $DIR/$tdir/$tfile failed"
14885
14886         # check changelogs have been generated
14887         local nbcl=$(changelog_dump | wc -l)
14888         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14889
14890         for param in "changelog_max_idle_time=10" \
14891                      "changelog_gc=1" \
14892                      "changelog_min_gc_interval=2"; do
14893                 local MDT0=$(facet_svc $SINGLEMDS)
14894                 local var="${param%=*}"
14895                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14896
14897                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14898                 do_nodes $mdts $LCTL set_param mdd.*.$param
14899         done
14900
14901         # force cl_user2 to be idle (1st part)
14902         sleep 9
14903
14904         for i in $(seq $MDSCOUNT); do
14905                 cl_users=(${CL_USERS[mds$i]})
14906                 cl_user1[mds$i]="${cl_users[0]}"
14907                 cl_user2[mds$i]="${cl_users[1]}"
14908
14909                 [ -n "${cl_user1[mds$i]}" ] ||
14910                         error "mds$i: no user registered"
14911                 [ -n "${cl_user2[mds$i]}" ] ||
14912                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14913
14914                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14915                 [ -n "$user_rec1" ] ||
14916                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14917                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14918                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14919                 [ -n "$user_rec2" ] ||
14920                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14921                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14922                      "$user_rec1 + 2 == $user_rec2"
14923                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14924                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14925                               "$user_rec1 + 2, but is $user_rec2"
14926                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14927                 [ -n "$user_rec2" ] ||
14928                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14929                 [ $user_rec1 == $user_rec2 ] ||
14930                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14931                               "$user_rec1, but is $user_rec2"
14932         done
14933
14934         # force cl_user2 to be idle (2nd part) and to reach
14935         # changelog_max_idle_time
14936         sleep 2
14937
14938         # force each GC-thread start and block then
14939         # one per MDT/MDD, set fail_val accordingly
14940         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14941         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14942
14943         # generate more changelogs to trigger fail_loc
14944         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14945                 error "create $DIR/$tdir/${tfile}bis failed"
14946
14947         # stop MDT to stop GC-thread, should be done in back-ground as it will
14948         # block waiting for the thread to be released and exit
14949         declare -A stop_pids
14950         for i in $(seq $MDSCOUNT); do
14951                 stop mds$i &
14952                 stop_pids[mds$i]=$!
14953         done
14954
14955         for i in $(mdts_nodes); do
14956                 local facet
14957                 local nb=0
14958                 local facets=$(facets_up_on_host $i)
14959
14960                 for facet in ${facets//,/ }; do
14961                         if [[ $facet == mds* ]]; then
14962                                 nb=$((nb + 1))
14963                         fi
14964                 done
14965                 # ensure each MDS's gc threads are still present and all in "R"
14966                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14967                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14968                         error "$i: expected $nb GC-thread"
14969                 wait_update $i \
14970                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14971                         "R" 20 ||
14972                         error "$i: GC-thread not found in R-state"
14973                 # check umounts of each MDT on MDS have reached kthread_stop()
14974                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14975                         error "$i: expected $nb umount"
14976                 wait_update $i \
14977                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14978                         error "$i: umount not found in D-state"
14979         done
14980
14981         # release all GC-threads
14982         do_nodes $mdts $LCTL set_param fail_loc=0
14983
14984         # wait for MDT stop to complete
14985         for i in $(seq $MDSCOUNT); do
14986                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14987         done
14988
14989         # XXX
14990         # may try to check if any orphan changelog records are present
14991         # via ldiskfs/zfs and llog_reader...
14992
14993         # re-start/mount MDTs
14994         for i in $(seq $MDSCOUNT); do
14995                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14996                         error "Fail to start mds$i"
14997         done
14998
14999         local first_rec
15000         for i in $(seq $MDSCOUNT); do
15001                 # check cl_user1 still registered
15002                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15003                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15004                 # check cl_user2 unregistered
15005                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15006                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15007
15008                 # check changelogs are present and starting at $user_rec1 + 1
15009                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15010                 [ -n "$user_rec1" ] ||
15011                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15012                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15013                             awk '{ print $1; exit; }')
15014
15015                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15016                 [ $((user_rec1 + 1)) == $first_rec ] ||
15017                         error "mds$i: first index should be $user_rec1 + 1, " \
15018                               "but is $first_rec"
15019         done
15020 }
15021 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15022               "during mount"
15023
15024 test_160i() {
15025
15026         local mdts=$(comma_list $(mdts_nodes))
15027
15028         changelog_register || error "first changelog_register failed"
15029
15030         # generate some changelog records to accumulate on each MDT
15031         # use fnv1a because created files should be evenly distributed
15032         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15033                 error "mkdir $tdir failed"
15034         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15035                 error "create $DIR/$tdir/$tfile failed"
15036
15037         # check changelogs have been generated
15038         local nbcl=$(changelog_dump | wc -l)
15039         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15040
15041         # simulate race between register and unregister
15042         # XXX as fail_loc is set per-MDS, with DNE configs the race
15043         # simulation will only occur for one MDT per MDS and for the
15044         # others the normal race scenario will take place
15045         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15046         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15047         do_nodes $mdts $LCTL set_param fail_val=1
15048
15049         # unregister 1st user
15050         changelog_deregister &
15051         local pid1=$!
15052         # wait some time for deregister work to reach race rdv
15053         sleep 2
15054         # register 2nd user
15055         changelog_register || error "2nd user register failed"
15056
15057         wait $pid1 || error "1st user deregister failed"
15058
15059         local i
15060         local last_rec
15061         declare -A LAST_REC
15062         for i in $(seq $MDSCOUNT); do
15063                 if changelog_users mds$i | grep "^cl"; then
15064                         # make sure new records are added with one user present
15065                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15066                                           awk '/^current.index:/ { print $NF }')
15067                 else
15068                         error "mds$i has no user registered"
15069                 fi
15070         done
15071
15072         # generate more changelog records to accumulate on each MDT
15073         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15074                 error "create $DIR/$tdir/${tfile}bis failed"
15075
15076         for i in $(seq $MDSCOUNT); do
15077                 last_rec=$(changelog_users $SINGLEMDS |
15078                            awk '/^current.index:/ { print $NF }')
15079                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15080                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15081                         error "changelogs are off on mds$i"
15082         done
15083 }
15084 run_test 160i "changelog user register/unregister race"
15085
15086 test_160j() {
15087         remote_mds_nodsh && skip "remote MDS with nodsh"
15088         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15089                 skip "Need MDS version at least 2.12.56"
15090
15091         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15092         stack_trap "umount $MOUNT2" EXIT
15093
15094         changelog_register || error "first changelog_register failed"
15095         stack_trap "changelog_deregister" EXIT
15096
15097         # generate some changelog
15098         # use fnv1a because created files should be evenly distributed
15099         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15100                 error "mkdir $tdir failed"
15101         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15102                 error "create $DIR/$tdir/${tfile}bis failed"
15103
15104         # open the changelog device
15105         exec 3>/dev/changelog-$FSNAME-MDT0000
15106         stack_trap "exec 3>&-" EXIT
15107         exec 4</dev/changelog-$FSNAME-MDT0000
15108         stack_trap "exec 4<&-" EXIT
15109
15110         # umount the first lustre mount
15111         umount $MOUNT
15112         stack_trap "mount_client $MOUNT" EXIT
15113
15114         # read changelog
15115         cat <&4 >/dev/null || error "read changelog failed"
15116
15117         # clear changelog
15118         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15119         changelog_users $SINGLEMDS | grep -q $cl_user ||
15120                 error "User $cl_user not found in changelog_users"
15121
15122         printf 'clear:'$cl_user':0' >&3
15123 }
15124 run_test 160j "client can be umounted  while its chanangelog is being used"
15125
15126 test_160k() {
15127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15128         remote_mds_nodsh && skip "remote MDS with nodsh"
15129
15130         mkdir -p $DIR/$tdir/1/1
15131
15132         changelog_register || error "changelog_register failed"
15133         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15134
15135         changelog_users $SINGLEMDS | grep -q $cl_user ||
15136                 error "User '$cl_user' not found in changelog_users"
15137 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15138         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15139         rmdir $DIR/$tdir/1/1 & sleep 1
15140         mkdir $DIR/$tdir/2
15141         touch $DIR/$tdir/2/2
15142         rm -rf $DIR/$tdir/2
15143
15144         wait
15145         sleep 4
15146
15147         changelog_dump | grep rmdir || error "rmdir not recorded"
15148
15149         rm -rf $DIR/$tdir
15150         changelog_deregister
15151 }
15152 run_test 160k "Verify that changelog records are not lost"
15153
15154 # Verifies that a file passed as a parameter has recently had an operation
15155 # performed on it that has generated an MTIME changelog which contains the
15156 # correct parent FID. As files might reside on a different MDT from the
15157 # parent directory in DNE configurations, the FIDs are translated to paths
15158 # before being compared, which should be identical
15159 compare_mtime_changelog() {
15160         local file="${1}"
15161         local mdtidx
15162         local mtime
15163         local cl_fid
15164         local pdir
15165         local dir
15166
15167         mdtidx=$($LFS getstripe --mdt-index $file)
15168         mdtidx=$(printf "%04x" $mdtidx)
15169
15170         # Obtain the parent FID from the MTIME changelog
15171         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15172         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15173
15174         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15175         [ -z "$cl_fid" ] && error "parent FID not present"
15176
15177         # Verify that the path for the parent FID is the same as the path for
15178         # the test directory
15179         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15180
15181         dir=$(dirname $1)
15182
15183         [[ "${pdir%/}" == "$dir" ]] ||
15184                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15185 }
15186
15187 test_160l() {
15188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15189
15190         remote_mds_nodsh && skip "remote MDS with nodsh"
15191         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15192                 skip "Need MDS version at least 2.13.55"
15193
15194         local cl_user
15195
15196         changelog_register || error "changelog_register failed"
15197         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15198
15199         changelog_users $SINGLEMDS | grep -q $cl_user ||
15200                 error "User '$cl_user' not found in changelog_users"
15201
15202         # Clear some types so that MTIME changelogs are generated
15203         changelog_chmask "-CREAT"
15204         changelog_chmask "-CLOSE"
15205
15206         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15207
15208         # Test CL_MTIME during setattr
15209         touch $DIR/$tdir/$tfile
15210         compare_mtime_changelog $DIR/$tdir/$tfile
15211
15212         # Test CL_MTIME during close
15213         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15214         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15215 }
15216 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15217
15218 test_161a() {
15219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15220
15221         test_mkdir -c1 $DIR/$tdir
15222         cp /etc/hosts $DIR/$tdir/$tfile
15223         test_mkdir -c1 $DIR/$tdir/foo1
15224         test_mkdir -c1 $DIR/$tdir/foo2
15225         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15226         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15227         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15228         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15229         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15230         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15231                 $LFS fid2path $DIR $FID
15232                 error "bad link ea"
15233         fi
15234         # middle
15235         rm $DIR/$tdir/foo2/zachary
15236         # last
15237         rm $DIR/$tdir/foo2/thor
15238         # first
15239         rm $DIR/$tdir/$tfile
15240         # rename
15241         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15242         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15243                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15244         rm $DIR/$tdir/foo2/maggie
15245
15246         # overflow the EA
15247         local longname=$tfile.avg_len_is_thirty_two_
15248         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15249                 error_noexit 'failed to unlink many hardlinks'" EXIT
15250         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15251                 error "failed to hardlink many files"
15252         links=$($LFS fid2path $DIR $FID | wc -l)
15253         echo -n "${links}/1000 links in link EA"
15254         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15255 }
15256 run_test 161a "link ea sanity"
15257
15258 test_161b() {
15259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15260         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15261
15262         local MDTIDX=1
15263         local remote_dir=$DIR/$tdir/remote_dir
15264
15265         mkdir -p $DIR/$tdir
15266         $LFS mkdir -i $MDTIDX $remote_dir ||
15267                 error "create remote directory failed"
15268
15269         cp /etc/hosts $remote_dir/$tfile
15270         mkdir -p $remote_dir/foo1
15271         mkdir -p $remote_dir/foo2
15272         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15273         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15274         ln $remote_dir/$tfile $remote_dir/foo1/luna
15275         ln $remote_dir/$tfile $remote_dir/foo2/thor
15276
15277         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15278                      tr -d ']')
15279         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15280                 $LFS fid2path $DIR $FID
15281                 error "bad link ea"
15282         fi
15283         # middle
15284         rm $remote_dir/foo2/zachary
15285         # last
15286         rm $remote_dir/foo2/thor
15287         # first
15288         rm $remote_dir/$tfile
15289         # rename
15290         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15291         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15292         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15293                 $LFS fid2path $DIR $FID
15294                 error "bad link rename"
15295         fi
15296         rm $remote_dir/foo2/maggie
15297
15298         # overflow the EA
15299         local longname=filename_avg_len_is_thirty_two_
15300         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15301                 error "failed to hardlink many files"
15302         links=$($LFS fid2path $DIR $FID | wc -l)
15303         echo -n "${links}/1000 links in link EA"
15304         [[ ${links} -gt 60 ]] ||
15305                 error "expected at least 60 links in link EA"
15306         unlinkmany $remote_dir/foo2/$longname 1000 ||
15307         error "failed to unlink many hardlinks"
15308 }
15309 run_test 161b "link ea sanity under remote directory"
15310
15311 test_161c() {
15312         remote_mds_nodsh && skip "remote MDS with nodsh"
15313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15314         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15315                 skip "Need MDS version at least 2.1.5"
15316
15317         # define CLF_RENAME_LAST 0x0001
15318         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15319         changelog_register || error "changelog_register failed"
15320
15321         rm -rf $DIR/$tdir
15322         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15323         touch $DIR/$tdir/foo_161c
15324         touch $DIR/$tdir/bar_161c
15325         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15326         changelog_dump | grep RENME | tail -n 5
15327         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15328         changelog_clear 0 || error "changelog_clear failed"
15329         if [ x$flags != "x0x1" ]; then
15330                 error "flag $flags is not 0x1"
15331         fi
15332
15333         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15334         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15335         touch $DIR/$tdir/foo_161c
15336         touch $DIR/$tdir/bar_161c
15337         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15338         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15339         changelog_dump | grep RENME | tail -n 5
15340         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15341         changelog_clear 0 || error "changelog_clear failed"
15342         if [ x$flags != "x0x0" ]; then
15343                 error "flag $flags is not 0x0"
15344         fi
15345         echo "rename overwrite a target having nlink > 1," \
15346                 "changelog record has flags of $flags"
15347
15348         # rename doesn't overwrite a target (changelog flag 0x0)
15349         touch $DIR/$tdir/foo_161c
15350         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15351         changelog_dump | grep RENME | tail -n 5
15352         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15353         changelog_clear 0 || error "changelog_clear failed"
15354         if [ x$flags != "x0x0" ]; then
15355                 error "flag $flags is not 0x0"
15356         fi
15357         echo "rename doesn't overwrite a target," \
15358                 "changelog record has flags of $flags"
15359
15360         # define CLF_UNLINK_LAST 0x0001
15361         # unlink a file having nlink = 1 (changelog flag 0x1)
15362         rm -f $DIR/$tdir/foo2_161c
15363         changelog_dump | grep UNLNK | tail -n 5
15364         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15365         changelog_clear 0 || error "changelog_clear failed"
15366         if [ x$flags != "x0x1" ]; then
15367                 error "flag $flags is not 0x1"
15368         fi
15369         echo "unlink a file having nlink = 1," \
15370                 "changelog record has flags of $flags"
15371
15372         # unlink a file having nlink > 1 (changelog flag 0x0)
15373         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15374         rm -f $DIR/$tdir/foobar_161c
15375         changelog_dump | grep UNLNK | tail -n 5
15376         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15377         changelog_clear 0 || error "changelog_clear failed"
15378         if [ x$flags != "x0x0" ]; then
15379                 error "flag $flags is not 0x0"
15380         fi
15381         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15382 }
15383 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15384
15385 test_161d() {
15386         remote_mds_nodsh && skip "remote MDS with nodsh"
15387         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15388
15389         local pid
15390         local fid
15391
15392         changelog_register || error "changelog_register failed"
15393
15394         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15395         # interfer with $MOUNT/.lustre/fid/ access
15396         mkdir $DIR/$tdir
15397         [[ $? -eq 0 ]] || error "mkdir failed"
15398
15399         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15400         $LCTL set_param fail_loc=0x8000140c
15401         # 5s pause
15402         $LCTL set_param fail_val=5
15403
15404         # create file
15405         echo foofoo > $DIR/$tdir/$tfile &
15406         pid=$!
15407
15408         # wait for create to be delayed
15409         sleep 2
15410
15411         ps -p $pid
15412         [[ $? -eq 0 ]] || error "create should be blocked"
15413
15414         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15415         stack_trap "rm -f $tempfile"
15416         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15417         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15418         # some delay may occur during ChangeLog publishing and file read just
15419         # above, that could allow file write to happen finally
15420         [[ -s $tempfile ]] && echo "file should be empty"
15421
15422         $LCTL set_param fail_loc=0
15423
15424         wait $pid
15425         [[ $? -eq 0 ]] || error "create failed"
15426 }
15427 run_test 161d "create with concurrent .lustre/fid access"
15428
15429 check_path() {
15430         local expected="$1"
15431         shift
15432         local fid="$2"
15433
15434         local path
15435         path=$($LFS fid2path "$@")
15436         local rc=$?
15437
15438         if [ $rc -ne 0 ]; then
15439                 error "path looked up of '$expected' failed: rc=$rc"
15440         elif [ "$path" != "$expected" ]; then
15441                 error "path looked up '$path' instead of '$expected'"
15442         else
15443                 echo "FID '$fid' resolves to path '$path' as expected"
15444         fi
15445 }
15446
15447 test_162a() { # was test_162
15448         test_mkdir -p -c1 $DIR/$tdir/d2
15449         touch $DIR/$tdir/d2/$tfile
15450         touch $DIR/$tdir/d2/x1
15451         touch $DIR/$tdir/d2/x2
15452         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15453         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15454         # regular file
15455         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15456         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15457
15458         # softlink
15459         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15460         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15461         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15462
15463         # softlink to wrong file
15464         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15465         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15466         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15467
15468         # hardlink
15469         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15470         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15471         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15472         # fid2path dir/fsname should both work
15473         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15474         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15475
15476         # hardlink count: check that there are 2 links
15477         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15478         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15479
15480         # hardlink indexing: remove the first link
15481         rm $DIR/$tdir/d2/p/q/r/hlink
15482         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15483 }
15484 run_test 162a "path lookup sanity"
15485
15486 test_162b() {
15487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15489
15490         mkdir $DIR/$tdir
15491         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15492                                 error "create striped dir failed"
15493
15494         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15495                                         tail -n 1 | awk '{print $2}')
15496         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15497
15498         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15499         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15500
15501         # regular file
15502         for ((i=0;i<5;i++)); do
15503                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15504                         error "get fid for f$i failed"
15505                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15506
15507                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15508                         error "get fid for d$i failed"
15509                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15510         done
15511
15512         return 0
15513 }
15514 run_test 162b "striped directory path lookup sanity"
15515
15516 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15517 test_162c() {
15518         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15519                 skip "Need MDS version at least 2.7.51"
15520
15521         local lpath=$tdir.local
15522         local rpath=$tdir.remote
15523
15524         test_mkdir $DIR/$lpath
15525         test_mkdir $DIR/$rpath
15526
15527         for ((i = 0; i <= 101; i++)); do
15528                 lpath="$lpath/$i"
15529                 mkdir $DIR/$lpath
15530                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15531                         error "get fid for local directory $DIR/$lpath failed"
15532                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15533
15534                 rpath="$rpath/$i"
15535                 test_mkdir $DIR/$rpath
15536                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15537                         error "get fid for remote directory $DIR/$rpath failed"
15538                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15539         done
15540
15541         return 0
15542 }
15543 run_test 162c "fid2path works with paths 100 or more directories deep"
15544
15545 oalr_event_count() {
15546         local event="${1}"
15547         local trace="${2}"
15548
15549         awk -v name="${FSNAME}-OST0000" \
15550             -v event="${event}" \
15551             '$1 == "TRACE" && $2 == event && $3 == name' \
15552             "${trace}" |
15553         wc -l
15554 }
15555
15556 oalr_expect_event_count() {
15557         local event="${1}"
15558         local trace="${2}"
15559         local expect="${3}"
15560         local count
15561
15562         count=$(oalr_event_count "${event}" "${trace}")
15563         if ((count == expect)); then
15564                 return 0
15565         fi
15566
15567         error_noexit "${event} event count was '${count}', expected ${expect}"
15568         cat "${trace}" >&2
15569         exit 1
15570 }
15571
15572 cleanup_165() {
15573         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15574         stop ost1
15575         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15576 }
15577
15578 setup_165() {
15579         sync # Flush previous IOs so we can count log entries.
15580         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15581         stack_trap cleanup_165 EXIT
15582 }
15583
15584 test_165a() {
15585         local trace="/tmp/${tfile}.trace"
15586         local rc
15587         local count
15588
15589         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15590                 skip "OFD access log unsupported"
15591
15592         setup_165
15593         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15594         sleep 5
15595
15596         do_facet ost1 ofd_access_log_reader --list
15597         stop ost1
15598
15599         do_facet ost1 killall -TERM ofd_access_log_reader
15600         wait
15601         rc=$?
15602
15603         if ((rc != 0)); then
15604                 error "ofd_access_log_reader exited with rc = '${rc}'"
15605         fi
15606
15607         # Parse trace file for discovery events:
15608         oalr_expect_event_count alr_log_add "${trace}" 1
15609         oalr_expect_event_count alr_log_eof "${trace}" 1
15610         oalr_expect_event_count alr_log_free "${trace}" 1
15611 }
15612 run_test 165a "ofd access log discovery"
15613
15614 test_165b() {
15615         local trace="/tmp/${tfile}.trace"
15616         local file="${DIR}/${tfile}"
15617         local pfid1
15618         local pfid2
15619         local -a entry
15620         local rc
15621         local count
15622         local size
15623         local flags
15624
15625         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15626                 skip "OFD access log unsupported"
15627
15628         setup_165
15629         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15630         sleep 5
15631
15632         do_facet ost1 ofd_access_log_reader --list
15633
15634         lfs setstripe -c 1 -i 0 "${file}"
15635         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15636                 error "cannot create '${file}'"
15637
15638         sleep 5
15639         do_facet ost1 killall -TERM ofd_access_log_reader
15640         wait
15641         rc=$?
15642
15643         if ((rc != 0)); then
15644                 error "ofd_access_log_reader exited with rc = '${rc}'"
15645         fi
15646
15647         oalr_expect_event_count alr_log_entry "${trace}" 1
15648
15649         pfid1=$($LFS path2fid "${file}")
15650
15651         # 1     2             3   4    5     6   7    8    9     10
15652         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15653         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15654
15655         echo "entry = '${entry[*]}'" >&2
15656
15657         pfid2=${entry[4]}
15658         if [[ "${pfid1}" != "${pfid2}" ]]; then
15659                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15660         fi
15661
15662         size=${entry[8]}
15663         if ((size != 1048576)); then
15664                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15665         fi
15666
15667         flags=${entry[10]}
15668         if [[ "${flags}" != "w" ]]; then
15669                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15670         fi
15671
15672         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15673         sleep 5
15674
15675         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15676                 error "cannot read '${file}'"
15677         sleep 5
15678
15679         do_facet ost1 killall -TERM ofd_access_log_reader
15680         wait
15681         rc=$?
15682
15683         if ((rc != 0)); then
15684                 error "ofd_access_log_reader exited with rc = '${rc}'"
15685         fi
15686
15687         oalr_expect_event_count alr_log_entry "${trace}" 1
15688
15689         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15690         echo "entry = '${entry[*]}'" >&2
15691
15692         pfid2=${entry[4]}
15693         if [[ "${pfid1}" != "${pfid2}" ]]; then
15694                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15695         fi
15696
15697         size=${entry[8]}
15698         if ((size != 524288)); then
15699                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15700         fi
15701
15702         flags=${entry[10]}
15703         if [[ "${flags}" != "r" ]]; then
15704                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15705         fi
15706 }
15707 run_test 165b "ofd access log entries are produced and consumed"
15708
15709 test_165c() {
15710         local trace="/tmp/${tfile}.trace"
15711         local file="${DIR}/${tdir}/${tfile}"
15712
15713         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15714                 skip "OFD access log unsupported"
15715
15716         test_mkdir "${DIR}/${tdir}"
15717
15718         setup_165
15719         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15720         sleep 5
15721
15722         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15723
15724         # 4096 / 64 = 64. Create twice as many entries.
15725         for ((i = 0; i < 128; i++)); do
15726                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15727                         error "cannot create file"
15728         done
15729
15730         sync
15731
15732         do_facet ost1 killall -TERM ofd_access_log_reader
15733         wait
15734         rc=$?
15735         if ((rc != 0)); then
15736                 error "ofd_access_log_reader exited with rc = '${rc}'"
15737         fi
15738
15739         unlinkmany  "${file}-%d" 128
15740 }
15741 run_test 165c "full ofd access logs do not block IOs"
15742
15743 oal_get_read_count() {
15744         local stats="$1"
15745
15746         # STATS lustre-OST0001 alr_read_count 1
15747
15748         do_facet ost1 cat "${stats}" |
15749         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15750              END { print count; }'
15751 }
15752
15753 oal_expect_read_count() {
15754         local stats="$1"
15755         local count
15756         local expect="$2"
15757
15758         # Ask ofd_access_log_reader to write stats.
15759         do_facet ost1 killall -USR1 ofd_access_log_reader
15760
15761         # Allow some time for things to happen.
15762         sleep 1
15763
15764         count=$(oal_get_read_count "${stats}")
15765         if ((count == expect)); then
15766                 return 0
15767         fi
15768
15769         error_noexit "bad read count, got ${count}, expected ${expect}"
15770         do_facet ost1 cat "${stats}" >&2
15771         exit 1
15772 }
15773
15774 test_165d() {
15775         local stats="/tmp/${tfile}.stats"
15776         local file="${DIR}/${tdir}/${tfile}"
15777         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15778
15779         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15780                 skip "OFD access log unsupported"
15781
15782         test_mkdir "${DIR}/${tdir}"
15783
15784         setup_165
15785         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15786         sleep 5
15787
15788         lfs setstripe -c 1 -i 0 "${file}"
15789
15790         do_facet ost1 lctl set_param "${param}=rw"
15791         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15792                 error "cannot create '${file}'"
15793         oal_expect_read_count "${stats}" 1
15794
15795         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15796                 error "cannot read '${file}'"
15797         oal_expect_read_count "${stats}" 2
15798
15799         do_facet ost1 lctl set_param "${param}=r"
15800         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15801                 error "cannot create '${file}'"
15802         oal_expect_read_count "${stats}" 2
15803
15804         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15805                 error "cannot read '${file}'"
15806         oal_expect_read_count "${stats}" 3
15807
15808         do_facet ost1 lctl set_param "${param}=w"
15809         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15810                 error "cannot create '${file}'"
15811         oal_expect_read_count "${stats}" 4
15812
15813         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15814                 error "cannot read '${file}'"
15815         oal_expect_read_count "${stats}" 4
15816
15817         do_facet ost1 lctl set_param "${param}=0"
15818         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15819                 error "cannot create '${file}'"
15820         oal_expect_read_count "${stats}" 4
15821
15822         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15823                 error "cannot read '${file}'"
15824         oal_expect_read_count "${stats}" 4
15825
15826         do_facet ost1 killall -TERM ofd_access_log_reader
15827         wait
15828         rc=$?
15829         if ((rc != 0)); then
15830                 error "ofd_access_log_reader exited with rc = '${rc}'"
15831         fi
15832 }
15833 run_test 165d "ofd_access_log mask works"
15834
15835 test_165e() {
15836         local stats="/tmp/${tfile}.stats"
15837         local file0="${DIR}/${tdir}-0/${tfile}"
15838         local file1="${DIR}/${tdir}-1/${tfile}"
15839
15840         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15841                 skip "OFD access log unsupported"
15842
15843         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15844
15845         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15846         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15847
15848         lfs setstripe -c 1 -i 0 "${file0}"
15849         lfs setstripe -c 1 -i 0 "${file1}"
15850
15851         setup_165
15852         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15853         sleep 5
15854
15855         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15856                 error "cannot create '${file0}'"
15857         sync
15858         oal_expect_read_count "${stats}" 0
15859
15860         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15861                 error "cannot create '${file1}'"
15862         sync
15863         oal_expect_read_count "${stats}" 1
15864
15865         do_facet ost1 killall -TERM ofd_access_log_reader
15866         wait
15867         rc=$?
15868         if ((rc != 0)); then
15869                 error "ofd_access_log_reader exited with rc = '${rc}'"
15870         fi
15871 }
15872 run_test 165e "ofd_access_log MDT index filter works"
15873
15874 test_165f() {
15875         local trace="/tmp/${tfile}.trace"
15876         local rc
15877         local count
15878
15879         setup_165
15880         do_facet ost1 timeout 60 ofd_access_log_reader \
15881                 --exit-on-close --debug=- --trace=- > "${trace}" &
15882         sleep 5
15883         stop ost1
15884
15885         wait
15886         rc=$?
15887
15888         if ((rc != 0)); then
15889                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15890                 cat "${trace}"
15891                 exit 1
15892         fi
15893 }
15894 run_test 165f "ofd_access_log_reader --exit-on-close works"
15895
15896 test_169() {
15897         # do directio so as not to populate the page cache
15898         log "creating a 10 Mb file"
15899         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15900                 error "multiop failed while creating a file"
15901         log "starting reads"
15902         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15903         log "truncating the file"
15904         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15905                 error "multiop failed while truncating the file"
15906         log "killing dd"
15907         kill %+ || true # reads might have finished
15908         echo "wait until dd is finished"
15909         wait
15910         log "removing the temporary file"
15911         rm -rf $DIR/$tfile || error "tmp file removal failed"
15912 }
15913 run_test 169 "parallel read and truncate should not deadlock"
15914
15915 test_170() {
15916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15917
15918         $LCTL clear     # bug 18514
15919         $LCTL debug_daemon start $TMP/${tfile}_log_good
15920         touch $DIR/$tfile
15921         $LCTL debug_daemon stop
15922         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15923                 error "sed failed to read log_good"
15924
15925         $LCTL debug_daemon start $TMP/${tfile}_log_good
15926         rm -rf $DIR/$tfile
15927         $LCTL debug_daemon stop
15928
15929         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15930                error "lctl df log_bad failed"
15931
15932         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15933         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15934
15935         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15936         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15937
15938         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15939                 error "bad_line good_line1 good_line2 are empty"
15940
15941         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15942         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15943         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15944
15945         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15946         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15947         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15948
15949         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15950                 error "bad_line_new good_line_new are empty"
15951
15952         local expected_good=$((good_line1 + good_line2*2))
15953
15954         rm -f $TMP/${tfile}*
15955         # LU-231, short malformed line may not be counted into bad lines
15956         if [ $bad_line -ne $bad_line_new ] &&
15957                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15958                 error "expected $bad_line bad lines, but got $bad_line_new"
15959                 return 1
15960         fi
15961
15962         if [ $expected_good -ne $good_line_new ]; then
15963                 error "expected $expected_good good lines, but got $good_line_new"
15964                 return 2
15965         fi
15966         true
15967 }
15968 run_test 170 "test lctl df to handle corrupted log ====================="
15969
15970 test_171() { # bug20592
15971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15972
15973         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15974         $LCTL set_param fail_loc=0x50e
15975         $LCTL set_param fail_val=3000
15976         multiop_bg_pause $DIR/$tfile O_s || true
15977         local MULTIPID=$!
15978         kill -USR1 $MULTIPID
15979         # cause log dump
15980         sleep 3
15981         wait $MULTIPID
15982         if dmesg | grep "recursive fault"; then
15983                 error "caught a recursive fault"
15984         fi
15985         $LCTL set_param fail_loc=0
15986         true
15987 }
15988 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15989
15990 # it would be good to share it with obdfilter-survey/iokit-libecho code
15991 setup_obdecho_osc () {
15992         local rc=0
15993         local ost_nid=$1
15994         local obdfilter_name=$2
15995         echo "Creating new osc for $obdfilter_name on $ost_nid"
15996         # make sure we can find loopback nid
15997         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15998
15999         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16000                            ${obdfilter_name}_osc_UUID || rc=2; }
16001         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16002                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16003         return $rc
16004 }
16005
16006 cleanup_obdecho_osc () {
16007         local obdfilter_name=$1
16008         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16009         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16010         return 0
16011 }
16012
16013 obdecho_test() {
16014         local OBD=$1
16015         local node=$2
16016         local pages=${3:-64}
16017         local rc=0
16018         local id
16019
16020         local count=10
16021         local obd_size=$(get_obd_size $node $OBD)
16022         local page_size=$(get_page_size $node)
16023         if [[ -n "$obd_size" ]]; then
16024                 local new_count=$((obd_size / (pages * page_size / 1024)))
16025                 [[ $new_count -ge $count ]] || count=$new_count
16026         fi
16027
16028         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16029         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16030                            rc=2; }
16031         if [ $rc -eq 0 ]; then
16032             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16033             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16034         fi
16035         echo "New object id is $id"
16036         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16037                            rc=4; }
16038         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16039                            "test_brw $count w v $pages $id" || rc=4; }
16040         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16041                            rc=4; }
16042         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16043                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16044         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16045                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16046         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16047         return $rc
16048 }
16049
16050 test_180a() {
16051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16052
16053         if ! [ -d /sys/fs/lustre/echo_client ] &&
16054            ! module_loaded obdecho; then
16055                 load_module obdecho/obdecho &&
16056                         stack_trap "rmmod obdecho" EXIT ||
16057                         error "unable to load obdecho on client"
16058         fi
16059
16060         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16061         local host=$($LCTL get_param -n osc.$osc.import |
16062                      awk '/current_connection:/ { print $2 }' )
16063         local target=$($LCTL get_param -n osc.$osc.import |
16064                        awk '/target:/ { print $2 }' )
16065         target=${target%_UUID}
16066
16067         if [ -n "$target" ]; then
16068                 setup_obdecho_osc $host $target &&
16069                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16070                         { error "obdecho setup failed with $?"; return; }
16071
16072                 obdecho_test ${target}_osc client ||
16073                         error "obdecho_test failed on ${target}_osc"
16074         else
16075                 $LCTL get_param osc.$osc.import
16076                 error "there is no osc.$osc.import target"
16077         fi
16078 }
16079 run_test 180a "test obdecho on osc"
16080
16081 test_180b() {
16082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16083         remote_ost_nodsh && skip "remote OST with nodsh"
16084
16085         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16086                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16087                 error "failed to load module obdecho"
16088
16089         local target=$(do_facet ost1 $LCTL dl |
16090                        awk '/obdfilter/ { print $4; exit; }')
16091
16092         if [ -n "$target" ]; then
16093                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16094         else
16095                 do_facet ost1 $LCTL dl
16096                 error "there is no obdfilter target on ost1"
16097         fi
16098 }
16099 run_test 180b "test obdecho directly on obdfilter"
16100
16101 test_180c() { # LU-2598
16102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16103         remote_ost_nodsh && skip "remote OST with nodsh"
16104         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16105                 skip "Need MDS version at least 2.4.0"
16106
16107         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16108                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16109                 error "failed to load module obdecho"
16110
16111         local target=$(do_facet ost1 $LCTL dl |
16112                        awk '/obdfilter/ { print $4; exit; }')
16113
16114         if [ -n "$target" ]; then
16115                 local pages=16384 # 64MB bulk I/O RPC size
16116
16117                 obdecho_test "$target" ost1 "$pages" ||
16118                         error "obdecho_test with pages=$pages failed with $?"
16119         else
16120                 do_facet ost1 $LCTL dl
16121                 error "there is no obdfilter target on ost1"
16122         fi
16123 }
16124 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16125
16126 test_181() { # bug 22177
16127         test_mkdir $DIR/$tdir
16128         # create enough files to index the directory
16129         createmany -o $DIR/$tdir/foobar 4000
16130         # print attributes for debug purpose
16131         lsattr -d .
16132         # open dir
16133         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16134         MULTIPID=$!
16135         # remove the files & current working dir
16136         unlinkmany $DIR/$tdir/foobar 4000
16137         rmdir $DIR/$tdir
16138         kill -USR1 $MULTIPID
16139         wait $MULTIPID
16140         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16141         return 0
16142 }
16143 run_test 181 "Test open-unlinked dir ========================"
16144
16145 test_182() {
16146         local fcount=1000
16147         local tcount=10
16148
16149         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16150
16151         $LCTL set_param mdc.*.rpc_stats=clear
16152
16153         for (( i = 0; i < $tcount; i++ )) ; do
16154                 mkdir $DIR/$tdir/$i
16155         done
16156
16157         for (( i = 0; i < $tcount; i++ )) ; do
16158                 createmany -o $DIR/$tdir/$i/f- $fcount &
16159         done
16160         wait
16161
16162         for (( i = 0; i < $tcount; i++ )) ; do
16163                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16164         done
16165         wait
16166
16167         $LCTL get_param mdc.*.rpc_stats
16168
16169         rm -rf $DIR/$tdir
16170 }
16171 run_test 182 "Test parallel modify metadata operations ================"
16172
16173 test_183() { # LU-2275
16174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16175         remote_mds_nodsh && skip "remote MDS with nodsh"
16176         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16177                 skip "Need MDS version at least 2.3.56"
16178
16179         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16180         echo aaa > $DIR/$tdir/$tfile
16181
16182 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16183         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16184
16185         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16186         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16187
16188         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16189
16190         # Flush negative dentry cache
16191         touch $DIR/$tdir/$tfile
16192
16193         # We are not checking for any leaked references here, they'll
16194         # become evident next time we do cleanup with module unload.
16195         rm -rf $DIR/$tdir
16196 }
16197 run_test 183 "No crash or request leak in case of strange dispositions ========"
16198
16199 # test suite 184 is for LU-2016, LU-2017
16200 test_184a() {
16201         check_swap_layouts_support
16202
16203         dir0=$DIR/$tdir/$testnum
16204         test_mkdir -p -c1 $dir0
16205         ref1=/etc/passwd
16206         ref2=/etc/group
16207         file1=$dir0/f1
16208         file2=$dir0/f2
16209         $LFS setstripe -c1 $file1
16210         cp $ref1 $file1
16211         $LFS setstripe -c2 $file2
16212         cp $ref2 $file2
16213         gen1=$($LFS getstripe -g $file1)
16214         gen2=$($LFS getstripe -g $file2)
16215
16216         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16217         gen=$($LFS getstripe -g $file1)
16218         [[ $gen1 != $gen ]] ||
16219                 "Layout generation on $file1 does not change"
16220         gen=$($LFS getstripe -g $file2)
16221         [[ $gen2 != $gen ]] ||
16222                 "Layout generation on $file2 does not change"
16223
16224         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16225         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16226
16227         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16228 }
16229 run_test 184a "Basic layout swap"
16230
16231 test_184b() {
16232         check_swap_layouts_support
16233
16234         dir0=$DIR/$tdir/$testnum
16235         mkdir -p $dir0 || error "creating dir $dir0"
16236         file1=$dir0/f1
16237         file2=$dir0/f2
16238         file3=$dir0/f3
16239         dir1=$dir0/d1
16240         dir2=$dir0/d2
16241         mkdir $dir1 $dir2
16242         $LFS setstripe -c1 $file1
16243         $LFS setstripe -c2 $file2
16244         $LFS setstripe -c1 $file3
16245         chown $RUNAS_ID $file3
16246         gen1=$($LFS getstripe -g $file1)
16247         gen2=$($LFS getstripe -g $file2)
16248
16249         $LFS swap_layouts $dir1 $dir2 &&
16250                 error "swap of directories layouts should fail"
16251         $LFS swap_layouts $dir1 $file1 &&
16252                 error "swap of directory and file layouts should fail"
16253         $RUNAS $LFS swap_layouts $file1 $file2 &&
16254                 error "swap of file we cannot write should fail"
16255         $LFS swap_layouts $file1 $file3 &&
16256                 error "swap of file with different owner should fail"
16257         /bin/true # to clear error code
16258 }
16259 run_test 184b "Forbidden layout swap (will generate errors)"
16260
16261 test_184c() {
16262         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16263         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16264         check_swap_layouts_support
16265         check_swap_layout_no_dom $DIR
16266
16267         local dir0=$DIR/$tdir/$testnum
16268         mkdir -p $dir0 || error "creating dir $dir0"
16269
16270         local ref1=$dir0/ref1
16271         local ref2=$dir0/ref2
16272         local file1=$dir0/file1
16273         local file2=$dir0/file2
16274         # create a file large enough for the concurrent test
16275         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16276         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16277         echo "ref file size: ref1($(stat -c %s $ref1))," \
16278              "ref2($(stat -c %s $ref2))"
16279
16280         cp $ref2 $file2
16281         dd if=$ref1 of=$file1 bs=16k &
16282         local DD_PID=$!
16283
16284         # Make sure dd starts to copy file, but wait at most 5 seconds
16285         local loops=0
16286         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16287
16288         $LFS swap_layouts $file1 $file2
16289         local rc=$?
16290         wait $DD_PID
16291         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16292         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16293
16294         # how many bytes copied before swapping layout
16295         local copied=$(stat -c %s $file2)
16296         local remaining=$(stat -c %s $ref1)
16297         remaining=$((remaining - copied))
16298         echo "Copied $copied bytes before swapping layout..."
16299
16300         cmp -n $copied $file1 $ref2 | grep differ &&
16301                 error "Content mismatch [0, $copied) of ref2 and file1"
16302         cmp -n $copied $file2 $ref1 ||
16303                 error "Content mismatch [0, $copied) of ref1 and file2"
16304         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16305                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16306
16307         # clean up
16308         rm -f $ref1 $ref2 $file1 $file2
16309 }
16310 run_test 184c "Concurrent write and layout swap"
16311
16312 test_184d() {
16313         check_swap_layouts_support
16314         check_swap_layout_no_dom $DIR
16315         [ -z "$(which getfattr 2>/dev/null)" ] &&
16316                 skip_env "no getfattr command"
16317
16318         local file1=$DIR/$tdir/$tfile-1
16319         local file2=$DIR/$tdir/$tfile-2
16320         local file3=$DIR/$tdir/$tfile-3
16321         local lovea1
16322         local lovea2
16323
16324         mkdir -p $DIR/$tdir
16325         touch $file1 || error "create $file1 failed"
16326         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16327                 error "create $file2 failed"
16328         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16329                 error "create $file3 failed"
16330         lovea1=$(get_layout_param $file1)
16331
16332         $LFS swap_layouts $file2 $file3 ||
16333                 error "swap $file2 $file3 layouts failed"
16334         $LFS swap_layouts $file1 $file2 ||
16335                 error "swap $file1 $file2 layouts failed"
16336
16337         lovea2=$(get_layout_param $file2)
16338         echo "$lovea1"
16339         echo "$lovea2"
16340         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16341
16342         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16343         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16344 }
16345 run_test 184d "allow stripeless layouts swap"
16346
16347 test_184e() {
16348         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16349                 skip "Need MDS version at least 2.6.94"
16350         check_swap_layouts_support
16351         check_swap_layout_no_dom $DIR
16352         [ -z "$(which getfattr 2>/dev/null)" ] &&
16353                 skip_env "no getfattr command"
16354
16355         local file1=$DIR/$tdir/$tfile-1
16356         local file2=$DIR/$tdir/$tfile-2
16357         local file3=$DIR/$tdir/$tfile-3
16358         local lovea
16359
16360         mkdir -p $DIR/$tdir
16361         touch $file1 || error "create $file1 failed"
16362         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16363                 error "create $file2 failed"
16364         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16365                 error "create $file3 failed"
16366
16367         $LFS swap_layouts $file1 $file2 ||
16368                 error "swap $file1 $file2 layouts failed"
16369
16370         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16371         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16372
16373         echo 123 > $file1 || error "Should be able to write into $file1"
16374
16375         $LFS swap_layouts $file1 $file3 ||
16376                 error "swap $file1 $file3 layouts failed"
16377
16378         echo 123 > $file1 || error "Should be able to write into $file1"
16379
16380         rm -rf $file1 $file2 $file3
16381 }
16382 run_test 184e "Recreate layout after stripeless layout swaps"
16383
16384 test_184f() {
16385         # Create a file with name longer than sizeof(struct stat) ==
16386         # 144 to see if we can get chars from the file name to appear
16387         # in the returned striping. Note that 'f' == 0x66.
16388         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16389
16390         mkdir -p $DIR/$tdir
16391         mcreate $DIR/$tdir/$file
16392         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16393                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16394         fi
16395 }
16396 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16397
16398 test_185() { # LU-2441
16399         # LU-3553 - no volatile file support in old servers
16400         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16401                 skip "Need MDS version at least 2.3.60"
16402
16403         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16404         touch $DIR/$tdir/spoo
16405         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16406         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16407                 error "cannot create/write a volatile file"
16408         [ "$FILESET" == "" ] &&
16409         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16410                 error "FID is still valid after close"
16411
16412         multiop_bg_pause $DIR/$tdir vVw4096_c
16413         local multi_pid=$!
16414
16415         local OLD_IFS=$IFS
16416         IFS=":"
16417         local fidv=($fid)
16418         IFS=$OLD_IFS
16419         # assume that the next FID for this client is sequential, since stdout
16420         # is unfortunately eaten by multiop_bg_pause
16421         local n=$((${fidv[1]} + 1))
16422         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16423         if [ "$FILESET" == "" ]; then
16424                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16425                         error "FID is missing before close"
16426         fi
16427         kill -USR1 $multi_pid
16428         # 1 second delay, so if mtime change we will see it
16429         sleep 1
16430         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16431         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16432 }
16433 run_test 185 "Volatile file support"
16434
16435 function create_check_volatile() {
16436         local idx=$1
16437         local tgt
16438
16439         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16440         local PID=$!
16441         sleep 1
16442         local FID=$(cat /tmp/${tfile}.fid)
16443         [ "$FID" == "" ] && error "can't get FID for volatile"
16444         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16445         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16446         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16447         kill -USR1 $PID
16448         wait
16449         sleep 1
16450         cancel_lru_locks mdc # flush opencache
16451         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16452         return 0
16453 }
16454
16455 test_185a(){
16456         # LU-12516 - volatile creation via .lustre
16457         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16458                 skip "Need MDS version at least 2.3.55"
16459
16460         create_check_volatile 0
16461         [ $MDSCOUNT -lt 2 ] && return 0
16462
16463         # DNE case
16464         create_check_volatile 1
16465
16466         return 0
16467 }
16468 run_test 185a "Volatile file creation in .lustre/fid/"
16469
16470 test_187a() {
16471         remote_mds_nodsh && skip "remote MDS with nodsh"
16472         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16473                 skip "Need MDS version at least 2.3.0"
16474
16475         local dir0=$DIR/$tdir/$testnum
16476         mkdir -p $dir0 || error "creating dir $dir0"
16477
16478         local file=$dir0/file1
16479         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16480         local dv1=$($LFS data_version $file)
16481         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16482         local dv2=$($LFS data_version $file)
16483         [[ $dv1 != $dv2 ]] ||
16484                 error "data version did not change on write $dv1 == $dv2"
16485
16486         # clean up
16487         rm -f $file1
16488 }
16489 run_test 187a "Test data version change"
16490
16491 test_187b() {
16492         remote_mds_nodsh && skip "remote MDS with nodsh"
16493         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16494                 skip "Need MDS version at least 2.3.0"
16495
16496         local dir0=$DIR/$tdir/$testnum
16497         mkdir -p $dir0 || error "creating dir $dir0"
16498
16499         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16500         [[ ${DV[0]} != ${DV[1]} ]] ||
16501                 error "data version did not change on write"\
16502                       " ${DV[0]} == ${DV[1]}"
16503
16504         # clean up
16505         rm -f $file1
16506 }
16507 run_test 187b "Test data version change on volatile file"
16508
16509 test_200() {
16510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16511         remote_mgs_nodsh && skip "remote MGS with nodsh"
16512         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16513
16514         local POOL=${POOL:-cea1}
16515         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16516         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16517         # Pool OST targets
16518         local first_ost=0
16519         local last_ost=$(($OSTCOUNT - 1))
16520         local ost_step=2
16521         local ost_list=$(seq $first_ost $ost_step $last_ost)
16522         local ost_range="$first_ost $last_ost $ost_step"
16523         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16524         local file_dir=$POOL_ROOT/file_tst
16525         local subdir=$test_path/subdir
16526         local rc=0
16527
16528         while : ; do
16529                 # former test_200a test_200b
16530                 pool_add $POOL                          || { rc=$? ; break; }
16531                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16532                 # former test_200c test_200d
16533                 mkdir -p $test_path
16534                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16535                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16536                 mkdir -p $subdir
16537                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16538                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16539                                                         || { rc=$? ; break; }
16540                 # former test_200e test_200f
16541                 local files=$((OSTCOUNT*3))
16542                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16543                                                         || { rc=$? ; break; }
16544                 pool_create_files $POOL $file_dir $files "$ost_list" \
16545                                                         || { rc=$? ; break; }
16546                 # former test_200g test_200h
16547                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16548                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16549
16550                 # former test_201a test_201b test_201c
16551                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16552
16553                 local f=$test_path/$tfile
16554                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16555                 pool_remove $POOL $f                    || { rc=$? ; break; }
16556                 break
16557         done
16558
16559         destroy_test_pools
16560
16561         return $rc
16562 }
16563 run_test 200 "OST pools"
16564
16565 # usage: default_attr <count | size | offset>
16566 default_attr() {
16567         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16568 }
16569
16570 # usage: check_default_stripe_attr
16571 check_default_stripe_attr() {
16572         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16573         case $1 in
16574         --stripe-count|-c)
16575                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16576         --stripe-size|-S)
16577                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16578         --stripe-index|-i)
16579                 EXPECTED=-1;;
16580         *)
16581                 error "unknown getstripe attr '$1'"
16582         esac
16583
16584         [ $ACTUAL == $EXPECTED ] ||
16585                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16586 }
16587
16588 test_204a() {
16589         test_mkdir $DIR/$tdir
16590         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16591
16592         check_default_stripe_attr --stripe-count
16593         check_default_stripe_attr --stripe-size
16594         check_default_stripe_attr --stripe-index
16595 }
16596 run_test 204a "Print default stripe attributes"
16597
16598 test_204b() {
16599         test_mkdir $DIR/$tdir
16600         $LFS setstripe --stripe-count 1 $DIR/$tdir
16601
16602         check_default_stripe_attr --stripe-size
16603         check_default_stripe_attr --stripe-index
16604 }
16605 run_test 204b "Print default stripe size and offset"
16606
16607 test_204c() {
16608         test_mkdir $DIR/$tdir
16609         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16610
16611         check_default_stripe_attr --stripe-count
16612         check_default_stripe_attr --stripe-index
16613 }
16614 run_test 204c "Print default stripe count and offset"
16615
16616 test_204d() {
16617         test_mkdir $DIR/$tdir
16618         $LFS setstripe --stripe-index 0 $DIR/$tdir
16619
16620         check_default_stripe_attr --stripe-count
16621         check_default_stripe_attr --stripe-size
16622 }
16623 run_test 204d "Print default stripe count and size"
16624
16625 test_204e() {
16626         test_mkdir $DIR/$tdir
16627         $LFS setstripe -d $DIR/$tdir
16628
16629         check_default_stripe_attr --stripe-count --raw
16630         check_default_stripe_attr --stripe-size --raw
16631         check_default_stripe_attr --stripe-index --raw
16632 }
16633 run_test 204e "Print raw stripe attributes"
16634
16635 test_204f() {
16636         test_mkdir $DIR/$tdir
16637         $LFS setstripe --stripe-count 1 $DIR/$tdir
16638
16639         check_default_stripe_attr --stripe-size --raw
16640         check_default_stripe_attr --stripe-index --raw
16641 }
16642 run_test 204f "Print raw stripe size and offset"
16643
16644 test_204g() {
16645         test_mkdir $DIR/$tdir
16646         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16647
16648         check_default_stripe_attr --stripe-count --raw
16649         check_default_stripe_attr --stripe-index --raw
16650 }
16651 run_test 204g "Print raw stripe count and offset"
16652
16653 test_204h() {
16654         test_mkdir $DIR/$tdir
16655         $LFS setstripe --stripe-index 0 $DIR/$tdir
16656
16657         check_default_stripe_attr --stripe-count --raw
16658         check_default_stripe_attr --stripe-size --raw
16659 }
16660 run_test 204h "Print raw stripe count and size"
16661
16662 # Figure out which job scheduler is being used, if any,
16663 # or use a fake one
16664 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16665         JOBENV=SLURM_JOB_ID
16666 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16667         JOBENV=LSB_JOBID
16668 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16669         JOBENV=PBS_JOBID
16670 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16671         JOBENV=LOADL_STEP_ID
16672 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16673         JOBENV=JOB_ID
16674 else
16675         $LCTL list_param jobid_name > /dev/null 2>&1
16676         if [ $? -eq 0 ]; then
16677                 JOBENV=nodelocal
16678         else
16679                 JOBENV=FAKE_JOBID
16680         fi
16681 fi
16682 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16683
16684 verify_jobstats() {
16685         local cmd=($1)
16686         shift
16687         local facets="$@"
16688
16689 # we don't really need to clear the stats for this test to work, since each
16690 # command has a unique jobid, but it makes debugging easier if needed.
16691 #       for facet in $facets; do
16692 #               local dev=$(convert_facet2label $facet)
16693 #               # clear old jobstats
16694 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16695 #       done
16696
16697         # use a new JobID for each test, or we might see an old one
16698         [ "$JOBENV" = "FAKE_JOBID" ] &&
16699                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16700
16701         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16702
16703         [ "$JOBENV" = "nodelocal" ] && {
16704                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16705                 $LCTL set_param jobid_name=$FAKE_JOBID
16706                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16707         }
16708
16709         log "Test: ${cmd[*]}"
16710         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16711
16712         if [ $JOBENV = "FAKE_JOBID" ]; then
16713                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16714         else
16715                 ${cmd[*]}
16716         fi
16717
16718         # all files are created on OST0000
16719         for facet in $facets; do
16720                 local stats="*.$(convert_facet2label $facet).job_stats"
16721
16722                 # strip out libtool wrappers for in-tree executables
16723                 if [ $(do_facet $facet lctl get_param $stats |
16724                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16725                         do_facet $facet lctl get_param $stats
16726                         error "No jobstats for $JOBVAL found on $facet::$stats"
16727                 fi
16728         done
16729 }
16730
16731 jobstats_set() {
16732         local new_jobenv=$1
16733
16734         set_persistent_param_and_check client "jobid_var" \
16735                 "$FSNAME.sys.jobid_var" $new_jobenv
16736 }
16737
16738 test_205a() { # Job stats
16739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16740         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16741                 skip "Need MDS version with at least 2.7.1"
16742         remote_mgs_nodsh && skip "remote MGS with nodsh"
16743         remote_mds_nodsh && skip "remote MDS with nodsh"
16744         remote_ost_nodsh && skip "remote OST with nodsh"
16745         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16746                 skip "Server doesn't support jobstats"
16747         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16748
16749         local old_jobenv=$($LCTL get_param -n jobid_var)
16750         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16751
16752         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16753                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16754         else
16755                 stack_trap "do_facet mgs $PERM_CMD \
16756                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16757         fi
16758         changelog_register
16759
16760         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16761                                 mdt.*.job_cleanup_interval | head -n 1)
16762         local new_interval=5
16763         do_facet $SINGLEMDS \
16764                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16765         stack_trap "do_facet $SINGLEMDS \
16766                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16767         local start=$SECONDS
16768
16769         local cmd
16770         # mkdir
16771         cmd="mkdir $DIR/$tdir"
16772         verify_jobstats "$cmd" "$SINGLEMDS"
16773         # rmdir
16774         cmd="rmdir $DIR/$tdir"
16775         verify_jobstats "$cmd" "$SINGLEMDS"
16776         # mkdir on secondary MDT
16777         if [ $MDSCOUNT -gt 1 ]; then
16778                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16779                 verify_jobstats "$cmd" "mds2"
16780         fi
16781         # mknod
16782         cmd="mknod $DIR/$tfile c 1 3"
16783         verify_jobstats "$cmd" "$SINGLEMDS"
16784         # unlink
16785         cmd="rm -f $DIR/$tfile"
16786         verify_jobstats "$cmd" "$SINGLEMDS"
16787         # create all files on OST0000 so verify_jobstats can find OST stats
16788         # open & close
16789         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16790         verify_jobstats "$cmd" "$SINGLEMDS"
16791         # setattr
16792         cmd="touch $DIR/$tfile"
16793         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16794         # write
16795         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16796         verify_jobstats "$cmd" "ost1"
16797         # read
16798         cancel_lru_locks osc
16799         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16800         verify_jobstats "$cmd" "ost1"
16801         # truncate
16802         cmd="$TRUNCATE $DIR/$tfile 0"
16803         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16804         # rename
16805         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16806         verify_jobstats "$cmd" "$SINGLEMDS"
16807         # jobstats expiry - sleep until old stats should be expired
16808         local left=$((new_interval + 5 - (SECONDS - start)))
16809         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16810                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16811                         "0" $left
16812         cmd="mkdir $DIR/$tdir.expire"
16813         verify_jobstats "$cmd" "$SINGLEMDS"
16814         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16815             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16816
16817         # Ensure that jobid are present in changelog (if supported by MDS)
16818         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16819                 changelog_dump | tail -10
16820                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16821                 [ $jobids -eq 9 ] ||
16822                         error "Wrong changelog jobid count $jobids != 9"
16823
16824                 # LU-5862
16825                 JOBENV="disable"
16826                 jobstats_set $JOBENV
16827                 touch $DIR/$tfile
16828                 changelog_dump | grep $tfile
16829                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16830                 [ $jobids -eq 0 ] ||
16831                         error "Unexpected jobids when jobid_var=$JOBENV"
16832         fi
16833
16834         # test '%j' access to environment variable - if supported
16835         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16836                 JOBENV="JOBCOMPLEX"
16837                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16838
16839                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16840         fi
16841
16842         # test '%j' access to per-session jobid - if supported
16843         if lctl list_param jobid_this_session > /dev/null 2>&1
16844         then
16845                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16846                 lctl set_param jobid_this_session=$USER
16847
16848                 JOBENV="JOBCOMPLEX"
16849                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16850
16851                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16852         fi
16853 }
16854 run_test 205a "Verify job stats"
16855
16856 # LU-13117, LU-13597
16857 test_205b() {
16858         job_stats="mdt.*.job_stats"
16859         $LCTL set_param $job_stats=clear
16860         # Setting jobid_var to USER might not be supported
16861         $LCTL set_param jobid_var=USER || true
16862         $LCTL set_param jobid_name="%e.%u"
16863         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16864         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16865                 grep "job_id:.*foolish" &&
16866                         error "Unexpected jobid found"
16867         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16868                 grep "open:.*min.*max.*sum" ||
16869                         error "wrong job_stats format found"
16870 }
16871 run_test 205b "Verify job stats jobid and output format"
16872
16873 # LU-13733
16874 test_205c() {
16875         $LCTL set_param llite.*.stats=0
16876         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16877         $LCTL get_param llite.*.stats
16878         $LCTL get_param llite.*.stats | grep \
16879                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16880                         error "wrong client stats format found"
16881 }
16882 run_test 205c "Verify client stats format"
16883
16884 # LU-1480, LU-1773 and LU-1657
16885 test_206() {
16886         mkdir -p $DIR/$tdir
16887         $LFS setstripe -c -1 $DIR/$tdir
16888 #define OBD_FAIL_LOV_INIT 0x1403
16889         $LCTL set_param fail_loc=0xa0001403
16890         $LCTL set_param fail_val=1
16891         touch $DIR/$tdir/$tfile || true
16892 }
16893 run_test 206 "fail lov_init_raid0() doesn't lbug"
16894
16895 test_207a() {
16896         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16897         local fsz=`stat -c %s $DIR/$tfile`
16898         cancel_lru_locks mdc
16899
16900         # do not return layout in getattr intent
16901 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16902         $LCTL set_param fail_loc=0x170
16903         local sz=`stat -c %s $DIR/$tfile`
16904
16905         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16906
16907         rm -rf $DIR/$tfile
16908 }
16909 run_test 207a "can refresh layout at glimpse"
16910
16911 test_207b() {
16912         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16913         local cksum=`md5sum $DIR/$tfile`
16914         local fsz=`stat -c %s $DIR/$tfile`
16915         cancel_lru_locks mdc
16916         cancel_lru_locks osc
16917
16918         # do not return layout in getattr intent
16919 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16920         $LCTL set_param fail_loc=0x171
16921
16922         # it will refresh layout after the file is opened but before read issues
16923         echo checksum is "$cksum"
16924         echo "$cksum" |md5sum -c --quiet || error "file differs"
16925
16926         rm -rf $DIR/$tfile
16927 }
16928 run_test 207b "can refresh layout at open"
16929
16930 test_208() {
16931         # FIXME: in this test suite, only RD lease is used. This is okay
16932         # for now as only exclusive open is supported. After generic lease
16933         # is done, this test suite should be revised. - Jinshan
16934
16935         remote_mds_nodsh && skip "remote MDS with nodsh"
16936         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16937                 skip "Need MDS version at least 2.4.52"
16938
16939         echo "==== test 1: verify get lease work"
16940         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16941
16942         echo "==== test 2: verify lease can be broken by upcoming open"
16943         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16944         local PID=$!
16945         sleep 1
16946
16947         $MULTIOP $DIR/$tfile oO_RDONLY:c
16948         kill -USR1 $PID && wait $PID || error "break lease error"
16949
16950         echo "==== test 3: verify lease can't be granted if an open already exists"
16951         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16952         local PID=$!
16953         sleep 1
16954
16955         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16956         kill -USR1 $PID && wait $PID || error "open file error"
16957
16958         echo "==== test 4: lease can sustain over recovery"
16959         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16960         PID=$!
16961         sleep 1
16962
16963         fail mds1
16964
16965         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16966
16967         echo "==== test 5: lease broken can't be regained by replay"
16968         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16969         PID=$!
16970         sleep 1
16971
16972         # open file to break lease and then recovery
16973         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16974         fail mds1
16975
16976         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16977
16978         rm -f $DIR/$tfile
16979 }
16980 run_test 208 "Exclusive open"
16981
16982 test_209() {
16983         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16984                 skip_env "must have disp_stripe"
16985
16986         touch $DIR/$tfile
16987         sync; sleep 5; sync;
16988
16989         echo 3 > /proc/sys/vm/drop_caches
16990         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16991                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16992         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16993
16994         # open/close 500 times
16995         for i in $(seq 500); do
16996                 cat $DIR/$tfile
16997         done
16998
16999         echo 3 > /proc/sys/vm/drop_caches
17000         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17001                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17002         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17003
17004         echo "before: $req_before, after: $req_after"
17005         [ $((req_after - req_before)) -ge 300 ] &&
17006                 error "open/close requests are not freed"
17007         return 0
17008 }
17009 run_test 209 "read-only open/close requests should be freed promptly"
17010
17011 test_210() {
17012         local pid
17013
17014         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17015         pid=$!
17016         sleep 1
17017
17018         $LFS getstripe $DIR/$tfile
17019         kill -USR1 $pid
17020         wait $pid || error "multiop failed"
17021
17022         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17023         pid=$!
17024         sleep 1
17025
17026         $LFS getstripe $DIR/$tfile
17027         kill -USR1 $pid
17028         wait $pid || error "multiop failed"
17029 }
17030 run_test 210 "lfs getstripe does not break leases"
17031
17032 test_212() {
17033         size=`date +%s`
17034         size=$((size % 8192 + 1))
17035         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17036         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17037         rm -f $DIR/f212 $DIR/f212.xyz
17038 }
17039 run_test 212 "Sendfile test ============================================"
17040
17041 test_213() {
17042         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17043         cancel_lru_locks osc
17044         lctl set_param fail_loc=0x8000040f
17045         # generate a read lock
17046         cat $DIR/$tfile > /dev/null
17047         # write to the file, it will try to cancel the above read lock.
17048         cat /etc/hosts >> $DIR/$tfile
17049 }
17050 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17051
17052 test_214() { # for bug 20133
17053         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17054         for (( i=0; i < 340; i++ )) ; do
17055                 touch $DIR/$tdir/d214c/a$i
17056         done
17057
17058         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17059         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17060         ls $DIR/d214c || error "ls $DIR/d214c failed"
17061         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17062         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17063 }
17064 run_test 214 "hash-indexed directory test - bug 20133"
17065
17066 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17067 create_lnet_proc_files() {
17068         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17069 }
17070
17071 # counterpart of create_lnet_proc_files
17072 remove_lnet_proc_files() {
17073         rm -f $TMP/lnet_$1.sys
17074 }
17075
17076 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17077 # 3rd arg as regexp for body
17078 check_lnet_proc_stats() {
17079         local l=$(cat "$TMP/lnet_$1" |wc -l)
17080         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17081
17082         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17083 }
17084
17085 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17086 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17087 # optional and can be regexp for 2nd line (lnet.routes case)
17088 check_lnet_proc_entry() {
17089         local blp=2          # blp stands for 'position of 1st line of body'
17090         [ -z "$5" ] || blp=3 # lnet.routes case
17091
17092         local l=$(cat "$TMP/lnet_$1" |wc -l)
17093         # subtracting one from $blp because the body can be empty
17094         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17095
17096         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17097                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17098
17099         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17100                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17101
17102         # bail out if any unexpected line happened
17103         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17104         [ "$?" != 0 ] || error "$2 misformatted"
17105 }
17106
17107 test_215() { # for bugs 18102, 21079, 21517
17108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17109
17110         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17111         local P='[1-9][0-9]*'           # positive numeric
17112         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17113         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17114         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17115         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17116
17117         local L1 # regexp for 1st line
17118         local L2 # regexp for 2nd line (optional)
17119         local BR # regexp for the rest (body)
17120
17121         # lnet.stats should look as 11 space-separated non-negative numerics
17122         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17123         create_lnet_proc_files "stats"
17124         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17125         remove_lnet_proc_files "stats"
17126
17127         # lnet.routes should look like this:
17128         # Routing disabled/enabled
17129         # net hops priority state router
17130         # where net is a string like tcp0, hops > 0, priority >= 0,
17131         # state is up/down,
17132         # router is a string like 192.168.1.1@tcp2
17133         L1="^Routing (disabled|enabled)$"
17134         L2="^net +hops +priority +state +router$"
17135         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17136         create_lnet_proc_files "routes"
17137         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17138         remove_lnet_proc_files "routes"
17139
17140         # lnet.routers should look like this:
17141         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17142         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17143         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17144         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17145         L1="^ref +rtr_ref +alive +router$"
17146         BR="^$P +$P +(up|down) +$NID$"
17147         create_lnet_proc_files "routers"
17148         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17149         remove_lnet_proc_files "routers"
17150
17151         # lnet.peers should look like this:
17152         # nid refs state last max rtr min tx min queue
17153         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17154         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17155         # numeric (0 or >0 or <0), queue >= 0.
17156         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17157         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17158         create_lnet_proc_files "peers"
17159         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17160         remove_lnet_proc_files "peers"
17161
17162         # lnet.buffers  should look like this:
17163         # pages count credits min
17164         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17165         L1="^pages +count +credits +min$"
17166         BR="^ +$N +$N +$I +$I$"
17167         create_lnet_proc_files "buffers"
17168         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17169         remove_lnet_proc_files "buffers"
17170
17171         # lnet.nis should look like this:
17172         # nid status alive refs peer rtr max tx min
17173         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17174         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17175         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17176         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17177         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17178         create_lnet_proc_files "nis"
17179         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17180         remove_lnet_proc_files "nis"
17181
17182         # can we successfully write to lnet.stats?
17183         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17184 }
17185 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17186
17187 test_216() { # bug 20317
17188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17189         remote_ost_nodsh && skip "remote OST with nodsh"
17190
17191         local node
17192         local facets=$(get_facets OST)
17193         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17194
17195         save_lustre_params client "osc.*.contention_seconds" > $p
17196         save_lustre_params $facets \
17197                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17198         save_lustre_params $facets \
17199                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17200         save_lustre_params $facets \
17201                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17202         clear_stats osc.*.osc_stats
17203
17204         # agressive lockless i/o settings
17205         do_nodes $(comma_list $(osts_nodes)) \
17206                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17207                         ldlm.namespaces.filter-*.contended_locks=0 \
17208                         ldlm.namespaces.filter-*.contention_seconds=60"
17209         lctl set_param -n osc.*.contention_seconds=60
17210
17211         $DIRECTIO write $DIR/$tfile 0 10 4096
17212         $CHECKSTAT -s 40960 $DIR/$tfile
17213
17214         # disable lockless i/o
17215         do_nodes $(comma_list $(osts_nodes)) \
17216                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17217                         ldlm.namespaces.filter-*.contended_locks=32 \
17218                         ldlm.namespaces.filter-*.contention_seconds=0"
17219         lctl set_param -n osc.*.contention_seconds=0
17220         clear_stats osc.*.osc_stats
17221
17222         dd if=/dev/zero of=$DIR/$tfile count=0
17223         $CHECKSTAT -s 0 $DIR/$tfile
17224
17225         restore_lustre_params <$p
17226         rm -f $p
17227         rm $DIR/$tfile
17228 }
17229 run_test 216 "check lockless direct write updates file size and kms correctly"
17230
17231 test_217() { # bug 22430
17232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17233
17234         local node
17235         local nid
17236
17237         for node in $(nodes_list); do
17238                 nid=$(host_nids_address $node $NETTYPE)
17239                 if [[ $nid = *-* ]] ; then
17240                         echo "lctl ping $(h2nettype $nid)"
17241                         lctl ping $(h2nettype $nid)
17242                 else
17243                         echo "skipping $node (no hyphen detected)"
17244                 fi
17245         done
17246 }
17247 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17248
17249 test_218() {
17250        # do directio so as not to populate the page cache
17251        log "creating a 10 Mb file"
17252        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17253        log "starting reads"
17254        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17255        log "truncating the file"
17256        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17257        log "killing dd"
17258        kill %+ || true # reads might have finished
17259        echo "wait until dd is finished"
17260        wait
17261        log "removing the temporary file"
17262        rm -rf $DIR/$tfile || error "tmp file removal failed"
17263 }
17264 run_test 218 "parallel read and truncate should not deadlock"
17265
17266 test_219() {
17267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17268
17269         # write one partial page
17270         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17271         # set no grant so vvp_io_commit_write will do sync write
17272         $LCTL set_param fail_loc=0x411
17273         # write a full page at the end of file
17274         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17275
17276         $LCTL set_param fail_loc=0
17277         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17278         $LCTL set_param fail_loc=0x411
17279         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17280
17281         # LU-4201
17282         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17283         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17284 }
17285 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17286
17287 test_220() { #LU-325
17288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17289         remote_ost_nodsh && skip "remote OST with nodsh"
17290         remote_mds_nodsh && skip "remote MDS with nodsh"
17291         remote_mgs_nodsh && skip "remote MGS with nodsh"
17292
17293         local OSTIDX=0
17294
17295         # create on MDT0000 so the last_id and next_id are correct
17296         mkdir $DIR/$tdir
17297         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17298         OST=${OST%_UUID}
17299
17300         # on the mdt's osc
17301         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17302         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17303                         osp.$mdtosc_proc1.prealloc_last_id)
17304         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17305                         osp.$mdtosc_proc1.prealloc_next_id)
17306
17307         $LFS df -i
17308
17309         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17310         #define OBD_FAIL_OST_ENOINO              0x229
17311         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17312         create_pool $FSNAME.$TESTNAME || return 1
17313         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17314
17315         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17316
17317         MDSOBJS=$((last_id - next_id))
17318         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17319
17320         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17321         echo "OST still has $count kbytes free"
17322
17323         echo "create $MDSOBJS files @next_id..."
17324         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17325
17326         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17327                         osp.$mdtosc_proc1.prealloc_last_id)
17328         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17329                         osp.$mdtosc_proc1.prealloc_next_id)
17330
17331         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17332         $LFS df -i
17333
17334         echo "cleanup..."
17335
17336         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17337         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17338
17339         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17340                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17341         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17342                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17343         echo "unlink $MDSOBJS files @$next_id..."
17344         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17345 }
17346 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17347
17348 test_221() {
17349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17350
17351         dd if=`which date` of=$MOUNT/date oflag=sync
17352         chmod +x $MOUNT/date
17353
17354         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17355         $LCTL set_param fail_loc=0x80001401
17356
17357         $MOUNT/date > /dev/null
17358         rm -f $MOUNT/date
17359 }
17360 run_test 221 "make sure fault and truncate race to not cause OOM"
17361
17362 test_222a () {
17363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17364
17365         rm -rf $DIR/$tdir
17366         test_mkdir $DIR/$tdir
17367         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17368         createmany -o $DIR/$tdir/$tfile 10
17369         cancel_lru_locks mdc
17370         cancel_lru_locks osc
17371         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17372         $LCTL set_param fail_loc=0x31a
17373         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17374         $LCTL set_param fail_loc=0
17375         rm -r $DIR/$tdir
17376 }
17377 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17378
17379 test_222b () {
17380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17381
17382         rm -rf $DIR/$tdir
17383         test_mkdir $DIR/$tdir
17384         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17385         createmany -o $DIR/$tdir/$tfile 10
17386         cancel_lru_locks mdc
17387         cancel_lru_locks osc
17388         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17389         $LCTL set_param fail_loc=0x31a
17390         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17391         $LCTL set_param fail_loc=0
17392 }
17393 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17394
17395 test_223 () {
17396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17397
17398         rm -rf $DIR/$tdir
17399         test_mkdir $DIR/$tdir
17400         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17401         createmany -o $DIR/$tdir/$tfile 10
17402         cancel_lru_locks mdc
17403         cancel_lru_locks osc
17404         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17405         $LCTL set_param fail_loc=0x31b
17406         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17407         $LCTL set_param fail_loc=0
17408         rm -r $DIR/$tdir
17409 }
17410 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17411
17412 test_224a() { # LU-1039, MRP-303
17413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17414
17415         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17416         $LCTL set_param fail_loc=0x508
17417         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17418         $LCTL set_param fail_loc=0
17419         df $DIR
17420 }
17421 run_test 224a "Don't panic on bulk IO failure"
17422
17423 test_224b() { # LU-1039, MRP-303
17424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17425
17426         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17427         cancel_lru_locks osc
17428         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17429         $LCTL set_param fail_loc=0x515
17430         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17431         $LCTL set_param fail_loc=0
17432         df $DIR
17433 }
17434 run_test 224b "Don't panic on bulk IO failure"
17435
17436 test_224c() { # LU-6441
17437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17438         remote_mds_nodsh && skip "remote MDS with nodsh"
17439
17440         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17441         save_writethrough $p
17442         set_cache writethrough on
17443
17444         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17445         local at_max=$($LCTL get_param -n at_max)
17446         local timeout=$($LCTL get_param -n timeout)
17447         local test_at="at_max"
17448         local param_at="$FSNAME.sys.at_max"
17449         local test_timeout="timeout"
17450         local param_timeout="$FSNAME.sys.timeout"
17451
17452         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17453
17454         set_persistent_param_and_check client "$test_at" "$param_at" 0
17455         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17456
17457         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17458         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17459         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17460         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17461         sync
17462         do_facet ost1 "$LCTL set_param fail_loc=0"
17463
17464         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17465         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17466                 $timeout
17467
17468         $LCTL set_param -n $pages_per_rpc
17469         restore_lustre_params < $p
17470         rm -f $p
17471 }
17472 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17473
17474 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17475 test_225a () {
17476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17477         if [ -z ${MDSSURVEY} ]; then
17478                 skip_env "mds-survey not found"
17479         fi
17480         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17481                 skip "Need MDS version at least 2.2.51"
17482
17483         local mds=$(facet_host $SINGLEMDS)
17484         local target=$(do_nodes $mds 'lctl dl' |
17485                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17486
17487         local cmd1="file_count=1000 thrhi=4"
17488         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17489         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17490         local cmd="$cmd1 $cmd2 $cmd3"
17491
17492         rm -f ${TMP}/mds_survey*
17493         echo + $cmd
17494         eval $cmd || error "mds-survey with zero-stripe failed"
17495         cat ${TMP}/mds_survey*
17496         rm -f ${TMP}/mds_survey*
17497 }
17498 run_test 225a "Metadata survey sanity with zero-stripe"
17499
17500 test_225b () {
17501         if [ -z ${MDSSURVEY} ]; then
17502                 skip_env "mds-survey not found"
17503         fi
17504         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17505                 skip "Need MDS version at least 2.2.51"
17506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17507         remote_mds_nodsh && skip "remote MDS with nodsh"
17508         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17509                 skip_env "Need to mount OST to test"
17510         fi
17511
17512         local mds=$(facet_host $SINGLEMDS)
17513         local target=$(do_nodes $mds 'lctl dl' |
17514                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17515
17516         local cmd1="file_count=1000 thrhi=4"
17517         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17518         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17519         local cmd="$cmd1 $cmd2 $cmd3"
17520
17521         rm -f ${TMP}/mds_survey*
17522         echo + $cmd
17523         eval $cmd || error "mds-survey with stripe_count failed"
17524         cat ${TMP}/mds_survey*
17525         rm -f ${TMP}/mds_survey*
17526 }
17527 run_test 225b "Metadata survey sanity with stripe_count = 1"
17528
17529 mcreate_path2fid () {
17530         local mode=$1
17531         local major=$2
17532         local minor=$3
17533         local name=$4
17534         local desc=$5
17535         local path=$DIR/$tdir/$name
17536         local fid
17537         local rc
17538         local fid_path
17539
17540         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17541                 error "cannot create $desc"
17542
17543         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17544         rc=$?
17545         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17546
17547         fid_path=$($LFS fid2path $MOUNT $fid)
17548         rc=$?
17549         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17550
17551         [ "$path" == "$fid_path" ] ||
17552                 error "fid2path returned $fid_path, expected $path"
17553
17554         echo "pass with $path and $fid"
17555 }
17556
17557 test_226a () {
17558         rm -rf $DIR/$tdir
17559         mkdir -p $DIR/$tdir
17560
17561         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17562         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17563         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17564         mcreate_path2fid 0040666 0 0 dir "directory"
17565         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17566         mcreate_path2fid 0100666 0 0 file "regular file"
17567         mcreate_path2fid 0120666 0 0 link "symbolic link"
17568         mcreate_path2fid 0140666 0 0 sock "socket"
17569 }
17570 run_test 226a "call path2fid and fid2path on files of all type"
17571
17572 test_226b () {
17573         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17574
17575         local MDTIDX=1
17576
17577         rm -rf $DIR/$tdir
17578         mkdir -p $DIR/$tdir
17579         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17580                 error "create remote directory failed"
17581         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17582         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17583                                 "character special file (null)"
17584         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17585                                 "character special file (no device)"
17586         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17587         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17588                                 "block special file (loop)"
17589         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17590         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17591         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17592 }
17593 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17594
17595 test_226c () {
17596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17597         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17598                 skip "Need MDS version at least 2.13.55"
17599
17600         local submnt=/mnt/submnt
17601         local srcfile=/etc/passwd
17602         local dstfile=$submnt/passwd
17603         local path
17604         local fid
17605
17606         rm -rf $DIR/$tdir
17607         rm -rf $submnt
17608         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17609                 error "create remote directory failed"
17610         mkdir -p $submnt || error "create $submnt failed"
17611         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17612                 error "mount $submnt failed"
17613         stack_trap "umount $submnt" EXIT
17614
17615         cp $srcfile $dstfile
17616         fid=$($LFS path2fid $dstfile)
17617         path=$($LFS fid2path $submnt "$fid")
17618         [ "$path" = "$dstfile" ] ||
17619                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17620 }
17621 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17622
17623 # LU-1299 Executing or running ldd on a truncated executable does not
17624 # cause an out-of-memory condition.
17625 test_227() {
17626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17627         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17628
17629         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17630         chmod +x $MOUNT/date
17631
17632         $MOUNT/date > /dev/null
17633         ldd $MOUNT/date > /dev/null
17634         rm -f $MOUNT/date
17635 }
17636 run_test 227 "running truncated executable does not cause OOM"
17637
17638 # LU-1512 try to reuse idle OI blocks
17639 test_228a() {
17640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17641         remote_mds_nodsh && skip "remote MDS with nodsh"
17642         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17643
17644         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17645         local myDIR=$DIR/$tdir
17646
17647         mkdir -p $myDIR
17648         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17649         $LCTL set_param fail_loc=0x80001002
17650         createmany -o $myDIR/t- 10000
17651         $LCTL set_param fail_loc=0
17652         # The guard is current the largest FID holder
17653         touch $myDIR/guard
17654         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17655                     tr -d '[')
17656         local IDX=$(($SEQ % 64))
17657
17658         do_facet $SINGLEMDS sync
17659         # Make sure journal flushed.
17660         sleep 6
17661         local blk1=$(do_facet $SINGLEMDS \
17662                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17663                      grep Blockcount | awk '{print $4}')
17664
17665         # Remove old files, some OI blocks will become idle.
17666         unlinkmany $myDIR/t- 10000
17667         # Create new files, idle OI blocks should be reused.
17668         createmany -o $myDIR/t- 2000
17669         do_facet $SINGLEMDS sync
17670         # Make sure journal flushed.
17671         sleep 6
17672         local blk2=$(do_facet $SINGLEMDS \
17673                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17674                      grep Blockcount | awk '{print $4}')
17675
17676         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17677 }
17678 run_test 228a "try to reuse idle OI blocks"
17679
17680 test_228b() {
17681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17682         remote_mds_nodsh && skip "remote MDS with nodsh"
17683         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17684
17685         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17686         local myDIR=$DIR/$tdir
17687
17688         mkdir -p $myDIR
17689         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17690         $LCTL set_param fail_loc=0x80001002
17691         createmany -o $myDIR/t- 10000
17692         $LCTL set_param fail_loc=0
17693         # The guard is current the largest FID holder
17694         touch $myDIR/guard
17695         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17696                     tr -d '[')
17697         local IDX=$(($SEQ % 64))
17698
17699         do_facet $SINGLEMDS sync
17700         # Make sure journal flushed.
17701         sleep 6
17702         local blk1=$(do_facet $SINGLEMDS \
17703                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17704                      grep Blockcount | awk '{print $4}')
17705
17706         # Remove old files, some OI blocks will become idle.
17707         unlinkmany $myDIR/t- 10000
17708
17709         # stop the MDT
17710         stop $SINGLEMDS || error "Fail to stop MDT."
17711         # remount the MDT
17712         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17713
17714         df $MOUNT || error "Fail to df."
17715         # Create new files, idle OI blocks should be reused.
17716         createmany -o $myDIR/t- 2000
17717         do_facet $SINGLEMDS sync
17718         # Make sure journal flushed.
17719         sleep 6
17720         local blk2=$(do_facet $SINGLEMDS \
17721                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17722                      grep Blockcount | awk '{print $4}')
17723
17724         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17725 }
17726 run_test 228b "idle OI blocks can be reused after MDT restart"
17727
17728 #LU-1881
17729 test_228c() {
17730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17731         remote_mds_nodsh && skip "remote MDS with nodsh"
17732         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17733
17734         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17735         local myDIR=$DIR/$tdir
17736
17737         mkdir -p $myDIR
17738         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17739         $LCTL set_param fail_loc=0x80001002
17740         # 20000 files can guarantee there are index nodes in the OI file
17741         createmany -o $myDIR/t- 20000
17742         $LCTL set_param fail_loc=0
17743         # The guard is current the largest FID holder
17744         touch $myDIR/guard
17745         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17746                     tr -d '[')
17747         local IDX=$(($SEQ % 64))
17748
17749         do_facet $SINGLEMDS sync
17750         # Make sure journal flushed.
17751         sleep 6
17752         local blk1=$(do_facet $SINGLEMDS \
17753                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17754                      grep Blockcount | awk '{print $4}')
17755
17756         # Remove old files, some OI blocks will become idle.
17757         unlinkmany $myDIR/t- 20000
17758         rm -f $myDIR/guard
17759         # The OI file should become empty now
17760
17761         # Create new files, idle OI blocks should be reused.
17762         createmany -o $myDIR/t- 2000
17763         do_facet $SINGLEMDS sync
17764         # Make sure journal flushed.
17765         sleep 6
17766         local blk2=$(do_facet $SINGLEMDS \
17767                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17768                      grep Blockcount | awk '{print $4}')
17769
17770         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17771 }
17772 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17773
17774 test_229() { # LU-2482, LU-3448
17775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17776         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17777         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17778                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17779
17780         rm -f $DIR/$tfile
17781
17782         # Create a file with a released layout and stripe count 2.
17783         $MULTIOP $DIR/$tfile H2c ||
17784                 error "failed to create file with released layout"
17785
17786         $LFS getstripe -v $DIR/$tfile
17787
17788         local pattern=$($LFS getstripe -L $DIR/$tfile)
17789         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17790
17791         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17792                 error "getstripe"
17793         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17794         stat $DIR/$tfile || error "failed to stat released file"
17795
17796         chown $RUNAS_ID $DIR/$tfile ||
17797                 error "chown $RUNAS_ID $DIR/$tfile failed"
17798
17799         chgrp $RUNAS_ID $DIR/$tfile ||
17800                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17801
17802         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17803         rm $DIR/$tfile || error "failed to remove released file"
17804 }
17805 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17806
17807 test_230a() {
17808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17811                 skip "Need MDS version at least 2.11.52"
17812
17813         local MDTIDX=1
17814
17815         test_mkdir $DIR/$tdir
17816         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17817         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17818         [ $mdt_idx -ne 0 ] &&
17819                 error "create local directory on wrong MDT $mdt_idx"
17820
17821         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17822                         error "create remote directory failed"
17823         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17824         [ $mdt_idx -ne $MDTIDX ] &&
17825                 error "create remote directory on wrong MDT $mdt_idx"
17826
17827         createmany -o $DIR/$tdir/test_230/t- 10 ||
17828                 error "create files on remote directory failed"
17829         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17830         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17831         rm -r $DIR/$tdir || error "unlink remote directory failed"
17832 }
17833 run_test 230a "Create remote directory and files under the remote directory"
17834
17835 test_230b() {
17836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17838         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17839                 skip "Need MDS version at least 2.11.52"
17840
17841         local MDTIDX=1
17842         local mdt_index
17843         local i
17844         local file
17845         local pid
17846         local stripe_count
17847         local migrate_dir=$DIR/$tdir/migrate_dir
17848         local other_dir=$DIR/$tdir/other_dir
17849
17850         test_mkdir $DIR/$tdir
17851         test_mkdir -i0 -c1 $migrate_dir
17852         test_mkdir -i0 -c1 $other_dir
17853         for ((i=0; i<10; i++)); do
17854                 mkdir -p $migrate_dir/dir_${i}
17855                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17856                         error "create files under remote dir failed $i"
17857         done
17858
17859         cp /etc/passwd $migrate_dir/$tfile
17860         cp /etc/passwd $other_dir/$tfile
17861         chattr +SAD $migrate_dir
17862         chattr +SAD $migrate_dir/$tfile
17863
17864         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17865         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17866         local old_dir_mode=$(stat -c%f $migrate_dir)
17867         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17868
17869         mkdir -p $migrate_dir/dir_default_stripe2
17870         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17871         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17872
17873         mkdir -p $other_dir
17874         ln $migrate_dir/$tfile $other_dir/luna
17875         ln $migrate_dir/$tfile $migrate_dir/sofia
17876         ln $other_dir/$tfile $migrate_dir/david
17877         ln -s $migrate_dir/$tfile $other_dir/zachary
17878         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17879         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17880
17881         local len
17882         local lnktgt
17883
17884         # inline symlink
17885         for len in 58 59 60; do
17886                 lnktgt=$(str_repeat 'l' $len)
17887                 touch $migrate_dir/$lnktgt
17888                 ln -s $lnktgt $migrate_dir/${len}char_ln
17889         done
17890
17891         # PATH_MAX
17892         for len in 4094 4095; do
17893                 lnktgt=$(str_repeat 'l' $len)
17894                 ln -s $lnktgt $migrate_dir/${len}char_ln
17895         done
17896
17897         # NAME_MAX
17898         for len in 254 255; do
17899                 touch $migrate_dir/$(str_repeat 'l' $len)
17900         done
17901
17902         $LFS migrate -m $MDTIDX $migrate_dir ||
17903                 error "fails on migrating remote dir to MDT1"
17904
17905         echo "migratate to MDT1, then checking.."
17906         for ((i = 0; i < 10; i++)); do
17907                 for file in $(find $migrate_dir/dir_${i}); do
17908                         mdt_index=$($LFS getstripe -m $file)
17909                         # broken symlink getstripe will fail
17910                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17911                                 error "$file is not on MDT${MDTIDX}"
17912                 done
17913         done
17914
17915         # the multiple link file should still in MDT0
17916         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17917         [ $mdt_index == 0 ] ||
17918                 error "$file is not on MDT${MDTIDX}"
17919
17920         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17921         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17922                 error " expect $old_dir_flag get $new_dir_flag"
17923
17924         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17925         [ "$old_file_flag" = "$new_file_flag" ] ||
17926                 error " expect $old_file_flag get $new_file_flag"
17927
17928         local new_dir_mode=$(stat -c%f $migrate_dir)
17929         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17930                 error "expect mode $old_dir_mode get $new_dir_mode"
17931
17932         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17933         [ "$old_file_mode" = "$new_file_mode" ] ||
17934                 error "expect mode $old_file_mode get $new_file_mode"
17935
17936         diff /etc/passwd $migrate_dir/$tfile ||
17937                 error "$tfile different after migration"
17938
17939         diff /etc/passwd $other_dir/luna ||
17940                 error "luna different after migration"
17941
17942         diff /etc/passwd $migrate_dir/sofia ||
17943                 error "sofia different after migration"
17944
17945         diff /etc/passwd $migrate_dir/david ||
17946                 error "david different after migration"
17947
17948         diff /etc/passwd $other_dir/zachary ||
17949                 error "zachary different after migration"
17950
17951         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17952                 error "${tfile}_ln different after migration"
17953
17954         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17955                 error "${tfile}_ln_other different after migration"
17956
17957         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17958         [ $stripe_count = 2 ] ||
17959                 error "dir strpe_count $d != 2 after migration."
17960
17961         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17962         [ $stripe_count = 2 ] ||
17963                 error "file strpe_count $d != 2 after migration."
17964
17965         #migrate back to MDT0
17966         MDTIDX=0
17967
17968         $LFS migrate -m $MDTIDX $migrate_dir ||
17969                 error "fails on migrating remote dir to MDT0"
17970
17971         echo "migrate back to MDT0, checking.."
17972         for file in $(find $migrate_dir); do
17973                 mdt_index=$($LFS getstripe -m $file)
17974                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17975                         error "$file is not on MDT${MDTIDX}"
17976         done
17977
17978         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17979         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17980                 error " expect $old_dir_flag get $new_dir_flag"
17981
17982         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17983         [ "$old_file_flag" = "$new_file_flag" ] ||
17984                 error " expect $old_file_flag get $new_file_flag"
17985
17986         local new_dir_mode=$(stat -c%f $migrate_dir)
17987         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17988                 error "expect mode $old_dir_mode get $new_dir_mode"
17989
17990         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17991         [ "$old_file_mode" = "$new_file_mode" ] ||
17992                 error "expect mode $old_file_mode get $new_file_mode"
17993
17994         diff /etc/passwd ${migrate_dir}/$tfile ||
17995                 error "$tfile different after migration"
17996
17997         diff /etc/passwd ${other_dir}/luna ||
17998                 error "luna different after migration"
17999
18000         diff /etc/passwd ${migrate_dir}/sofia ||
18001                 error "sofia different after migration"
18002
18003         diff /etc/passwd ${other_dir}/zachary ||
18004                 error "zachary different after migration"
18005
18006         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18007                 error "${tfile}_ln different after migration"
18008
18009         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18010                 error "${tfile}_ln_other different after migration"
18011
18012         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18013         [ $stripe_count = 2 ] ||
18014                 error "dir strpe_count $d != 2 after migration."
18015
18016         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18017         [ $stripe_count = 2 ] ||
18018                 error "file strpe_count $d != 2 after migration."
18019
18020         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18021 }
18022 run_test 230b "migrate directory"
18023
18024 test_230c() {
18025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18027         remote_mds_nodsh && skip "remote MDS with nodsh"
18028         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18029                 skip "Need MDS version at least 2.11.52"
18030
18031         local MDTIDX=1
18032         local total=3
18033         local mdt_index
18034         local file
18035         local migrate_dir=$DIR/$tdir/migrate_dir
18036
18037         #If migrating directory fails in the middle, all entries of
18038         #the directory is still accessiable.
18039         test_mkdir $DIR/$tdir
18040         test_mkdir -i0 -c1 $migrate_dir
18041         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18042         stat $migrate_dir
18043         createmany -o $migrate_dir/f $total ||
18044                 error "create files under ${migrate_dir} failed"
18045
18046         # fail after migrating top dir, and this will fail only once, so the
18047         # first sub file migration will fail (currently f3), others succeed.
18048         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18049         do_facet mds1 lctl set_param fail_loc=0x1801
18050         local t=$(ls $migrate_dir | wc -l)
18051         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18052                 error "migrate should fail"
18053         local u=$(ls $migrate_dir | wc -l)
18054         [ "$u" == "$t" ] || error "$u != $t during migration"
18055
18056         # add new dir/file should succeed
18057         mkdir $migrate_dir/dir ||
18058                 error "mkdir failed under migrating directory"
18059         touch $migrate_dir/file ||
18060                 error "create file failed under migrating directory"
18061
18062         # add file with existing name should fail
18063         for file in $migrate_dir/f*; do
18064                 stat $file > /dev/null || error "stat $file failed"
18065                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18066                         error "open(O_CREAT|O_EXCL) $file should fail"
18067                 $MULTIOP $file m && error "create $file should fail"
18068                 touch $DIR/$tdir/remote_dir/$tfile ||
18069                         error "touch $tfile failed"
18070                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18071                         error "link $file should fail"
18072                 mdt_index=$($LFS getstripe -m $file)
18073                 if [ $mdt_index == 0 ]; then
18074                         # file failed to migrate is not allowed to rename to
18075                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18076                                 error "rename to $file should fail"
18077                 else
18078                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18079                                 error "rename to $file failed"
18080                 fi
18081                 echo hello >> $file || error "write $file failed"
18082         done
18083
18084         # resume migration with different options should fail
18085         $LFS migrate -m 0 $migrate_dir &&
18086                 error "migrate -m 0 $migrate_dir should fail"
18087
18088         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18089                 error "migrate -c 2 $migrate_dir should fail"
18090
18091         # resume migration should succeed
18092         $LFS migrate -m $MDTIDX $migrate_dir ||
18093                 error "migrate $migrate_dir failed"
18094
18095         echo "Finish migration, then checking.."
18096         for file in $(find $migrate_dir); do
18097                 mdt_index=$($LFS getstripe -m $file)
18098                 [ $mdt_index == $MDTIDX ] ||
18099                         error "$file is not on MDT${MDTIDX}"
18100         done
18101
18102         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18103 }
18104 run_test 230c "check directory accessiblity if migration failed"
18105
18106 test_230d() {
18107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18109         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18110                 skip "Need MDS version at least 2.11.52"
18111         # LU-11235
18112         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18113
18114         local migrate_dir=$DIR/$tdir/migrate_dir
18115         local old_index
18116         local new_index
18117         local old_count
18118         local new_count
18119         local new_hash
18120         local mdt_index
18121         local i
18122         local j
18123
18124         old_index=$((RANDOM % MDSCOUNT))
18125         old_count=$((MDSCOUNT - old_index))
18126         new_index=$((RANDOM % MDSCOUNT))
18127         new_count=$((MDSCOUNT - new_index))
18128         new_hash=1 # for all_char
18129
18130         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18131         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18132
18133         test_mkdir $DIR/$tdir
18134         test_mkdir -i $old_index -c $old_count $migrate_dir
18135
18136         for ((i=0; i<100; i++)); do
18137                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18138                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18139                         error "create files under remote dir failed $i"
18140         done
18141
18142         echo -n "Migrate from MDT$old_index "
18143         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18144         echo -n "to MDT$new_index"
18145         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18146         echo
18147
18148         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18149         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18150                 error "migrate remote dir error"
18151
18152         echo "Finish migration, then checking.."
18153         for file in $(find $migrate_dir); do
18154                 mdt_index=$($LFS getstripe -m $file)
18155                 if [ $mdt_index -lt $new_index ] ||
18156                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18157                         error "$file is on MDT$mdt_index"
18158                 fi
18159         done
18160
18161         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18162 }
18163 run_test 230d "check migrate big directory"
18164
18165 test_230e() {
18166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18168         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18169                 skip "Need MDS version at least 2.11.52"
18170
18171         local i
18172         local j
18173         local a_fid
18174         local b_fid
18175
18176         mkdir -p $DIR/$tdir
18177         mkdir $DIR/$tdir/migrate_dir
18178         mkdir $DIR/$tdir/other_dir
18179         touch $DIR/$tdir/migrate_dir/a
18180         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18181         ls $DIR/$tdir/other_dir
18182
18183         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18184                 error "migrate dir fails"
18185
18186         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18187         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18188
18189         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18190         [ $mdt_index == 0 ] || error "a is not on MDT0"
18191
18192         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18193                 error "migrate dir fails"
18194
18195         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18196         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18197
18198         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18199         [ $mdt_index == 1 ] || error "a is not on MDT1"
18200
18201         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18202         [ $mdt_index == 1 ] || error "b is not on MDT1"
18203
18204         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18205         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18206
18207         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18208
18209         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18210 }
18211 run_test 230e "migrate mulitple local link files"
18212
18213 test_230f() {
18214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18215         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18216         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18217                 skip "Need MDS version at least 2.11.52"
18218
18219         local a_fid
18220         local ln_fid
18221
18222         mkdir -p $DIR/$tdir
18223         mkdir $DIR/$tdir/migrate_dir
18224         $LFS mkdir -i1 $DIR/$tdir/other_dir
18225         touch $DIR/$tdir/migrate_dir/a
18226         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18227         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18228         ls $DIR/$tdir/other_dir
18229
18230         # a should be migrated to MDT1, since no other links on MDT0
18231         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18232                 error "#1 migrate dir fails"
18233         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18234         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18235         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18236         [ $mdt_index == 1 ] || error "a is not on MDT1"
18237
18238         # a should stay on MDT1, because it is a mulitple link file
18239         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18240                 error "#2 migrate dir fails"
18241         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18242         [ $mdt_index == 1 ] || error "a is not on MDT1"
18243
18244         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18245                 error "#3 migrate dir fails"
18246
18247         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18248         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18249         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18250
18251         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18252         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18253
18254         # a should be migrated to MDT0, since no other links on MDT1
18255         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18256                 error "#4 migrate dir fails"
18257         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18258         [ $mdt_index == 0 ] || error "a is not on MDT0"
18259
18260         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18261 }
18262 run_test 230f "migrate mulitple remote link files"
18263
18264 test_230g() {
18265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18267         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18268                 skip "Need MDS version at least 2.11.52"
18269
18270         mkdir -p $DIR/$tdir/migrate_dir
18271
18272         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18273                 error "migrating dir to non-exist MDT succeeds"
18274         true
18275 }
18276 run_test 230g "migrate dir to non-exist MDT"
18277
18278 test_230h() {
18279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18281         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18282                 skip "Need MDS version at least 2.11.52"
18283
18284         local mdt_index
18285
18286         mkdir -p $DIR/$tdir/migrate_dir
18287
18288         $LFS migrate -m1 $DIR &&
18289                 error "migrating mountpoint1 should fail"
18290
18291         $LFS migrate -m1 $DIR/$tdir/.. &&
18292                 error "migrating mountpoint2 should fail"
18293
18294         # same as mv
18295         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18296                 error "migrating $tdir/migrate_dir/.. should fail"
18297
18298         true
18299 }
18300 run_test 230h "migrate .. and root"
18301
18302 test_230i() {
18303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18305         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18306                 skip "Need MDS version at least 2.11.52"
18307
18308         mkdir -p $DIR/$tdir/migrate_dir
18309
18310         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18311                 error "migration fails with a tailing slash"
18312
18313         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18314                 error "migration fails with two tailing slashes"
18315 }
18316 run_test 230i "lfs migrate -m tolerates trailing slashes"
18317
18318 test_230j() {
18319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18320         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18321                 skip "Need MDS version at least 2.11.52"
18322
18323         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18324         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18325                 error "create $tfile failed"
18326         cat /etc/passwd > $DIR/$tdir/$tfile
18327
18328         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18329
18330         cmp /etc/passwd $DIR/$tdir/$tfile ||
18331                 error "DoM file mismatch after migration"
18332 }
18333 run_test 230j "DoM file data not changed after dir migration"
18334
18335 test_230k() {
18336         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18337         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18338                 skip "Need MDS version at least 2.11.56"
18339
18340         local total=20
18341         local files_on_starting_mdt=0
18342
18343         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18344         $LFS getdirstripe $DIR/$tdir
18345         for i in $(seq $total); do
18346                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18347                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18348                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18349         done
18350
18351         echo "$files_on_starting_mdt files on MDT0"
18352
18353         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18354         $LFS getdirstripe $DIR/$tdir
18355
18356         files_on_starting_mdt=0
18357         for i in $(seq $total); do
18358                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18359                         error "file $tfile.$i mismatch after migration"
18360                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18361                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18362         done
18363
18364         echo "$files_on_starting_mdt files on MDT1 after migration"
18365         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18366
18367         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18368         $LFS getdirstripe $DIR/$tdir
18369
18370         files_on_starting_mdt=0
18371         for i in $(seq $total); do
18372                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18373                         error "file $tfile.$i mismatch after 2nd migration"
18374                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18375                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18376         done
18377
18378         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18379         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18380
18381         true
18382 }
18383 run_test 230k "file data not changed after dir migration"
18384
18385 test_230l() {
18386         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18387         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18388                 skip "Need MDS version at least 2.11.56"
18389
18390         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18391         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18392                 error "create files under remote dir failed $i"
18393         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18394 }
18395 run_test 230l "readdir between MDTs won't crash"
18396
18397 test_230m() {
18398         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18399         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18400                 skip "Need MDS version at least 2.11.56"
18401
18402         local MDTIDX=1
18403         local mig_dir=$DIR/$tdir/migrate_dir
18404         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18405         local shortstr="b"
18406         local val
18407
18408         echo "Creating files and dirs with xattrs"
18409         test_mkdir $DIR/$tdir
18410         test_mkdir -i0 -c1 $mig_dir
18411         mkdir $mig_dir/dir
18412         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18413                 error "cannot set xattr attr1 on dir"
18414         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18415                 error "cannot set xattr attr2 on dir"
18416         touch $mig_dir/dir/f0
18417         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18418                 error "cannot set xattr attr1 on file"
18419         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18420                 error "cannot set xattr attr2 on file"
18421         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18422         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18423         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18424         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18425         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18426         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18427         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18428         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18429         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18430
18431         echo "Migrating to MDT1"
18432         $LFS migrate -m $MDTIDX $mig_dir ||
18433                 error "fails on migrating dir to MDT1"
18434
18435         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18436         echo "Checking xattrs"
18437         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18438         [ "$val" = $longstr ] ||
18439                 error "expecting xattr1 $longstr on dir, found $val"
18440         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18441         [ "$val" = $shortstr ] ||
18442                 error "expecting xattr2 $shortstr on dir, found $val"
18443         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18444         [ "$val" = $longstr ] ||
18445                 error "expecting xattr1 $longstr on file, found $val"
18446         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18447         [ "$val" = $shortstr ] ||
18448                 error "expecting xattr2 $shortstr on file, found $val"
18449 }
18450 run_test 230m "xattrs not changed after dir migration"
18451
18452 test_230n() {
18453         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18454         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18455                 skip "Need MDS version at least 2.13.53"
18456
18457         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18458         cat /etc/hosts > $DIR/$tdir/$tfile
18459         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18460         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18461
18462         cmp /etc/hosts $DIR/$tdir/$tfile ||
18463                 error "File data mismatch after migration"
18464 }
18465 run_test 230n "Dir migration with mirrored file"
18466
18467 test_230o() {
18468         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18469         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18470                 skip "Need MDS version at least 2.13.52"
18471
18472         local mdts=$(comma_list $(mdts_nodes))
18473         local timeout=100
18474
18475         local restripe_status
18476         local delta
18477         local i
18478         local j
18479
18480         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18481
18482         # in case "crush" hash type is not set
18483         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18484
18485         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18486                            mdt.*MDT0000.enable_dir_restripe)
18487         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18488         stack_trap "do_nodes $mdts $LCTL set_param \
18489                     mdt.*.enable_dir_restripe=$restripe_status"
18490
18491         mkdir $DIR/$tdir
18492         createmany -m $DIR/$tdir/f 100 ||
18493                 error "create files under remote dir failed $i"
18494         createmany -d $DIR/$tdir/d 100 ||
18495                 error "create dirs under remote dir failed $i"
18496
18497         for i in $(seq 2 $MDSCOUNT); do
18498                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18499                 $LFS setdirstripe -c $i $DIR/$tdir ||
18500                         error "split -c $i $tdir failed"
18501                 wait_update $HOSTNAME \
18502                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18503                         error "dir split not finished"
18504                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18505                         awk '/migrate/ {sum += $2} END { print sum }')
18506                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18507                 # delta is around total_files/stripe_count
18508                 [ $delta -lt $((200 /(i - 1))) ] ||
18509                         error "$delta files migrated"
18510         done
18511 }
18512 run_test 230o "dir split"
18513
18514 test_230p() {
18515         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18516         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18517                 skip "Need MDS version at least 2.13.52"
18518
18519         local mdts=$(comma_list $(mdts_nodes))
18520         local timeout=100
18521
18522         local restripe_status
18523         local delta
18524         local i
18525         local j
18526
18527         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18528
18529         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18530
18531         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18532                            mdt.*MDT0000.enable_dir_restripe)
18533         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18534         stack_trap "do_nodes $mdts $LCTL set_param \
18535                     mdt.*.enable_dir_restripe=$restripe_status"
18536
18537         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18538         createmany -m $DIR/$tdir/f 100 ||
18539                 error "create files under remote dir failed $i"
18540         createmany -d $DIR/$tdir/d 100 ||
18541                 error "create dirs under remote dir failed $i"
18542
18543         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18544                 local mdt_hash="crush"
18545
18546                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18547                 $LFS setdirstripe -c $i $DIR/$tdir ||
18548                         error "split -c $i $tdir failed"
18549                 [ $i -eq 1 ] && mdt_hash="none"
18550                 wait_update $HOSTNAME \
18551                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18552                         error "dir merge not finished"
18553                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18554                         awk '/migrate/ {sum += $2} END { print sum }')
18555                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18556                 # delta is around total_files/stripe_count
18557                 [ $delta -lt $((200 / i)) ] ||
18558                         error "$delta files migrated"
18559         done
18560 }
18561 run_test 230p "dir merge"
18562
18563 test_230q() {
18564         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18565         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18566                 skip "Need MDS version at least 2.13.52"
18567
18568         local mdts=$(comma_list $(mdts_nodes))
18569         local saved_threshold=$(do_facet mds1 \
18570                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18571         local saved_delta=$(do_facet mds1 \
18572                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18573         local threshold=100
18574         local delta=2
18575         local total=0
18576         local stripe_count=0
18577         local stripe_index
18578         local nr_files
18579
18580         # test with fewer files on ZFS
18581         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18582
18583         stack_trap "do_nodes $mdts $LCTL set_param \
18584                     mdt.*.dir_split_count=$saved_threshold"
18585         stack_trap "do_nodes $mdts $LCTL set_param \
18586                     mdt.*.dir_split_delta=$saved_delta"
18587         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18588         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18589         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18590         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18591         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18592         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18593
18594         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18595         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18596
18597         while [ $stripe_count -lt $MDSCOUNT ]; do
18598                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18599                         error "create sub files failed"
18600                 stat $DIR/$tdir > /dev/null
18601                 total=$((total + threshold * 3 / 2))
18602                 stripe_count=$((stripe_count + delta))
18603                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18604
18605                 wait_update $HOSTNAME \
18606                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18607                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18608
18609                 wait_update $HOSTNAME \
18610                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18611                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18612
18613                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18614                            grep -w $stripe_index | wc -l)
18615                 echo "$nr_files files on MDT$stripe_index after split"
18616                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18617                         error "$nr_files files on MDT$stripe_index after split"
18618
18619                 nr_files=$(ls $DIR/$tdir | wc -w)
18620                 [ $nr_files -eq $total ] ||
18621                         error "total sub files $nr_files != $total"
18622         done
18623 }
18624 run_test 230q "dir auto split"
18625
18626 test_230r() {
18627         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18628         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18629         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18630                 skip "Need MDS version at least 2.13.54"
18631
18632         # maximum amount of local locks:
18633         # parent striped dir - 2 locks
18634         # new stripe in parent to migrate to - 1 lock
18635         # source and target - 2 locks
18636         # Total 5 locks for regular file
18637         mkdir -p $DIR/$tdir
18638         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18639         touch $DIR/$tdir/dir1/eee
18640
18641         # create 4 hardlink for 4 more locks
18642         # Total: 9 locks > RS_MAX_LOCKS (8)
18643         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18644         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18645         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18646         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18647         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18648         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18649         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18650         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18651
18652         cancel_lru_locks mdc
18653
18654         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18655                 error "migrate dir fails"
18656
18657         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18658 }
18659 run_test 230r "migrate with too many local locks"
18660
18661 test_231a()
18662 {
18663         # For simplicity this test assumes that max_pages_per_rpc
18664         # is the same across all OSCs
18665         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18666         local bulk_size=$((max_pages * PAGE_SIZE))
18667         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18668                                        head -n 1)
18669
18670         mkdir -p $DIR/$tdir
18671         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18672                 error "failed to set stripe with -S ${brw_size}M option"
18673
18674         # clear the OSC stats
18675         $LCTL set_param osc.*.stats=0 &>/dev/null
18676         stop_writeback
18677
18678         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18679         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18680                 oflag=direct &>/dev/null || error "dd failed"
18681
18682         sync; sleep 1; sync # just to be safe
18683         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18684         if [ x$nrpcs != "x1" ]; then
18685                 $LCTL get_param osc.*.stats
18686                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18687         fi
18688
18689         start_writeback
18690         # Drop the OSC cache, otherwise we will read from it
18691         cancel_lru_locks osc
18692
18693         # clear the OSC stats
18694         $LCTL set_param osc.*.stats=0 &>/dev/null
18695
18696         # Client reads $bulk_size.
18697         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18698                 iflag=direct &>/dev/null || error "dd failed"
18699
18700         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18701         if [ x$nrpcs != "x1" ]; then
18702                 $LCTL get_param osc.*.stats
18703                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18704         fi
18705 }
18706 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18707
18708 test_231b() {
18709         mkdir -p $DIR/$tdir
18710         local i
18711         for i in {0..1023}; do
18712                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18713                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18714                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18715         done
18716         sync
18717 }
18718 run_test 231b "must not assert on fully utilized OST request buffer"
18719
18720 test_232a() {
18721         mkdir -p $DIR/$tdir
18722         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18723
18724         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18725         do_facet ost1 $LCTL set_param fail_loc=0x31c
18726
18727         # ignore dd failure
18728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18729
18730         do_facet ost1 $LCTL set_param fail_loc=0
18731         umount_client $MOUNT || error "umount failed"
18732         mount_client $MOUNT || error "mount failed"
18733         stop ost1 || error "cannot stop ost1"
18734         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18735 }
18736 run_test 232a "failed lock should not block umount"
18737
18738 test_232b() {
18739         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18740                 skip "Need MDS version at least 2.10.58"
18741
18742         mkdir -p $DIR/$tdir
18743         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18744         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18745         sync
18746         cancel_lru_locks osc
18747
18748         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18749         do_facet ost1 $LCTL set_param fail_loc=0x31c
18750
18751         # ignore failure
18752         $LFS data_version $DIR/$tdir/$tfile || true
18753
18754         do_facet ost1 $LCTL set_param fail_loc=0
18755         umount_client $MOUNT || error "umount failed"
18756         mount_client $MOUNT || error "mount failed"
18757         stop ost1 || error "cannot stop ost1"
18758         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18759 }
18760 run_test 232b "failed data version lock should not block umount"
18761
18762 test_233a() {
18763         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18764                 skip "Need MDS version at least 2.3.64"
18765         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18766
18767         local fid=$($LFS path2fid $MOUNT)
18768
18769         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18770                 error "cannot access $MOUNT using its FID '$fid'"
18771 }
18772 run_test 233a "checking that OBF of the FS root succeeds"
18773
18774 test_233b() {
18775         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18776                 skip "Need MDS version at least 2.5.90"
18777         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18778
18779         local fid=$($LFS path2fid $MOUNT/.lustre)
18780
18781         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18782                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18783
18784         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18785         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18786                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18787 }
18788 run_test 233b "checking that OBF of the FS .lustre succeeds"
18789
18790 test_234() {
18791         local p="$TMP/sanityN-$TESTNAME.parameters"
18792         save_lustre_params client "llite.*.xattr_cache" > $p
18793         lctl set_param llite.*.xattr_cache 1 ||
18794                 skip_env "xattr cache is not supported"
18795
18796         mkdir -p $DIR/$tdir || error "mkdir failed"
18797         touch $DIR/$tdir/$tfile || error "touch failed"
18798         # OBD_FAIL_LLITE_XATTR_ENOMEM
18799         $LCTL set_param fail_loc=0x1405
18800         getfattr -n user.attr $DIR/$tdir/$tfile &&
18801                 error "getfattr should have failed with ENOMEM"
18802         $LCTL set_param fail_loc=0x0
18803         rm -rf $DIR/$tdir
18804
18805         restore_lustre_params < $p
18806         rm -f $p
18807 }
18808 run_test 234 "xattr cache should not crash on ENOMEM"
18809
18810 test_235() {
18811         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18812                 skip "Need MDS version at least 2.4.52"
18813
18814         flock_deadlock $DIR/$tfile
18815         local RC=$?
18816         case $RC in
18817                 0)
18818                 ;;
18819                 124) error "process hangs on a deadlock"
18820                 ;;
18821                 *) error "error executing flock_deadlock $DIR/$tfile"
18822                 ;;
18823         esac
18824 }
18825 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18826
18827 #LU-2935
18828 test_236() {
18829         check_swap_layouts_support
18830
18831         local ref1=/etc/passwd
18832         local ref2=/etc/group
18833         local file1=$DIR/$tdir/f1
18834         local file2=$DIR/$tdir/f2
18835
18836         test_mkdir -c1 $DIR/$tdir
18837         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18838         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18839         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18840         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18841         local fd=$(free_fd)
18842         local cmd="exec $fd<>$file2"
18843         eval $cmd
18844         rm $file2
18845         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18846                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18847         cmd="exec $fd>&-"
18848         eval $cmd
18849         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18850
18851         #cleanup
18852         rm -rf $DIR/$tdir
18853 }
18854 run_test 236 "Layout swap on open unlinked file"
18855
18856 # LU-4659 linkea consistency
18857 test_238() {
18858         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18859                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18860                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18861                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18862
18863         touch $DIR/$tfile
18864         ln $DIR/$tfile $DIR/$tfile.lnk
18865         touch $DIR/$tfile.new
18866         mv $DIR/$tfile.new $DIR/$tfile
18867         local fid1=$($LFS path2fid $DIR/$tfile)
18868         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18869         local path1=$($LFS fid2path $FSNAME "$fid1")
18870         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18871         local path2=$($LFS fid2path $FSNAME "$fid2")
18872         [ $tfile.lnk == $path2 ] ||
18873                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18874         rm -f $DIR/$tfile*
18875 }
18876 run_test 238 "Verify linkea consistency"
18877
18878 test_239A() { # was test_239
18879         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18880                 skip "Need MDS version at least 2.5.60"
18881
18882         local list=$(comma_list $(mdts_nodes))
18883
18884         mkdir -p $DIR/$tdir
18885         createmany -o $DIR/$tdir/f- 5000
18886         unlinkmany $DIR/$tdir/f- 5000
18887         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18888                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18889         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18890                         osp.*MDT*.sync_in_flight" | calc_sum)
18891         [ "$changes" -eq 0 ] || error "$changes not synced"
18892 }
18893 run_test 239A "osp_sync test"
18894
18895 test_239a() { #LU-5297
18896         remote_mds_nodsh && skip "remote MDS with nodsh"
18897
18898         touch $DIR/$tfile
18899         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18900         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18901         chgrp $RUNAS_GID $DIR/$tfile
18902         wait_delete_completed
18903 }
18904 run_test 239a "process invalid osp sync record correctly"
18905
18906 test_239b() { #LU-5297
18907         remote_mds_nodsh && skip "remote MDS with nodsh"
18908
18909         touch $DIR/$tfile1
18910         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18911         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18912         chgrp $RUNAS_GID $DIR/$tfile1
18913         wait_delete_completed
18914         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18915         touch $DIR/$tfile2
18916         chgrp $RUNAS_GID $DIR/$tfile2
18917         wait_delete_completed
18918 }
18919 run_test 239b "process osp sync record with ENOMEM error correctly"
18920
18921 test_240() {
18922         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18923         remote_mds_nodsh && skip "remote MDS with nodsh"
18924
18925         mkdir -p $DIR/$tdir
18926
18927         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18928                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18929         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18930                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18931
18932         umount_client $MOUNT || error "umount failed"
18933         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18934         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18935         mount_client $MOUNT || error "failed to mount client"
18936
18937         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18938         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18939 }
18940 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18941
18942 test_241_bio() {
18943         local count=$1
18944         local bsize=$2
18945
18946         for LOOP in $(seq $count); do
18947                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18948                 cancel_lru_locks $OSC || true
18949         done
18950 }
18951
18952 test_241_dio() {
18953         local count=$1
18954         local bsize=$2
18955
18956         for LOOP in $(seq $1); do
18957                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18958                         2>/dev/null
18959         done
18960 }
18961
18962 test_241a() { # was test_241
18963         local bsize=$PAGE_SIZE
18964
18965         (( bsize < 40960 )) && bsize=40960
18966         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18967         ls -la $DIR/$tfile
18968         cancel_lru_locks $OSC
18969         test_241_bio 1000 $bsize &
18970         PID=$!
18971         test_241_dio 1000 $bsize
18972         wait $PID
18973 }
18974 run_test 241a "bio vs dio"
18975
18976 test_241b() {
18977         local bsize=$PAGE_SIZE
18978
18979         (( bsize < 40960 )) && bsize=40960
18980         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18981         ls -la $DIR/$tfile
18982         test_241_dio 1000 $bsize &
18983         PID=$!
18984         test_241_dio 1000 $bsize
18985         wait $PID
18986 }
18987 run_test 241b "dio vs dio"
18988
18989 test_242() {
18990         remote_mds_nodsh && skip "remote MDS with nodsh"
18991
18992         mkdir -p $DIR/$tdir
18993         touch $DIR/$tdir/$tfile
18994
18995         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18996         do_facet mds1 lctl set_param fail_loc=0x105
18997         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18998
18999         do_facet mds1 lctl set_param fail_loc=0
19000         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19001 }
19002 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19003
19004 test_243()
19005 {
19006         test_mkdir $DIR/$tdir
19007         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19008 }
19009 run_test 243 "various group lock tests"
19010
19011 test_244a()
19012 {
19013         test_mkdir $DIR/$tdir
19014         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19015         sendfile_grouplock $DIR/$tdir/$tfile || \
19016                 error "sendfile+grouplock failed"
19017         rm -rf $DIR/$tdir
19018 }
19019 run_test 244a "sendfile with group lock tests"
19020
19021 test_244b()
19022 {
19023         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19024
19025         local threads=50
19026         local size=$((1024*1024))
19027
19028         test_mkdir $DIR/$tdir
19029         for i in $(seq 1 $threads); do
19030                 local file=$DIR/$tdir/file_$((i / 10))
19031                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19032                 local pids[$i]=$!
19033         done
19034         for i in $(seq 1 $threads); do
19035                 wait ${pids[$i]}
19036         done
19037 }
19038 run_test 244b "multi-threaded write with group lock"
19039
19040 test_245() {
19041         local flagname="multi_mod_rpcs"
19042         local connect_data_name="max_mod_rpcs"
19043         local out
19044
19045         # check if multiple modify RPCs flag is set
19046         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19047                 grep "connect_flags:")
19048         echo "$out"
19049
19050         echo "$out" | grep -qw $flagname
19051         if [ $? -ne 0 ]; then
19052                 echo "connect flag $flagname is not set"
19053                 return
19054         fi
19055
19056         # check if multiple modify RPCs data is set
19057         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19058         echo "$out"
19059
19060         echo "$out" | grep -qw $connect_data_name ||
19061                 error "import should have connect data $connect_data_name"
19062 }
19063 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19064
19065 cleanup_247() {
19066         local submount=$1
19067
19068         trap 0
19069         umount_client $submount
19070         rmdir $submount
19071 }
19072
19073 test_247a() {
19074         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19075                 grep -q subtree ||
19076                 skip_env "Fileset feature is not supported"
19077
19078         local submount=${MOUNT}_$tdir
19079
19080         mkdir $MOUNT/$tdir
19081         mkdir -p $submount || error "mkdir $submount failed"
19082         FILESET="$FILESET/$tdir" mount_client $submount ||
19083                 error "mount $submount failed"
19084         trap "cleanup_247 $submount" EXIT
19085         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19086         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19087                 error "read $MOUNT/$tdir/$tfile failed"
19088         cleanup_247 $submount
19089 }
19090 run_test 247a "mount subdir as fileset"
19091
19092 test_247b() {
19093         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19094                 skip_env "Fileset feature is not supported"
19095
19096         local submount=${MOUNT}_$tdir
19097
19098         rm -rf $MOUNT/$tdir
19099         mkdir -p $submount || error "mkdir $submount failed"
19100         SKIP_FILESET=1
19101         FILESET="$FILESET/$tdir" mount_client $submount &&
19102                 error "mount $submount should fail"
19103         rmdir $submount
19104 }
19105 run_test 247b "mount subdir that dose not exist"
19106
19107 test_247c() {
19108         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19109                 skip_env "Fileset feature is not supported"
19110
19111         local submount=${MOUNT}_$tdir
19112
19113         mkdir -p $MOUNT/$tdir/dir1
19114         mkdir -p $submount || error "mkdir $submount failed"
19115         trap "cleanup_247 $submount" EXIT
19116         FILESET="$FILESET/$tdir" mount_client $submount ||
19117                 error "mount $submount failed"
19118         local fid=$($LFS path2fid $MOUNT/)
19119         $LFS fid2path $submount $fid && error "fid2path should fail"
19120         cleanup_247 $submount
19121 }
19122 run_test 247c "running fid2path outside subdirectory root"
19123
19124 test_247d() {
19125         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19126                 skip "Fileset feature is not supported"
19127
19128         local submount=${MOUNT}_$tdir
19129
19130         mkdir -p $MOUNT/$tdir/dir1
19131         mkdir -p $submount || error "mkdir $submount failed"
19132         FILESET="$FILESET/$tdir" mount_client $submount ||
19133                 error "mount $submount failed"
19134         trap "cleanup_247 $submount" EXIT
19135
19136         local td=$submount/dir1
19137         local fid=$($LFS path2fid $td)
19138         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19139
19140         # check that we get the same pathname back
19141         local rootpath
19142         local found
19143         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19144                 echo "$rootpath $fid"
19145                 found=$($LFS fid2path $rootpath "$fid")
19146                 [ -n "found" ] || error "fid2path should succeed"
19147                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19148         done
19149         # check wrong root path format
19150         rootpath=$submount"_wrong"
19151         found=$($LFS fid2path $rootpath "$fid")
19152         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19153
19154         cleanup_247 $submount
19155 }
19156 run_test 247d "running fid2path inside subdirectory root"
19157
19158 # LU-8037
19159 test_247e() {
19160         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19161                 grep -q subtree ||
19162                 skip "Fileset feature is not supported"
19163
19164         local submount=${MOUNT}_$tdir
19165
19166         mkdir $MOUNT/$tdir
19167         mkdir -p $submount || error "mkdir $submount failed"
19168         FILESET="$FILESET/.." mount_client $submount &&
19169                 error "mount $submount should fail"
19170         rmdir $submount
19171 }
19172 run_test 247e "mount .. as fileset"
19173
19174 test_247f() {
19175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19176         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19177                 skip "Need at least version 2.13.52"
19178         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19179                 grep -q subtree ||
19180                 skip "Fileset feature is not supported"
19181
19182         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19183         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19184                 error "mkdir remote failed"
19185         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19186         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19187                 error "mkdir striped failed"
19188         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19189
19190         local submount=${MOUNT}_$tdir
19191
19192         mkdir -p $submount || error "mkdir $submount failed"
19193
19194         local dir
19195         local fileset=$FILESET
19196
19197         for dir in $tdir/remote $tdir/remote/subdir \
19198                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19199                 FILESET="$fileset/$dir" mount_client $submount ||
19200                         error "mount $dir failed"
19201                 umount_client $submount
19202         done
19203 }
19204 run_test 247f "mount striped or remote directory as fileset"
19205
19206 test_248a() {
19207         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19208         [ -z "$fast_read_sav" ] && skip "no fast read support"
19209
19210         # create a large file for fast read verification
19211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19212
19213         # make sure the file is created correctly
19214         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19215                 { rm -f $DIR/$tfile; skip "file creation error"; }
19216
19217         echo "Test 1: verify that fast read is 4 times faster on cache read"
19218
19219         # small read with fast read enabled
19220         $LCTL set_param -n llite.*.fast_read=1
19221         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19222                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19223                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19224         # small read with fast read disabled
19225         $LCTL set_param -n llite.*.fast_read=0
19226         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19227                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19228                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19229
19230         # verify that fast read is 4 times faster for cache read
19231         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19232                 error_not_in_vm "fast read was not 4 times faster: " \
19233                            "$t_fast vs $t_slow"
19234
19235         echo "Test 2: verify the performance between big and small read"
19236         $LCTL set_param -n llite.*.fast_read=1
19237
19238         # 1k non-cache read
19239         cancel_lru_locks osc
19240         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19241                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19242                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19243
19244         # 1M non-cache read
19245         cancel_lru_locks osc
19246         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19247                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19248                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19249
19250         # verify that big IO is not 4 times faster than small IO
19251         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19252                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19253
19254         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19255         rm -f $DIR/$tfile
19256 }
19257 run_test 248a "fast read verification"
19258
19259 test_248b() {
19260         # Default short_io_bytes=16384, try both smaller and larger sizes.
19261         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19262         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19263         echo "bs=53248 count=113 normal buffered write"
19264         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19265                 error "dd of initial data file failed"
19266         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19267
19268         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19269         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19270                 error "dd with sync normal writes failed"
19271         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19272
19273         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19274         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19275                 error "dd with sync small writes failed"
19276         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19277
19278         cancel_lru_locks osc
19279
19280         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19281         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19282         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19283         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19284                 iflag=direct || error "dd with O_DIRECT small read failed"
19285         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19286         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19287                 error "compare $TMP/$tfile.1 failed"
19288
19289         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19290         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19291
19292         # just to see what the maximum tunable value is, and test parsing
19293         echo "test invalid parameter 2MB"
19294         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19295                 error "too-large short_io_bytes allowed"
19296         echo "test maximum parameter 512KB"
19297         # if we can set a larger short_io_bytes, run test regardless of version
19298         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19299                 # older clients may not allow setting it this large, that's OK
19300                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19301                         skip "Need at least client version 2.13.50"
19302                 error "medium short_io_bytes failed"
19303         fi
19304         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19305         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19306
19307         echo "test large parameter 64KB"
19308         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19309         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19310
19311         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19312         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19313                 error "dd with sync large writes failed"
19314         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19315
19316         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19317         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19318         num=$((113 * 4096 / PAGE_SIZE))
19319         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19320         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19321                 error "dd with O_DIRECT large writes failed"
19322         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19323                 error "compare $DIR/$tfile.3 failed"
19324
19325         cancel_lru_locks osc
19326
19327         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19328         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19329                 error "dd with O_DIRECT large read failed"
19330         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19331                 error "compare $TMP/$tfile.2 failed"
19332
19333         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19334         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19335                 error "dd with O_DIRECT large read failed"
19336         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19337                 error "compare $TMP/$tfile.3 failed"
19338 }
19339 run_test 248b "test short_io read and write for both small and large sizes"
19340
19341 test_249() { # LU-7890
19342         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19343                 skip "Need at least version 2.8.54"
19344
19345         rm -f $DIR/$tfile
19346         $LFS setstripe -c 1 $DIR/$tfile
19347         # Offset 2T == 4k * 512M
19348         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19349                 error "dd to 2T offset failed"
19350 }
19351 run_test 249 "Write above 2T file size"
19352
19353 test_250() {
19354         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19355          && skip "no 16TB file size limit on ZFS"
19356
19357         $LFS setstripe -c 1 $DIR/$tfile
19358         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19359         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19360         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19361         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19362                 conv=notrunc,fsync && error "append succeeded"
19363         return 0
19364 }
19365 run_test 250 "Write above 16T limit"
19366
19367 test_251() {
19368         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19369
19370         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19371         #Skip once - writing the first stripe will succeed
19372         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19373         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19374                 error "short write happened"
19375
19376         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19377         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19378                 error "short read happened"
19379
19380         rm -f $DIR/$tfile
19381 }
19382 run_test 251 "Handling short read and write correctly"
19383
19384 test_252() {
19385         remote_mds_nodsh && skip "remote MDS with nodsh"
19386         remote_ost_nodsh && skip "remote OST with nodsh"
19387         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19388                 skip_env "ldiskfs only test"
19389         fi
19390
19391         local tgt
19392         local dev
19393         local out
19394         local uuid
19395         local num
19396         local gen
19397
19398         # check lr_reader on OST0000
19399         tgt=ost1
19400         dev=$(facet_device $tgt)
19401         out=$(do_facet $tgt $LR_READER $dev)
19402         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19403         echo "$out"
19404         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19405         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19406                 error "Invalid uuid returned by $LR_READER on target $tgt"
19407         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19408
19409         # check lr_reader -c on MDT0000
19410         tgt=mds1
19411         dev=$(facet_device $tgt)
19412         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19413                 skip "$LR_READER does not support additional options"
19414         fi
19415         out=$(do_facet $tgt $LR_READER -c $dev)
19416         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19417         echo "$out"
19418         num=$(echo "$out" | grep -c "mdtlov")
19419         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19420                 error "Invalid number of mdtlov clients returned by $LR_READER"
19421         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19422
19423         # check lr_reader -cr on MDT0000
19424         out=$(do_facet $tgt $LR_READER -cr $dev)
19425         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19426         echo "$out"
19427         echo "$out" | grep -q "^reply_data:$" ||
19428                 error "$LR_READER should have returned 'reply_data' section"
19429         num=$(echo "$out" | grep -c "client_generation")
19430         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19431 }
19432 run_test 252 "check lr_reader tool"
19433
19434 test_253() {
19435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19436         remote_mds_nodsh && skip "remote MDS with nodsh"
19437         remote_mgs_nodsh && skip "remote MGS with nodsh"
19438
19439         local ostidx=0
19440         local rc=0
19441         local ost_name=$(ostname_from_index $ostidx)
19442
19443         # on the mdt's osc
19444         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19445         do_facet $SINGLEMDS $LCTL get_param -n \
19446                 osp.$mdtosc_proc1.reserved_mb_high ||
19447                 skip  "remote MDS does not support reserved_mb_high"
19448
19449         rm -rf $DIR/$tdir
19450         wait_mds_ost_sync
19451         wait_delete_completed
19452         mkdir $DIR/$tdir
19453
19454         pool_add $TESTNAME || error "Pool creation failed"
19455         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19456
19457         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19458                 error "Setstripe failed"
19459
19460         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19461
19462         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19463                     grep "watermarks")
19464         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19465
19466         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19467                         osp.$mdtosc_proc1.prealloc_status)
19468         echo "prealloc_status $oa_status"
19469
19470         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19471                 error "File creation should fail"
19472
19473         #object allocation was stopped, but we still able to append files
19474         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19475                 oflag=append || error "Append failed"
19476
19477         rm -f $DIR/$tdir/$tfile.0
19478
19479         # For this test, we want to delete the files we created to go out of
19480         # space but leave the watermark, so we remain nearly out of space
19481         ost_watermarks_enospc_delete_files $tfile $ostidx
19482
19483         wait_delete_completed
19484
19485         sleep_maxage
19486
19487         for i in $(seq 10 12); do
19488                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19489                         2>/dev/null || error "File creation failed after rm"
19490         done
19491
19492         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19493                         osp.$mdtosc_proc1.prealloc_status)
19494         echo "prealloc_status $oa_status"
19495
19496         if (( oa_status != 0 )); then
19497                 error "Object allocation still disable after rm"
19498         fi
19499 }
19500 run_test 253 "Check object allocation limit"
19501
19502 test_254() {
19503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19504         remote_mds_nodsh && skip "remote MDS with nodsh"
19505         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19506                 skip "MDS does not support changelog_size"
19507
19508         local cl_user
19509         local MDT0=$(facet_svc $SINGLEMDS)
19510
19511         changelog_register || error "changelog_register failed"
19512
19513         changelog_clear 0 || error "changelog_clear failed"
19514
19515         local size1=$(do_facet $SINGLEMDS \
19516                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19517         echo "Changelog size $size1"
19518
19519         rm -rf $DIR/$tdir
19520         $LFS mkdir -i 0 $DIR/$tdir
19521         # change something
19522         mkdir -p $DIR/$tdir/pics/2008/zachy
19523         touch $DIR/$tdir/pics/2008/zachy/timestamp
19524         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19525         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19526         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19527         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19528         rm $DIR/$tdir/pics/desktop.jpg
19529
19530         local size2=$(do_facet $SINGLEMDS \
19531                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19532         echo "Changelog size after work $size2"
19533
19534         (( $size2 > $size1 )) ||
19535                 error "new Changelog size=$size2 less than old size=$size1"
19536 }
19537 run_test 254 "Check changelog size"
19538
19539 ladvise_no_type()
19540 {
19541         local type=$1
19542         local file=$2
19543
19544         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19545                 awk -F: '{print $2}' | grep $type > /dev/null
19546         if [ $? -ne 0 ]; then
19547                 return 0
19548         fi
19549         return 1
19550 }
19551
19552 ladvise_no_ioctl()
19553 {
19554         local file=$1
19555
19556         lfs ladvise -a willread $file > /dev/null 2>&1
19557         if [ $? -eq 0 ]; then
19558                 return 1
19559         fi
19560
19561         lfs ladvise -a willread $file 2>&1 |
19562                 grep "Inappropriate ioctl for device" > /dev/null
19563         if [ $? -eq 0 ]; then
19564                 return 0
19565         fi
19566         return 1
19567 }
19568
19569 percent() {
19570         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19571 }
19572
19573 # run a random read IO workload
19574 # usage: random_read_iops <filename> <filesize> <iosize>
19575 random_read_iops() {
19576         local file=$1
19577         local fsize=$2
19578         local iosize=${3:-4096}
19579
19580         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19581                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19582 }
19583
19584 drop_file_oss_cache() {
19585         local file="$1"
19586         local nodes="$2"
19587
19588         $LFS ladvise -a dontneed $file 2>/dev/null ||
19589                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19590 }
19591
19592 ladvise_willread_performance()
19593 {
19594         local repeat=10
19595         local average_origin=0
19596         local average_cache=0
19597         local average_ladvise=0
19598
19599         for ((i = 1; i <= $repeat; i++)); do
19600                 echo "Iter $i/$repeat: reading without willread hint"
19601                 cancel_lru_locks osc
19602                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19603                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19604                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19605                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19606
19607                 cancel_lru_locks osc
19608                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19609                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19610                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19611
19612                 cancel_lru_locks osc
19613                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19614                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19615                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19616                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19617                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19618         done
19619         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19620         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19621         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19622
19623         speedup_cache=$(percent $average_cache $average_origin)
19624         speedup_ladvise=$(percent $average_ladvise $average_origin)
19625
19626         echo "Average uncached read: $average_origin"
19627         echo "Average speedup with OSS cached read: " \
19628                 "$average_cache = +$speedup_cache%"
19629         echo "Average speedup with ladvise willread: " \
19630                 "$average_ladvise = +$speedup_ladvise%"
19631
19632         local lowest_speedup=20
19633         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19634                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19635                         "got $average_cache%. Skipping ladvise willread check."
19636                 return 0
19637         fi
19638
19639         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19640         # it is still good to run until then to exercise 'ladvise willread'
19641         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19642                 [ "$ost1_FSTYPE" = "zfs" ] &&
19643                 echo "osd-zfs does not support dontneed or drop_caches" &&
19644                 return 0
19645
19646         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19647         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19648                 error_not_in_vm "Speedup with willread is less than " \
19649                         "$lowest_speedup%, got $average_ladvise%"
19650 }
19651
19652 test_255a() {
19653         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19654                 skip "lustre < 2.8.54 does not support ladvise "
19655         remote_ost_nodsh && skip "remote OST with nodsh"
19656
19657         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19658
19659         ladvise_no_type willread $DIR/$tfile &&
19660                 skip "willread ladvise is not supported"
19661
19662         ladvise_no_ioctl $DIR/$tfile &&
19663                 skip "ladvise ioctl is not supported"
19664
19665         local size_mb=100
19666         local size=$((size_mb * 1048576))
19667         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19668                 error "dd to $DIR/$tfile failed"
19669
19670         lfs ladvise -a willread $DIR/$tfile ||
19671                 error "Ladvise failed with no range argument"
19672
19673         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19674                 error "Ladvise failed with no -l or -e argument"
19675
19676         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19677                 error "Ladvise failed with only -e argument"
19678
19679         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19680                 error "Ladvise failed with only -l argument"
19681
19682         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19683                 error "End offset should not be smaller than start offset"
19684
19685         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19686                 error "End offset should not be equal to start offset"
19687
19688         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19689                 error "Ladvise failed with overflowing -s argument"
19690
19691         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19692                 error "Ladvise failed with overflowing -e argument"
19693
19694         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19695                 error "Ladvise failed with overflowing -l argument"
19696
19697         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19698                 error "Ladvise succeeded with conflicting -l and -e arguments"
19699
19700         echo "Synchronous ladvise should wait"
19701         local delay=4
19702 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19703         do_nodes $(comma_list $(osts_nodes)) \
19704                 $LCTL set_param fail_val=$delay fail_loc=0x237
19705
19706         local start_ts=$SECONDS
19707         lfs ladvise -a willread $DIR/$tfile ||
19708                 error "Ladvise failed with no range argument"
19709         local end_ts=$SECONDS
19710         local inteval_ts=$((end_ts - start_ts))
19711
19712         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19713                 error "Synchronous advice didn't wait reply"
19714         fi
19715
19716         echo "Asynchronous ladvise shouldn't wait"
19717         local start_ts=$SECONDS
19718         lfs ladvise -a willread -b $DIR/$tfile ||
19719                 error "Ladvise failed with no range argument"
19720         local end_ts=$SECONDS
19721         local inteval_ts=$((end_ts - start_ts))
19722
19723         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19724                 error "Asynchronous advice blocked"
19725         fi
19726
19727         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19728         ladvise_willread_performance
19729 }
19730 run_test 255a "check 'lfs ladvise -a willread'"
19731
19732 facet_meminfo() {
19733         local facet=$1
19734         local info=$2
19735
19736         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19737 }
19738
19739 test_255b() {
19740         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19741                 skip "lustre < 2.8.54 does not support ladvise "
19742         remote_ost_nodsh && skip "remote OST with nodsh"
19743
19744         lfs setstripe -c 1 -i 0 $DIR/$tfile
19745
19746         ladvise_no_type dontneed $DIR/$tfile &&
19747                 skip "dontneed ladvise is not supported"
19748
19749         ladvise_no_ioctl $DIR/$tfile &&
19750                 skip "ladvise ioctl is not supported"
19751
19752         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19753                 [ "$ost1_FSTYPE" = "zfs" ] &&
19754                 skip "zfs-osd does not support 'ladvise dontneed'"
19755
19756         local size_mb=100
19757         local size=$((size_mb * 1048576))
19758         # In order to prevent disturbance of other processes, only check 3/4
19759         # of the memory usage
19760         local kibibytes=$((size_mb * 1024 * 3 / 4))
19761
19762         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19763                 error "dd to $DIR/$tfile failed"
19764
19765         #force write to complete before dropping OST cache & checking memory
19766         sync
19767
19768         local total=$(facet_meminfo ost1 MemTotal)
19769         echo "Total memory: $total KiB"
19770
19771         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19772         local before_read=$(facet_meminfo ost1 Cached)
19773         echo "Cache used before read: $before_read KiB"
19774
19775         lfs ladvise -a willread $DIR/$tfile ||
19776                 error "Ladvise willread failed"
19777         local after_read=$(facet_meminfo ost1 Cached)
19778         echo "Cache used after read: $after_read KiB"
19779
19780         lfs ladvise -a dontneed $DIR/$tfile ||
19781                 error "Ladvise dontneed again failed"
19782         local no_read=$(facet_meminfo ost1 Cached)
19783         echo "Cache used after dontneed ladvise: $no_read KiB"
19784
19785         if [ $total -lt $((before_read + kibibytes)) ]; then
19786                 echo "Memory is too small, abort checking"
19787                 return 0
19788         fi
19789
19790         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19791                 error "Ladvise willread should use more memory" \
19792                         "than $kibibytes KiB"
19793         fi
19794
19795         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19796                 error "Ladvise dontneed should release more memory" \
19797                         "than $kibibytes KiB"
19798         fi
19799 }
19800 run_test 255b "check 'lfs ladvise -a dontneed'"
19801
19802 test_255c() {
19803         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19804                 skip "lustre < 2.10.50 does not support lockahead"
19805
19806         local count
19807         local new_count
19808         local difference
19809         local i
19810         local rc
19811
19812         test_mkdir -p $DIR/$tdir
19813         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19814
19815         #test 10 returns only success/failure
19816         i=10
19817         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19818         rc=$?
19819         if [ $rc -eq 255 ]; then
19820                 error "Ladvise test${i} failed, ${rc}"
19821         fi
19822
19823         #test 11 counts lock enqueue requests, all others count new locks
19824         i=11
19825         count=$(do_facet ost1 \
19826                 $LCTL get_param -n ost.OSS.ost.stats)
19827         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19828
19829         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19830         rc=$?
19831         if [ $rc -eq 255 ]; then
19832                 error "Ladvise test${i} failed, ${rc}"
19833         fi
19834
19835         new_count=$(do_facet ost1 \
19836                 $LCTL get_param -n ost.OSS.ost.stats)
19837         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19838                    awk '{ print $2 }')
19839
19840         difference="$((new_count - count))"
19841         if [ $difference -ne $rc ]; then
19842                 error "Ladvise test${i}, bad enqueue count, returned " \
19843                       "${rc}, actual ${difference}"
19844         fi
19845
19846         for i in $(seq 12 21); do
19847                 # If we do not do this, we run the risk of having too many
19848                 # locks and starting lock cancellation while we are checking
19849                 # lock counts.
19850                 cancel_lru_locks osc
19851
19852                 count=$($LCTL get_param -n \
19853                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19854
19855                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19856                 rc=$?
19857                 if [ $rc -eq 255 ]; then
19858                         error "Ladvise test ${i} failed, ${rc}"
19859                 fi
19860
19861                 new_count=$($LCTL get_param -n \
19862                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19863                 difference="$((new_count - count))"
19864
19865                 # Test 15 output is divided by 100 to map down to valid return
19866                 if [ $i -eq 15 ]; then
19867                         rc="$((rc * 100))"
19868                 fi
19869
19870                 if [ $difference -ne $rc ]; then
19871                         error "Ladvise test ${i}, bad lock count, returned " \
19872                               "${rc}, actual ${difference}"
19873                 fi
19874         done
19875
19876         #test 22 returns only success/failure
19877         i=22
19878         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19879         rc=$?
19880         if [ $rc -eq 255 ]; then
19881                 error "Ladvise test${i} failed, ${rc}"
19882         fi
19883 }
19884 run_test 255c "suite of ladvise lockahead tests"
19885
19886 test_256() {
19887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19888         remote_mds_nodsh && skip "remote MDS with nodsh"
19889         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19890         changelog_users $SINGLEMDS | grep "^cl" &&
19891                 skip "active changelog user"
19892
19893         local cl_user
19894         local cat_sl
19895         local mdt_dev
19896
19897         mdt_dev=$(mdsdevname 1)
19898         echo $mdt_dev
19899
19900         changelog_register || error "changelog_register failed"
19901
19902         rm -rf $DIR/$tdir
19903         mkdir -p $DIR/$tdir
19904
19905         changelog_clear 0 || error "changelog_clear failed"
19906
19907         # change something
19908         touch $DIR/$tdir/{1..10}
19909
19910         # stop the MDT
19911         stop $SINGLEMDS || error "Fail to stop MDT"
19912
19913         # remount the MDT
19914
19915         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19916
19917         #after mount new plainllog is used
19918         touch $DIR/$tdir/{11..19}
19919         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19920         stack_trap "rm -f $tmpfile"
19921         cat_sl=$(do_facet $SINGLEMDS "sync; \
19922                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19923                  llog_reader $tmpfile | grep -c type=1064553b")
19924         do_facet $SINGLEMDS llog_reader $tmpfile
19925
19926         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19927
19928         changelog_clear 0 || error "changelog_clear failed"
19929
19930         cat_sl=$(do_facet $SINGLEMDS "sync; \
19931                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19932                  llog_reader $tmpfile | grep -c type=1064553b")
19933
19934         if (( cat_sl == 2 )); then
19935                 error "Empty plain llog was not deleted from changelog catalog"
19936         elif (( cat_sl != 1 )); then
19937                 error "Active plain llog shouldn't be deleted from catalog"
19938         fi
19939 }
19940 run_test 256 "Check llog delete for empty and not full state"
19941
19942 test_257() {
19943         remote_mds_nodsh && skip "remote MDS with nodsh"
19944         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19945                 skip "Need MDS version at least 2.8.55"
19946
19947         test_mkdir $DIR/$tdir
19948
19949         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19950                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19951         stat $DIR/$tdir
19952
19953 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19954         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19955         local facet=mds$((mdtidx + 1))
19956         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19957         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19958
19959         stop $facet || error "stop MDS failed"
19960         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19961                 error "start MDS fail"
19962         wait_recovery_complete $facet
19963 }
19964 run_test 257 "xattr locks are not lost"
19965
19966 # Verify we take the i_mutex when security requires it
19967 test_258a() {
19968 #define OBD_FAIL_IMUTEX_SEC 0x141c
19969         $LCTL set_param fail_loc=0x141c
19970         touch $DIR/$tfile
19971         chmod u+s $DIR/$tfile
19972         chmod a+rwx $DIR/$tfile
19973         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19974         RC=$?
19975         if [ $RC -ne 0 ]; then
19976                 error "error, failed to take i_mutex, rc=$?"
19977         fi
19978         rm -f $DIR/$tfile
19979 }
19980 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19981
19982 # Verify we do NOT take the i_mutex in the normal case
19983 test_258b() {
19984 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19985         $LCTL set_param fail_loc=0x141d
19986         touch $DIR/$tfile
19987         chmod a+rwx $DIR
19988         chmod a+rw $DIR/$tfile
19989         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19990         RC=$?
19991         if [ $RC -ne 0 ]; then
19992                 error "error, took i_mutex unnecessarily, rc=$?"
19993         fi
19994         rm -f $DIR/$tfile
19995
19996 }
19997 run_test 258b "verify i_mutex security behavior"
19998
19999 test_259() {
20000         local file=$DIR/$tfile
20001         local before
20002         local after
20003
20004         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20005
20006         stack_trap "rm -f $file" EXIT
20007
20008         wait_delete_completed
20009         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20010         echo "before: $before"
20011
20012         $LFS setstripe -i 0 -c 1 $file
20013         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20014         sync_all_data
20015         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20016         echo "after write: $after"
20017
20018 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20019         do_facet ost1 $LCTL set_param fail_loc=0x2301
20020         $TRUNCATE $file 0
20021         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20022         echo "after truncate: $after"
20023
20024         stop ost1
20025         do_facet ost1 $LCTL set_param fail_loc=0
20026         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20027         sleep 2
20028         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20029         echo "after restart: $after"
20030         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20031                 error "missing truncate?"
20032
20033         return 0
20034 }
20035 run_test 259 "crash at delayed truncate"
20036
20037 test_260() {
20038 #define OBD_FAIL_MDC_CLOSE               0x806
20039         $LCTL set_param fail_loc=0x80000806
20040         touch $DIR/$tfile
20041
20042 }
20043 run_test 260 "Check mdc_close fail"
20044
20045 ### Data-on-MDT sanity tests ###
20046 test_270a() {
20047         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20048                 skip "Need MDS version at least 2.10.55 for DoM"
20049
20050         # create DoM file
20051         local dom=$DIR/$tdir/dom_file
20052         local tmp=$DIR/$tdir/tmp_file
20053
20054         mkdir -p $DIR/$tdir
20055
20056         # basic checks for DoM component creation
20057         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20058                 error "Can set MDT layout to non-first entry"
20059
20060         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20061                 error "Can define multiple entries as MDT layout"
20062
20063         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20064
20065         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20066         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20067         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20068
20069         local mdtidx=$($LFS getstripe -m $dom)
20070         local mdtname=MDT$(printf %04x $mdtidx)
20071         local facet=mds$((mdtidx + 1))
20072         local space_check=1
20073
20074         # Skip free space checks with ZFS
20075         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20076
20077         # write
20078         sync
20079         local size_tmp=$((65536 * 3))
20080         local mdtfree1=$(do_facet $facet \
20081                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20082
20083         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20084         # check also direct IO along write
20085         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20086         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20087         sync
20088         cmp $tmp $dom || error "file data is different"
20089         [ $(stat -c%s $dom) == $size_tmp ] ||
20090                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20091         if [ $space_check == 1 ]; then
20092                 local mdtfree2=$(do_facet $facet \
20093                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20094
20095                 # increase in usage from by $size_tmp
20096                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20097                         error "MDT free space wrong after write: " \
20098                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20099         fi
20100
20101         # truncate
20102         local size_dom=10000
20103
20104         $TRUNCATE $dom $size_dom
20105         [ $(stat -c%s $dom) == $size_dom ] ||
20106                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20107         if [ $space_check == 1 ]; then
20108                 mdtfree1=$(do_facet $facet \
20109                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20110                 # decrease in usage from $size_tmp to new $size_dom
20111                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20112                   $(((size_tmp - size_dom) / 1024)) ] ||
20113                         error "MDT free space is wrong after truncate: " \
20114                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20115         fi
20116
20117         # append
20118         cat $tmp >> $dom
20119         sync
20120         size_dom=$((size_dom + size_tmp))
20121         [ $(stat -c%s $dom) == $size_dom ] ||
20122                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20123         if [ $space_check == 1 ]; then
20124                 mdtfree2=$(do_facet $facet \
20125                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20126                 # increase in usage by $size_tmp from previous
20127                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20128                         error "MDT free space is wrong after append: " \
20129                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20130         fi
20131
20132         # delete
20133         rm $dom
20134         if [ $space_check == 1 ]; then
20135                 mdtfree1=$(do_facet $facet \
20136                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20137                 # decrease in usage by $size_dom from previous
20138                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20139                         error "MDT free space is wrong after removal: " \
20140                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20141         fi
20142
20143         # combined striping
20144         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20145                 error "Can't create DoM + OST striping"
20146
20147         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20148         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20149         # check also direct IO along write
20150         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20151         sync
20152         cmp $tmp $dom || error "file data is different"
20153         [ $(stat -c%s $dom) == $size_tmp ] ||
20154                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20155         rm $dom $tmp
20156
20157         return 0
20158 }
20159 run_test 270a "DoM: basic functionality tests"
20160
20161 test_270b() {
20162         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20163                 skip "Need MDS version at least 2.10.55"
20164
20165         local dom=$DIR/$tdir/dom_file
20166         local max_size=1048576
20167
20168         mkdir -p $DIR/$tdir
20169         $LFS setstripe -E $max_size -L mdt $dom
20170
20171         # truncate over the limit
20172         $TRUNCATE $dom $(($max_size + 1)) &&
20173                 error "successful truncate over the maximum size"
20174         # write over the limit
20175         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20176                 error "successful write over the maximum size"
20177         # append over the limit
20178         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20179         echo "12345" >> $dom && error "successful append over the maximum size"
20180         rm $dom
20181
20182         return 0
20183 }
20184 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20185
20186 test_270c() {
20187         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20188                 skip "Need MDS version at least 2.10.55"
20189
20190         mkdir -p $DIR/$tdir
20191         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20192
20193         # check files inherit DoM EA
20194         touch $DIR/$tdir/first
20195         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20196                 error "bad pattern"
20197         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20198                 error "bad stripe count"
20199         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20200                 error "bad stripe size"
20201
20202         # check directory inherits DoM EA and uses it as default
20203         mkdir $DIR/$tdir/subdir
20204         touch $DIR/$tdir/subdir/second
20205         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20206                 error "bad pattern in sub-directory"
20207         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20208                 error "bad stripe count in sub-directory"
20209         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20210                 error "bad stripe size in sub-directory"
20211         return 0
20212 }
20213 run_test 270c "DoM: DoM EA inheritance tests"
20214
20215 test_270d() {
20216         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20217                 skip "Need MDS version at least 2.10.55"
20218
20219         mkdir -p $DIR/$tdir
20220         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20221
20222         # inherit default DoM striping
20223         mkdir $DIR/$tdir/subdir
20224         touch $DIR/$tdir/subdir/f1
20225
20226         # change default directory striping
20227         $LFS setstripe -c 1 $DIR/$tdir/subdir
20228         touch $DIR/$tdir/subdir/f2
20229         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20230                 error "wrong default striping in file 2"
20231         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20232                 error "bad pattern in file 2"
20233         return 0
20234 }
20235 run_test 270d "DoM: change striping from DoM to RAID0"
20236
20237 test_270e() {
20238         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20239                 skip "Need MDS version at least 2.10.55"
20240
20241         mkdir -p $DIR/$tdir/dom
20242         mkdir -p $DIR/$tdir/norm
20243         DOMFILES=20
20244         NORMFILES=10
20245         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20246         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20247
20248         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20249         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20250
20251         # find DoM files by layout
20252         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20253         [ $NUM -eq  $DOMFILES ] ||
20254                 error "lfs find -L: found $NUM, expected $DOMFILES"
20255         echo "Test 1: lfs find 20 DOM files by layout: OK"
20256
20257         # there should be 1 dir with default DOM striping
20258         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20259         [ $NUM -eq  1 ] ||
20260                 error "lfs find -L: found $NUM, expected 1 dir"
20261         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20262
20263         # find DoM files by stripe size
20264         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20265         [ $NUM -eq  $DOMFILES ] ||
20266                 error "lfs find -S: found $NUM, expected $DOMFILES"
20267         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20268
20269         # find files by stripe offset except DoM files
20270         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20271         [ $NUM -eq  $NORMFILES ] ||
20272                 error "lfs find -i: found $NUM, expected $NORMFILES"
20273         echo "Test 5: lfs find no DOM files by stripe index: OK"
20274         return 0
20275 }
20276 run_test 270e "DoM: lfs find with DoM files test"
20277
20278 test_270f() {
20279         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20280                 skip "Need MDS version at least 2.10.55"
20281
20282         local mdtname=${FSNAME}-MDT0000-mdtlov
20283         local dom=$DIR/$tdir/dom_file
20284         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20285                                                 lod.$mdtname.dom_stripesize)
20286         local dom_limit=131072
20287
20288         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20289         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20290                                                 lod.$mdtname.dom_stripesize)
20291         [ ${dom_limit} -eq ${dom_current} ] ||
20292                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20293
20294         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20295         $LFS setstripe -d $DIR/$tdir
20296         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20297                 error "Can't set directory default striping"
20298
20299         # exceed maximum stripe size
20300         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20301                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20302         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20303                 error "Able to create DoM component size more than LOD limit"
20304
20305         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20306         dom_current=$(do_facet mds1 $LCTL get_param -n \
20307                                                 lod.$mdtname.dom_stripesize)
20308         [ 0 -eq ${dom_current} ] ||
20309                 error "Can't set zero DoM stripe limit"
20310         rm $dom
20311
20312         # attempt to create DoM file on server with disabled DoM should
20313         # remove DoM entry from layout and be succeed
20314         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20315                 error "Can't create DoM file (DoM is disabled)"
20316         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20317                 error "File has DoM component while DoM is disabled"
20318         rm $dom
20319
20320         # attempt to create DoM file with only DoM stripe should return error
20321         $LFS setstripe -E $dom_limit -L mdt $dom &&
20322                 error "Able to create DoM-only file while DoM is disabled"
20323
20324         # too low values to be aligned with smallest stripe size 64K
20325         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20326         dom_current=$(do_facet mds1 $LCTL get_param -n \
20327                                                 lod.$mdtname.dom_stripesize)
20328         [ 30000 -eq ${dom_current} ] &&
20329                 error "Can set too small DoM stripe limit"
20330
20331         # 64K is a minimal stripe size in Lustre, expect limit of that size
20332         [ 65536 -eq ${dom_current} ] ||
20333                 error "Limit is not set to 64K but ${dom_current}"
20334
20335         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20336         dom_current=$(do_facet mds1 $LCTL get_param -n \
20337                                                 lod.$mdtname.dom_stripesize)
20338         echo $dom_current
20339         [ 2147483648 -eq ${dom_current} ] &&
20340                 error "Can set too large DoM stripe limit"
20341
20342         do_facet mds1 $LCTL set_param -n \
20343                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20344         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20345                 error "Can't create DoM component size after limit change"
20346         do_facet mds1 $LCTL set_param -n \
20347                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20348         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20349                 error "Can't create DoM file after limit decrease"
20350         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20351                 error "Can create big DoM component after limit decrease"
20352         touch ${dom}_def ||
20353                 error "Can't create file with old default layout"
20354
20355         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20356         return 0
20357 }
20358 run_test 270f "DoM: maximum DoM stripe size checks"
20359
20360 test_270g() {
20361         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20362                 skip "Need MDS version at least 2.13.52"
20363         local dom=$DIR/$tdir/$tfile
20364
20365         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20366         local lodname=${FSNAME}-MDT0000-mdtlov
20367
20368         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20369         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20370         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20371         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20372
20373         local dom_limit=1024
20374         local dom_threshold="50%"
20375
20376         $LFS setstripe -d $DIR/$tdir
20377         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20378                 error "Can't set directory default striping"
20379
20380         do_facet mds1 $LCTL set_param -n \
20381                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20382         # set 0 threshold and create DOM file to change tunable stripesize
20383         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20384         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20385                 error "Failed to create $dom file"
20386         # now tunable dom_cur_stripesize should reach maximum
20387         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20388                                         lod.${lodname}.dom_stripesize_cur_kb)
20389         [[ $dom_current == $dom_limit ]] ||
20390                 error "Current DOM stripesize is not maximum"
20391         rm $dom
20392
20393         # set threshold for further tests
20394         do_facet mds1 $LCTL set_param -n \
20395                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20396         echo "DOM threshold is $dom_threshold free space"
20397         local dom_def
20398         local dom_set
20399         # Spoof bfree to exceed threshold
20400         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20401         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20402         for spfree in 40 20 0 15 30 55; do
20403                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20404                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20405                         error "Failed to create $dom file"
20406                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20407                                         lod.${lodname}.dom_stripesize_cur_kb)
20408                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20409                 [[ $dom_def != $dom_current ]] ||
20410                         error "Default stripe size was not changed"
20411                 if [[ $spfree > 0 ]] ; then
20412                         dom_set=$($LFS getstripe -S $dom)
20413                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20414                                 error "DOM component size is still old"
20415                 else
20416                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20417                                 error "DoM component is set with no free space"
20418                 fi
20419                 rm $dom
20420                 dom_current=$dom_def
20421         done
20422 }
20423 run_test 270g "DoM: default DoM stripe size depends on free space"
20424
20425 test_270h() {
20426         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20427                 skip "Need MDS version at least 2.13.53"
20428
20429         local mdtname=${FSNAME}-MDT0000-mdtlov
20430         local dom=$DIR/$tdir/$tfile
20431         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20432
20433         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20434         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20435
20436         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20437         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20438                 error "can't create OST file"
20439         # mirrored file with DOM entry in the second mirror
20440         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20441                 error "can't create mirror with DoM component"
20442
20443         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20444
20445         # DOM component in the middle and has other enries in the same mirror,
20446         # should succeed but lost DoM component
20447         $LFS setstripe --copy=${dom}_1 $dom ||
20448                 error "Can't create file from OST|DOM mirror layout"
20449         # check new file has no DoM layout after all
20450         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20451                 error "File has DoM component while DoM is disabled"
20452 }
20453 run_test 270h "DoM: DoM stripe removal when disabled on server"
20454
20455 test_271a() {
20456         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20457                 skip "Need MDS version at least 2.10.55"
20458
20459         local dom=$DIR/$tdir/dom
20460
20461         mkdir -p $DIR/$tdir
20462
20463         $LFS setstripe -E 1024K -L mdt $dom
20464
20465         lctl set_param -n mdc.*.stats=clear
20466         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20467         cat $dom > /dev/null
20468         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20469         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20470         ls $dom
20471         rm -f $dom
20472 }
20473 run_test 271a "DoM: data is cached for read after write"
20474
20475 test_271b() {
20476         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20477                 skip "Need MDS version at least 2.10.55"
20478
20479         local dom=$DIR/$tdir/dom
20480
20481         mkdir -p $DIR/$tdir
20482
20483         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20484
20485         lctl set_param -n mdc.*.stats=clear
20486         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20487         cancel_lru_locks mdc
20488         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20489         # second stat to check size is cached on client
20490         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20491         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20492         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20493         rm -f $dom
20494 }
20495 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20496
20497 test_271ba() {
20498         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20499                 skip "Need MDS version at least 2.10.55"
20500
20501         local dom=$DIR/$tdir/dom
20502
20503         mkdir -p $DIR/$tdir
20504
20505         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20506
20507         lctl set_param -n mdc.*.stats=clear
20508         lctl set_param -n osc.*.stats=clear
20509         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20510         cancel_lru_locks mdc
20511         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20512         # second stat to check size is cached on client
20513         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20514         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20515         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20516         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20517         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20518         rm -f $dom
20519 }
20520 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20521
20522
20523 get_mdc_stats() {
20524         local mdtidx=$1
20525         local param=$2
20526         local mdt=MDT$(printf %04x $mdtidx)
20527
20528         if [ -z $param ]; then
20529                 lctl get_param -n mdc.*$mdt*.stats
20530         else
20531                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20532         fi
20533 }
20534
20535 test_271c() {
20536         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20537                 skip "Need MDS version at least 2.10.55"
20538
20539         local dom=$DIR/$tdir/dom
20540
20541         mkdir -p $DIR/$tdir
20542
20543         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20544
20545         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20546         local facet=mds$((mdtidx + 1))
20547
20548         cancel_lru_locks mdc
20549         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20550         createmany -o $dom 1000
20551         lctl set_param -n mdc.*.stats=clear
20552         smalliomany -w $dom 1000 200
20553         get_mdc_stats $mdtidx
20554         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20555         # Each file has 1 open, 1 IO enqueues, total 2000
20556         # but now we have also +1 getxattr for security.capability, total 3000
20557         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20558         unlinkmany $dom 1000
20559
20560         cancel_lru_locks mdc
20561         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20562         createmany -o $dom 1000
20563         lctl set_param -n mdc.*.stats=clear
20564         smalliomany -w $dom 1000 200
20565         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20566         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20567         # for OPEN and IO lock.
20568         [ $((enq - enq_2)) -ge 1000 ] ||
20569                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20570         unlinkmany $dom 1000
20571         return 0
20572 }
20573 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20574
20575 cleanup_271def_tests() {
20576         trap 0
20577         rm -f $1
20578 }
20579
20580 test_271d() {
20581         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20582                 skip "Need MDS version at least 2.10.57"
20583
20584         local dom=$DIR/$tdir/dom
20585         local tmp=$TMP/$tfile
20586         trap "cleanup_271def_tests $tmp" EXIT
20587
20588         mkdir -p $DIR/$tdir
20589
20590         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20591
20592         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20593
20594         cancel_lru_locks mdc
20595         dd if=/dev/urandom of=$tmp bs=1000 count=1
20596         dd if=$tmp of=$dom bs=1000 count=1
20597         cancel_lru_locks mdc
20598
20599         cat /etc/hosts >> $tmp
20600         lctl set_param -n mdc.*.stats=clear
20601
20602         # append data to the same file it should update local page
20603         echo "Append to the same page"
20604         cat /etc/hosts >> $dom
20605         local num=$(get_mdc_stats $mdtidx ost_read)
20606         local ra=$(get_mdc_stats $mdtidx req_active)
20607         local rw=$(get_mdc_stats $mdtidx req_waittime)
20608
20609         [ -z $num ] || error "$num READ RPC occured"
20610         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20611         echo "... DONE"
20612
20613         # compare content
20614         cmp $tmp $dom || error "file miscompare"
20615
20616         cancel_lru_locks mdc
20617         lctl set_param -n mdc.*.stats=clear
20618
20619         echo "Open and read file"
20620         cat $dom > /dev/null
20621         local num=$(get_mdc_stats $mdtidx ost_read)
20622         local ra=$(get_mdc_stats $mdtidx req_active)
20623         local rw=$(get_mdc_stats $mdtidx req_waittime)
20624
20625         [ -z $num ] || error "$num READ RPC occured"
20626         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20627         echo "... DONE"
20628
20629         # compare content
20630         cmp $tmp $dom || error "file miscompare"
20631
20632         return 0
20633 }
20634 run_test 271d "DoM: read on open (1K file in reply buffer)"
20635
20636 test_271f() {
20637         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20638                 skip "Need MDS version at least 2.10.57"
20639
20640         local dom=$DIR/$tdir/dom
20641         local tmp=$TMP/$tfile
20642         trap "cleanup_271def_tests $tmp" EXIT
20643
20644         mkdir -p $DIR/$tdir
20645
20646         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20647
20648         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20649
20650         cancel_lru_locks mdc
20651         dd if=/dev/urandom of=$tmp bs=265000 count=1
20652         dd if=$tmp of=$dom bs=265000 count=1
20653         cancel_lru_locks mdc
20654         cat /etc/hosts >> $tmp
20655         lctl set_param -n mdc.*.stats=clear
20656
20657         echo "Append to the same page"
20658         cat /etc/hosts >> $dom
20659         local num=$(get_mdc_stats $mdtidx ost_read)
20660         local ra=$(get_mdc_stats $mdtidx req_active)
20661         local rw=$(get_mdc_stats $mdtidx req_waittime)
20662
20663         [ -z $num ] || error "$num READ RPC occured"
20664         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20665         echo "... DONE"
20666
20667         # compare content
20668         cmp $tmp $dom || error "file miscompare"
20669
20670         cancel_lru_locks mdc
20671         lctl set_param -n mdc.*.stats=clear
20672
20673         echo "Open and read file"
20674         cat $dom > /dev/null
20675         local num=$(get_mdc_stats $mdtidx ost_read)
20676         local ra=$(get_mdc_stats $mdtidx req_active)
20677         local rw=$(get_mdc_stats $mdtidx req_waittime)
20678
20679         [ -z $num ] && num=0
20680         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20681         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20682         echo "... DONE"
20683
20684         # compare content
20685         cmp $tmp $dom || error "file miscompare"
20686
20687         return 0
20688 }
20689 run_test 271f "DoM: read on open (200K file and read tail)"
20690
20691 test_271g() {
20692         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20693                 skip "Skipping due to old client or server version"
20694
20695         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20696         # to get layout
20697         $CHECKSTAT -t file $DIR1/$tfile
20698
20699         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20700         MULTIOP_PID=$!
20701         sleep 1
20702         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20703         $LCTL set_param fail_loc=0x80000314
20704         rm $DIR1/$tfile || error "Unlink fails"
20705         RC=$?
20706         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20707         [ $RC -eq 0 ] || error "Failed write to stale object"
20708 }
20709 run_test 271g "Discard DoM data vs client flush race"
20710
20711 test_272a() {
20712         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20713                 skip "Need MDS version at least 2.11.50"
20714
20715         local dom=$DIR/$tdir/dom
20716         mkdir -p $DIR/$tdir
20717
20718         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20719         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20720                 error "failed to write data into $dom"
20721         local old_md5=$(md5sum $dom)
20722
20723         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20724                 error "failed to migrate to the same DoM component"
20725
20726         local new_md5=$(md5sum $dom)
20727
20728         [ "$old_md5" == "$new_md5" ] ||
20729                 error "md5sum differ: $old_md5, $new_md5"
20730
20731         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20732                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20733 }
20734 run_test 272a "DoM migration: new layout with the same DOM component"
20735
20736 test_272b() {
20737         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20738                 skip "Need MDS version at least 2.11.50"
20739
20740         local dom=$DIR/$tdir/dom
20741         mkdir -p $DIR/$tdir
20742         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20743
20744         local mdtidx=$($LFS getstripe -m $dom)
20745         local mdtname=MDT$(printf %04x $mdtidx)
20746         local facet=mds$((mdtidx + 1))
20747
20748         local mdtfree1=$(do_facet $facet \
20749                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20750         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20751                 error "failed to write data into $dom"
20752         local old_md5=$(md5sum $dom)
20753         cancel_lru_locks mdc
20754         local mdtfree1=$(do_facet $facet \
20755                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20756
20757         $LFS migrate -c2 $dom ||
20758                 error "failed to migrate to the new composite layout"
20759         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20760                 error "MDT stripe was not removed"
20761
20762         cancel_lru_locks mdc
20763         local new_md5=$(md5sum $dom)
20764         [ "$old_md5" == "$new_md5" ] ||
20765                 error "$old_md5 != $new_md5"
20766
20767         # Skip free space checks with ZFS
20768         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20769                 local mdtfree2=$(do_facet $facet \
20770                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20771                 [ $mdtfree2 -gt $mdtfree1 ] ||
20772                         error "MDT space is not freed after migration"
20773         fi
20774         return 0
20775 }
20776 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20777
20778 test_272c() {
20779         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20780                 skip "Need MDS version at least 2.11.50"
20781
20782         local dom=$DIR/$tdir/$tfile
20783         mkdir -p $DIR/$tdir
20784         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20785
20786         local mdtidx=$($LFS getstripe -m $dom)
20787         local mdtname=MDT$(printf %04x $mdtidx)
20788         local facet=mds$((mdtidx + 1))
20789
20790         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20791                 error "failed to write data into $dom"
20792         local old_md5=$(md5sum $dom)
20793         cancel_lru_locks mdc
20794         local mdtfree1=$(do_facet $facet \
20795                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20796
20797         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20798                 error "failed to migrate to the new composite layout"
20799         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20800                 error "MDT stripe was not removed"
20801
20802         cancel_lru_locks mdc
20803         local new_md5=$(md5sum $dom)
20804         [ "$old_md5" == "$new_md5" ] ||
20805                 error "$old_md5 != $new_md5"
20806
20807         # Skip free space checks with ZFS
20808         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20809                 local mdtfree2=$(do_facet $facet \
20810                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20811                 [ $mdtfree2 -gt $mdtfree1 ] ||
20812                         error "MDS space is not freed after migration"
20813         fi
20814         return 0
20815 }
20816 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20817
20818 test_272d() {
20819         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20820                 skip "Need MDS version at least 2.12.55"
20821
20822         local dom=$DIR/$tdir/$tfile
20823         mkdir -p $DIR/$tdir
20824         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20825
20826         local mdtidx=$($LFS getstripe -m $dom)
20827         local mdtname=MDT$(printf %04x $mdtidx)
20828         local facet=mds$((mdtidx + 1))
20829
20830         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20831                 error "failed to write data into $dom"
20832         local old_md5=$(md5sum $dom)
20833         cancel_lru_locks mdc
20834         local mdtfree1=$(do_facet $facet \
20835                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20836
20837         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20838                 error "failed mirroring to the new composite layout"
20839         $LFS mirror resync $dom ||
20840                 error "failed mirror resync"
20841         $LFS mirror split --mirror-id 1 -d $dom ||
20842                 error "failed mirror split"
20843
20844         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20845                 error "MDT stripe was not removed"
20846
20847         cancel_lru_locks mdc
20848         local new_md5=$(md5sum $dom)
20849         [ "$old_md5" == "$new_md5" ] ||
20850                 error "$old_md5 != $new_md5"
20851
20852         # Skip free space checks with ZFS
20853         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20854                 local mdtfree2=$(do_facet $facet \
20855                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20856                 [ $mdtfree2 -gt $mdtfree1 ] ||
20857                         error "MDS space is not freed after DOM mirror deletion"
20858         fi
20859         return 0
20860 }
20861 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20862
20863 test_272e() {
20864         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20865                 skip "Need MDS version at least 2.12.55"
20866
20867         local dom=$DIR/$tdir/$tfile
20868         mkdir -p $DIR/$tdir
20869         $LFS setstripe -c 2 $dom
20870
20871         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20872                 error "failed to write data into $dom"
20873         local old_md5=$(md5sum $dom)
20874         cancel_lru_locks mdc
20875
20876         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20877                 error "failed mirroring to the DOM layout"
20878         $LFS mirror resync $dom ||
20879                 error "failed mirror resync"
20880         $LFS mirror split --mirror-id 1 -d $dom ||
20881                 error "failed mirror split"
20882
20883         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20884                 error "MDT stripe was not removed"
20885
20886         cancel_lru_locks mdc
20887         local new_md5=$(md5sum $dom)
20888         [ "$old_md5" == "$new_md5" ] ||
20889                 error "$old_md5 != $new_md5"
20890
20891         return 0
20892 }
20893 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20894
20895 test_272f() {
20896         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20897                 skip "Need MDS version at least 2.12.55"
20898
20899         local dom=$DIR/$tdir/$tfile
20900         mkdir -p $DIR/$tdir
20901         $LFS setstripe -c 2 $dom
20902
20903         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20904                 error "failed to write data into $dom"
20905         local old_md5=$(md5sum $dom)
20906         cancel_lru_locks mdc
20907
20908         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20909                 error "failed migrating to the DOM file"
20910
20911         cancel_lru_locks mdc
20912         local new_md5=$(md5sum $dom)
20913         [ "$old_md5" != "$new_md5" ] &&
20914                 error "$old_md5 != $new_md5"
20915
20916         return 0
20917 }
20918 run_test 272f "DoM migration: OST-striped file to DOM file"
20919
20920 test_273a() {
20921         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20922                 skip "Need MDS version at least 2.11.50"
20923
20924         # Layout swap cannot be done if either file has DOM component,
20925         # this will never be supported, migration should be used instead
20926
20927         local dom=$DIR/$tdir/$tfile
20928         mkdir -p $DIR/$tdir
20929
20930         $LFS setstripe -c2 ${dom}_plain
20931         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20932         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20933                 error "can swap layout with DoM component"
20934         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20935                 error "can swap layout with DoM component"
20936
20937         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20938         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20939                 error "can swap layout with DoM component"
20940         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20941                 error "can swap layout with DoM component"
20942         return 0
20943 }
20944 run_test 273a "DoM: layout swapping should fail with DOM"
20945
20946 test_275() {
20947         remote_ost_nodsh && skip "remote OST with nodsh"
20948         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20949                 skip "Need OST version >= 2.10.57"
20950
20951         local file=$DIR/$tfile
20952         local oss
20953
20954         oss=$(comma_list $(osts_nodes))
20955
20956         dd if=/dev/urandom of=$file bs=1M count=2 ||
20957                 error "failed to create a file"
20958         cancel_lru_locks osc
20959
20960         #lock 1
20961         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20962                 error "failed to read a file"
20963
20964 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20965         $LCTL set_param fail_loc=0x8000031f
20966
20967         cancel_lru_locks osc &
20968         sleep 1
20969
20970 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20971         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20972         #IO takes another lock, but matches the PENDING one
20973         #and places it to the IO RPC
20974         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20975                 error "failed to read a file with PENDING lock"
20976 }
20977 run_test 275 "Read on a canceled duplicate lock"
20978
20979 test_276() {
20980         remote_ost_nodsh && skip "remote OST with nodsh"
20981         local pid
20982
20983         do_facet ost1 "(while true; do \
20984                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20985                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20986         pid=$!
20987
20988         for LOOP in $(seq 20); do
20989                 stop ost1
20990                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20991         done
20992         kill -9 $pid
20993         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20994                 rm $TMP/sanity_276_pid"
20995 }
20996 run_test 276 "Race between mount and obd_statfs"
20997
20998 test_277() {
20999         $LCTL set_param ldlm.namespaces.*.lru_size=0
21000         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21001         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21002                         grep ^used_mb | awk '{print $2}')
21003         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21004         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21005                 oflag=direct conv=notrunc
21006         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21007                         grep ^used_mb | awk '{print $2}')
21008         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21009 }
21010 run_test 277 "Direct IO shall drop page cache"
21011
21012 test_278() {
21013         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21014         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21015         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21016                 skip "needs the same host for mdt1 mdt2" && return
21017
21018         local pid1
21019         local pid2
21020
21021 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21022         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21023         stop mds2 &
21024         pid2=$!
21025
21026         stop mds1
21027
21028         echo "Starting MDTs"
21029         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21030         wait $pid2
21031 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21032 #will return NULL
21033         do_facet mds2 $LCTL set_param fail_loc=0
21034
21035         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21036         wait_recovery_complete mds2
21037 }
21038 run_test 278 "Race starting MDS between MDTs stop/start"
21039
21040 test_280() {
21041         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21042                 skip "Need MGS version at least 2.13.52"
21043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21044         combined_mgs_mds || skip "needs combined MGS/MDT"
21045
21046         umount_client $MOUNT
21047 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21048         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21049
21050         mount_client $MOUNT &
21051         sleep 1
21052         stop mgs || error "stop mgs failed"
21053         #for a race mgs would crash
21054         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21055         mount_client $MOUNT || error "mount client failed"
21056 }
21057 run_test 280 "Race between MGS umount and client llog processing"
21058
21059 cleanup_test_300() {
21060         trap 0
21061         umask $SAVE_UMASK
21062 }
21063 test_striped_dir() {
21064         local mdt_index=$1
21065         local stripe_count
21066         local stripe_index
21067
21068         mkdir -p $DIR/$tdir
21069
21070         SAVE_UMASK=$(umask)
21071         trap cleanup_test_300 RETURN EXIT
21072
21073         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21074                                                 $DIR/$tdir/striped_dir ||
21075                 error "set striped dir error"
21076
21077         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21078         [ "$mode" = "755" ] || error "expect 755 got $mode"
21079
21080         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21081                 error "getdirstripe failed"
21082         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21083         if [ "$stripe_count" != "2" ]; then
21084                 error "1:stripe_count is $stripe_count, expect 2"
21085         fi
21086         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21087         if [ "$stripe_count" != "2" ]; then
21088                 error "2:stripe_count is $stripe_count, expect 2"
21089         fi
21090
21091         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21092         if [ "$stripe_index" != "$mdt_index" ]; then
21093                 error "stripe_index is $stripe_index, expect $mdt_index"
21094         fi
21095
21096         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21097                 error "nlink error after create striped dir"
21098
21099         mkdir $DIR/$tdir/striped_dir/a
21100         mkdir $DIR/$tdir/striped_dir/b
21101
21102         stat $DIR/$tdir/striped_dir/a ||
21103                 error "create dir under striped dir failed"
21104         stat $DIR/$tdir/striped_dir/b ||
21105                 error "create dir under striped dir failed"
21106
21107         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21108                 error "nlink error after mkdir"
21109
21110         rmdir $DIR/$tdir/striped_dir/a
21111         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21112                 error "nlink error after rmdir"
21113
21114         rmdir $DIR/$tdir/striped_dir/b
21115         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21116                 error "nlink error after rmdir"
21117
21118         chattr +i $DIR/$tdir/striped_dir
21119         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21120                 error "immutable flags not working under striped dir!"
21121         chattr -i $DIR/$tdir/striped_dir
21122
21123         rmdir $DIR/$tdir/striped_dir ||
21124                 error "rmdir striped dir error"
21125
21126         cleanup_test_300
21127
21128         true
21129 }
21130
21131 test_300a() {
21132         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21133                 skip "skipped for lustre < 2.7.0"
21134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21136
21137         test_striped_dir 0 || error "failed on striped dir on MDT0"
21138         test_striped_dir 1 || error "failed on striped dir on MDT0"
21139 }
21140 run_test 300a "basic striped dir sanity test"
21141
21142 test_300b() {
21143         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21144                 skip "skipped for lustre < 2.7.0"
21145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21147
21148         local i
21149         local mtime1
21150         local mtime2
21151         local mtime3
21152
21153         test_mkdir $DIR/$tdir || error "mkdir fail"
21154         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21155                 error "set striped dir error"
21156         for i in {0..9}; do
21157                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21158                 sleep 1
21159                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21160                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21161                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21162                 sleep 1
21163                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21164                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21165                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21166         done
21167         true
21168 }
21169 run_test 300b "check ctime/mtime for striped dir"
21170
21171 test_300c() {
21172         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21173                 skip "skipped for lustre < 2.7.0"
21174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21176
21177         local file_count
21178
21179         mkdir -p $DIR/$tdir
21180         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21181                 error "set striped dir error"
21182
21183         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21184                 error "chown striped dir failed"
21185
21186         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21187                 error "create 5k files failed"
21188
21189         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21190
21191         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21192
21193         rm -rf $DIR/$tdir
21194 }
21195 run_test 300c "chown && check ls under striped directory"
21196
21197 test_300d() {
21198         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21199                 skip "skipped for lustre < 2.7.0"
21200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21201         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21202
21203         local stripe_count
21204         local file
21205
21206         mkdir -p $DIR/$tdir
21207         $LFS setstripe -c 2 $DIR/$tdir
21208
21209         #local striped directory
21210         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21211                 error "set striped dir error"
21212         #look at the directories for debug purposes
21213         ls -l $DIR/$tdir
21214         $LFS getdirstripe $DIR/$tdir
21215         ls -l $DIR/$tdir/striped_dir
21216         $LFS getdirstripe $DIR/$tdir/striped_dir
21217         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21218                 error "create 10 files failed"
21219
21220         #remote striped directory
21221         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21222                 error "set striped dir error"
21223         #look at the directories for debug purposes
21224         ls -l $DIR/$tdir
21225         $LFS getdirstripe $DIR/$tdir
21226         ls -l $DIR/$tdir/remote_striped_dir
21227         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21228         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21229                 error "create 10 files failed"
21230
21231         for file in $(find $DIR/$tdir); do
21232                 stripe_count=$($LFS getstripe -c $file)
21233                 [ $stripe_count -eq 2 ] ||
21234                         error "wrong stripe $stripe_count for $file"
21235         done
21236
21237         rm -rf $DIR/$tdir
21238 }
21239 run_test 300d "check default stripe under striped directory"
21240
21241 test_300e() {
21242         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21243                 skip "Need MDS version at least 2.7.55"
21244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21245         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21246
21247         local stripe_count
21248         local file
21249
21250         mkdir -p $DIR/$tdir
21251
21252         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21253                 error "set striped dir error"
21254
21255         touch $DIR/$tdir/striped_dir/a
21256         touch $DIR/$tdir/striped_dir/b
21257         touch $DIR/$tdir/striped_dir/c
21258
21259         mkdir $DIR/$tdir/striped_dir/dir_a
21260         mkdir $DIR/$tdir/striped_dir/dir_b
21261         mkdir $DIR/$tdir/striped_dir/dir_c
21262
21263         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21264                 error "set striped adir under striped dir error"
21265
21266         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21267                 error "set striped bdir under striped dir error"
21268
21269         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21270                 error "set striped cdir under striped dir error"
21271
21272         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21273                 error "rename dir under striped dir fails"
21274
21275         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21276                 error "rename dir under different stripes fails"
21277
21278         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21279                 error "rename file under striped dir should succeed"
21280
21281         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21282                 error "rename dir under striped dir should succeed"
21283
21284         rm -rf $DIR/$tdir
21285 }
21286 run_test 300e "check rename under striped directory"
21287
21288 test_300f() {
21289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21291         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21292                 skip "Need MDS version at least 2.7.55"
21293
21294         local stripe_count
21295         local file
21296
21297         rm -rf $DIR/$tdir
21298         mkdir -p $DIR/$tdir
21299
21300         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21301                 error "set striped dir error"
21302
21303         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21304                 error "set striped dir error"
21305
21306         touch $DIR/$tdir/striped_dir/a
21307         mkdir $DIR/$tdir/striped_dir/dir_a
21308         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21309                 error "create striped dir under striped dir fails"
21310
21311         touch $DIR/$tdir/striped_dir1/b
21312         mkdir $DIR/$tdir/striped_dir1/dir_b
21313         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21314                 error "create striped dir under striped dir fails"
21315
21316         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21317                 error "rename dir under different striped dir should fail"
21318
21319         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21320                 error "rename striped dir under diff striped dir should fail"
21321
21322         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21323                 error "rename file under diff striped dirs fails"
21324
21325         rm -rf $DIR/$tdir
21326 }
21327 run_test 300f "check rename cross striped directory"
21328
21329 test_300_check_default_striped_dir()
21330 {
21331         local dirname=$1
21332         local default_count=$2
21333         local default_index=$3
21334         local stripe_count
21335         local stripe_index
21336         local dir_stripe_index
21337         local dir
21338
21339         echo "checking $dirname $default_count $default_index"
21340         $LFS setdirstripe -D -c $default_count -i $default_index \
21341                                 -t all_char $DIR/$tdir/$dirname ||
21342                 error "set default stripe on striped dir error"
21343         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21344         [ $stripe_count -eq $default_count ] ||
21345                 error "expect $default_count get $stripe_count for $dirname"
21346
21347         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21348         [ $stripe_index -eq $default_index ] ||
21349                 error "expect $default_index get $stripe_index for $dirname"
21350
21351         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21352                                                 error "create dirs failed"
21353
21354         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21355         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21356         for dir in $(find $DIR/$tdir/$dirname/*); do
21357                 stripe_count=$($LFS getdirstripe -c $dir)
21358                 [ $stripe_count -eq $default_count ] ||
21359                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21360                 error "stripe count $default_count != $stripe_count for $dir"
21361
21362                 stripe_index=$($LFS getdirstripe -i $dir)
21363                 [ $default_index -eq -1 ] ||
21364                         [ $stripe_index -eq $default_index ] ||
21365                         error "$stripe_index != $default_index for $dir"
21366
21367                 #check default stripe
21368                 stripe_count=$($LFS getdirstripe -D -c $dir)
21369                 [ $stripe_count -eq $default_count ] ||
21370                 error "default count $default_count != $stripe_count for $dir"
21371
21372                 stripe_index=$($LFS getdirstripe -D -i $dir)
21373                 [ $stripe_index -eq $default_index ] ||
21374                 error "default index $default_index != $stripe_index for $dir"
21375         done
21376         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21377 }
21378
21379 test_300g() {
21380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21381         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21382                 skip "Need MDS version at least 2.7.55"
21383
21384         local dir
21385         local stripe_count
21386         local stripe_index
21387
21388         mkdir $DIR/$tdir
21389         mkdir $DIR/$tdir/normal_dir
21390
21391         #Checking when client cache stripe index
21392         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21393         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21394                 error "create striped_dir failed"
21395
21396         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21397                 error "create dir0 fails"
21398         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21399         [ $stripe_index -eq 0 ] ||
21400                 error "dir0 expect index 0 got $stripe_index"
21401
21402         mkdir $DIR/$tdir/striped_dir/dir1 ||
21403                 error "create dir1 fails"
21404         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21405         [ $stripe_index -eq 1 ] ||
21406                 error "dir1 expect index 1 got $stripe_index"
21407
21408         #check default stripe count/stripe index
21409         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21410         test_300_check_default_striped_dir normal_dir 1 0
21411         test_300_check_default_striped_dir normal_dir 2 1
21412         test_300_check_default_striped_dir normal_dir 2 -1
21413
21414         #delete default stripe information
21415         echo "delete default stripeEA"
21416         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21417                 error "set default stripe on striped dir error"
21418
21419         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21420         for dir in $(find $DIR/$tdir/normal_dir/*); do
21421                 stripe_count=$($LFS getdirstripe -c $dir)
21422                 [ $stripe_count -eq 0 ] ||
21423                         error "expect 1 get $stripe_count for $dir"
21424                 stripe_index=$($LFS getdirstripe -i $dir)
21425                 [ $stripe_index -eq 0 ] ||
21426                         error "expect 0 get $stripe_index for $dir"
21427         done
21428 }
21429 run_test 300g "check default striped directory for normal directory"
21430
21431 test_300h() {
21432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21433         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21434                 skip "Need MDS version at least 2.7.55"
21435
21436         local dir
21437         local stripe_count
21438
21439         mkdir $DIR/$tdir
21440         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21441                 error "set striped dir error"
21442
21443         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21444         test_300_check_default_striped_dir striped_dir 1 0
21445         test_300_check_default_striped_dir striped_dir 2 1
21446         test_300_check_default_striped_dir striped_dir 2 -1
21447
21448         #delete default stripe information
21449         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21450                 error "set default stripe on striped dir error"
21451
21452         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21453         for dir in $(find $DIR/$tdir/striped_dir/*); do
21454                 stripe_count=$($LFS getdirstripe -c $dir)
21455                 [ $stripe_count -eq 0 ] ||
21456                         error "expect 1 get $stripe_count for $dir"
21457         done
21458 }
21459 run_test 300h "check default striped directory for striped directory"
21460
21461 test_300i() {
21462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21464         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21465                 skip "Need MDS version at least 2.7.55"
21466
21467         local stripe_count
21468         local file
21469
21470         mkdir $DIR/$tdir
21471
21472         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21473                 error "set striped dir error"
21474
21475         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21476                 error "create files under striped dir failed"
21477
21478         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21479                 error "set striped hashdir error"
21480
21481         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21482                 error "create dir0 under hash dir failed"
21483         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21484                 error "create dir1 under hash dir failed"
21485
21486         # unfortunately, we need to umount to clear dir layout cache for now
21487         # once we fully implement dir layout, we can drop this
21488         umount_client $MOUNT || error "umount failed"
21489         mount_client $MOUNT || error "mount failed"
21490
21491         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21492         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21493         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21494
21495         #set the stripe to be unknown hash type
21496         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21497         $LCTL set_param fail_loc=0x1901
21498         for ((i = 0; i < 10; i++)); do
21499                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21500                         error "stat f-$i failed"
21501                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21502         done
21503
21504         touch $DIR/$tdir/striped_dir/f0 &&
21505                 error "create under striped dir with unknown hash should fail"
21506
21507         $LCTL set_param fail_loc=0
21508
21509         umount_client $MOUNT || error "umount failed"
21510         mount_client $MOUNT || error "mount failed"
21511
21512         return 0
21513 }
21514 run_test 300i "client handle unknown hash type striped directory"
21515
21516 test_300j() {
21517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21519         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21520                 skip "Need MDS version at least 2.7.55"
21521
21522         local stripe_count
21523         local file
21524
21525         mkdir $DIR/$tdir
21526
21527         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21528         $LCTL set_param fail_loc=0x1702
21529         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21530                 error "set striped dir error"
21531
21532         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21533                 error "create files under striped dir failed"
21534
21535         $LCTL set_param fail_loc=0
21536
21537         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21538
21539         return 0
21540 }
21541 run_test 300j "test large update record"
21542
21543 test_300k() {
21544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21545         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21546         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21547                 skip "Need MDS version at least 2.7.55"
21548
21549         # this test needs a huge transaction
21550         local kb
21551         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21552              osd*.$FSNAME-MDT0000.kbytestotal")
21553         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21554
21555         local stripe_count
21556         local file
21557
21558         mkdir $DIR/$tdir
21559
21560         #define OBD_FAIL_LARGE_STRIPE   0x1703
21561         $LCTL set_param fail_loc=0x1703
21562         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21563                 error "set striped dir error"
21564         $LCTL set_param fail_loc=0
21565
21566         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21567                 error "getstripeddir fails"
21568         rm -rf $DIR/$tdir/striped_dir ||
21569                 error "unlink striped dir fails"
21570
21571         return 0
21572 }
21573 run_test 300k "test large striped directory"
21574
21575 test_300l() {
21576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21578         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21579                 skip "Need MDS version at least 2.7.55"
21580
21581         local stripe_index
21582
21583         test_mkdir -p $DIR/$tdir/striped_dir
21584         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21585                         error "chown $RUNAS_ID failed"
21586         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21587                 error "set default striped dir failed"
21588
21589         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21590         $LCTL set_param fail_loc=0x80000158
21591         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21592
21593         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21594         [ $stripe_index -eq 1 ] ||
21595                 error "expect 1 get $stripe_index for $dir"
21596 }
21597 run_test 300l "non-root user to create dir under striped dir with stale layout"
21598
21599 test_300m() {
21600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21601         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21602         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21603                 skip "Need MDS version at least 2.7.55"
21604
21605         mkdir -p $DIR/$tdir/striped_dir
21606         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21607                 error "set default stripes dir error"
21608
21609         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21610
21611         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21612         [ $stripe_count -eq 0 ] ||
21613                         error "expect 0 get $stripe_count for a"
21614
21615         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21616                 error "set default stripes dir error"
21617
21618         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21619
21620         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21621         [ $stripe_count -eq 0 ] ||
21622                         error "expect 0 get $stripe_count for b"
21623
21624         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21625                 error "set default stripes dir error"
21626
21627         mkdir $DIR/$tdir/striped_dir/c &&
21628                 error "default stripe_index is invalid, mkdir c should fails"
21629
21630         rm -rf $DIR/$tdir || error "rmdir fails"
21631 }
21632 run_test 300m "setstriped directory on single MDT FS"
21633
21634 cleanup_300n() {
21635         local list=$(comma_list $(mdts_nodes))
21636
21637         trap 0
21638         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21639 }
21640
21641 test_300n() {
21642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21643         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21644         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21645                 skip "Need MDS version at least 2.7.55"
21646         remote_mds_nodsh && skip "remote MDS with nodsh"
21647
21648         local stripe_index
21649         local list=$(comma_list $(mdts_nodes))
21650
21651         trap cleanup_300n RETURN EXIT
21652         mkdir -p $DIR/$tdir
21653         chmod 777 $DIR/$tdir
21654         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21655                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21656                 error "create striped dir succeeds with gid=0"
21657
21658         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21659         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21660                 error "create striped dir fails with gid=-1"
21661
21662         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21663         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21664                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21665                 error "set default striped dir succeeds with gid=0"
21666
21667
21668         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21669         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21670                 error "set default striped dir fails with gid=-1"
21671
21672
21673         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21674         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21675                                         error "create test_dir fails"
21676         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21677                                         error "create test_dir1 fails"
21678         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21679                                         error "create test_dir2 fails"
21680         cleanup_300n
21681 }
21682 run_test 300n "non-root user to create dir under striped dir with default EA"
21683
21684 test_300o() {
21685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21686         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21687         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21688                 skip "Need MDS version at least 2.7.55"
21689
21690         local numfree1
21691         local numfree2
21692
21693         mkdir -p $DIR/$tdir
21694
21695         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21696         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21697         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21698                 skip "not enough free inodes $numfree1 $numfree2"
21699         fi
21700
21701         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21702         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21703         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21704                 skip "not enough free space $numfree1 $numfree2"
21705         fi
21706
21707         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21708                 error "setdirstripe fails"
21709
21710         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21711                 error "create dirs fails"
21712
21713         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21714         ls $DIR/$tdir/striped_dir > /dev/null ||
21715                 error "ls striped dir fails"
21716         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21717                 error "unlink big striped dir fails"
21718 }
21719 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21720
21721 test_300p() {
21722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21724         remote_mds_nodsh && skip "remote MDS with nodsh"
21725
21726         mkdir -p $DIR/$tdir
21727
21728         #define OBD_FAIL_OUT_ENOSPC     0x1704
21729         do_facet mds2 lctl set_param fail_loc=0x80001704
21730         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21731                  && error "create striped directory should fail"
21732
21733         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21734
21735         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21736         true
21737 }
21738 run_test 300p "create striped directory without space"
21739
21740 test_300q() {
21741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21742         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21743
21744         local fd=$(free_fd)
21745         local cmd="exec $fd<$tdir"
21746         cd $DIR
21747         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21748         eval $cmd
21749         cmd="exec $fd<&-"
21750         trap "eval $cmd" EXIT
21751         cd $tdir || error "cd $tdir fails"
21752         rmdir  ../$tdir || error "rmdir $tdir fails"
21753         mkdir local_dir && error "create dir succeeds"
21754         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21755         eval $cmd
21756         return 0
21757 }
21758 run_test 300q "create remote directory under orphan directory"
21759
21760 test_300r() {
21761         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21762                 skip "Need MDS version at least 2.7.55" && return
21763         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21764
21765         mkdir $DIR/$tdir
21766
21767         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21768                 error "set striped dir error"
21769
21770         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21771                 error "getstripeddir fails"
21772
21773         local stripe_count
21774         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21775                       awk '/lmv_stripe_count:/ { print $2 }')
21776
21777         [ $MDSCOUNT -ne $stripe_count ] &&
21778                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21779
21780         rm -rf $DIR/$tdir/striped_dir ||
21781                 error "unlink striped dir fails"
21782 }
21783 run_test 300r "test -1 striped directory"
21784
21785 test_300s_helper() {
21786         local count=$1
21787
21788         local stripe_dir=$DIR/$tdir/striped_dir.$count
21789
21790         $LFS mkdir -c $count $stripe_dir ||
21791                 error "lfs mkdir -c error"
21792
21793         $LFS getdirstripe $stripe_dir ||
21794                 error "lfs getdirstripe fails"
21795
21796         local stripe_count
21797         stripe_count=$($LFS getdirstripe $stripe_dir |
21798                       awk '/lmv_stripe_count:/ { print $2 }')
21799
21800         [ $count -ne $stripe_count ] &&
21801                 error_noexit "bad stripe count $stripe_count expected $count"
21802
21803         local dupe_stripes
21804         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21805                 awk '/0x/ {count[$1] += 1}; END {
21806                         for (idx in count) {
21807                                 if (count[idx]>1) {
21808                                         print "index " idx " count " count[idx]
21809                                 }
21810                         }
21811                 }')
21812
21813         if [[ -n "$dupe_stripes" ]] ; then
21814                 lfs getdirstripe $stripe_dir
21815                 error_noexit "Dupe MDT above: $dupe_stripes "
21816         fi
21817
21818         rm -rf $stripe_dir ||
21819                 error_noexit "unlink $stripe_dir fails"
21820 }
21821
21822 test_300s() {
21823         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21824                 skip "Need MDS version at least 2.7.55" && return
21825         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21826
21827         mkdir $DIR/$tdir
21828         for count in $(seq 2 $MDSCOUNT); do
21829                 test_300s_helper $count
21830         done
21831 }
21832 run_test 300s "test lfs mkdir -c without -i"
21833
21834
21835 prepare_remote_file() {
21836         mkdir $DIR/$tdir/src_dir ||
21837                 error "create remote source failed"
21838
21839         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21840                  error "cp to remote source failed"
21841         touch $DIR/$tdir/src_dir/a
21842
21843         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21844                 error "create remote target dir failed"
21845
21846         touch $DIR/$tdir/tgt_dir/b
21847
21848         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21849                 error "rename dir cross MDT failed!"
21850
21851         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21852                 error "src_child still exists after rename"
21853
21854         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21855                 error "missing file(a) after rename"
21856
21857         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21858                 error "diff after rename"
21859 }
21860
21861 test_310a() {
21862         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21864
21865         local remote_file=$DIR/$tdir/tgt_dir/b
21866
21867         mkdir -p $DIR/$tdir
21868
21869         prepare_remote_file || error "prepare remote file failed"
21870
21871         #open-unlink file
21872         $OPENUNLINK $remote_file $remote_file ||
21873                 error "openunlink $remote_file failed"
21874         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21875 }
21876 run_test 310a "open unlink remote file"
21877
21878 test_310b() {
21879         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21881
21882         local remote_file=$DIR/$tdir/tgt_dir/b
21883
21884         mkdir -p $DIR/$tdir
21885
21886         prepare_remote_file || error "prepare remote file failed"
21887
21888         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21889         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21890         $CHECKSTAT -t file $remote_file || error "check file failed"
21891 }
21892 run_test 310b "unlink remote file with multiple links while open"
21893
21894 test_310c() {
21895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21896         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21897
21898         local remote_file=$DIR/$tdir/tgt_dir/b
21899
21900         mkdir -p $DIR/$tdir
21901
21902         prepare_remote_file || error "prepare remote file failed"
21903
21904         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21905         multiop_bg_pause $remote_file O_uc ||
21906                         error "mulitop failed for remote file"
21907         MULTIPID=$!
21908         $MULTIOP $DIR/$tfile Ouc
21909         kill -USR1 $MULTIPID
21910         wait $MULTIPID
21911 }
21912 run_test 310c "open-unlink remote file with multiple links"
21913
21914 #LU-4825
21915 test_311() {
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21918         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21919                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21920         remote_mds_nodsh && skip "remote MDS with nodsh"
21921
21922         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21923         local mdts=$(comma_list $(mdts_nodes))
21924
21925         mkdir -p $DIR/$tdir
21926         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21927         createmany -o $DIR/$tdir/$tfile. 1000
21928
21929         # statfs data is not real time, let's just calculate it
21930         old_iused=$((old_iused + 1000))
21931
21932         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21933                         osp.*OST0000*MDT0000.create_count")
21934         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21935                                 osp.*OST0000*MDT0000.max_create_count")
21936         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21937
21938         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21939         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21940         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21941
21942         unlinkmany $DIR/$tdir/$tfile. 1000
21943
21944         do_nodes $mdts "$LCTL set_param -n \
21945                         osp.*OST0000*.max_create_count=$max_count"
21946         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21947                 do_nodes $mdts "$LCTL set_param -n \
21948                                 osp.*OST0000*.create_count=$count"
21949         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21950                         grep "=0" && error "create_count is zero"
21951
21952         local new_iused
21953         for i in $(seq 120); do
21954                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21955                 # system may be too busy to destroy all objs in time, use
21956                 # a somewhat small value to not fail autotest
21957                 [ $((old_iused - new_iused)) -gt 400 ] && break
21958                 sleep 1
21959         done
21960
21961         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21962         [ $((old_iused - new_iused)) -gt 400 ] ||
21963                 error "objs not destroyed after unlink"
21964 }
21965 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21966
21967 zfs_oid_to_objid()
21968 {
21969         local ost=$1
21970         local objid=$2
21971
21972         local vdevdir=$(dirname $(facet_vdevice $ost))
21973         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21974         local zfs_zapid=$(do_facet $ost $cmd |
21975                           grep -w "/O/0/d$((objid%32))" -C 5 |
21976                           awk '/Object/{getline; print $1}')
21977         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21978                           awk "/$objid = /"'{printf $3}')
21979
21980         echo $zfs_objid
21981 }
21982
21983 zfs_object_blksz() {
21984         local ost=$1
21985         local objid=$2
21986
21987         local vdevdir=$(dirname $(facet_vdevice $ost))
21988         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21989         local blksz=$(do_facet $ost $cmd $objid |
21990                       awk '/dblk/{getline; printf $4}')
21991
21992         case "${blksz: -1}" in
21993                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21994                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21995                 *) ;;
21996         esac
21997
21998         echo $blksz
21999 }
22000
22001 test_312() { # LU-4856
22002         remote_ost_nodsh && skip "remote OST with nodsh"
22003         [ "$ost1_FSTYPE" = "zfs" ] ||
22004                 skip_env "the test only applies to zfs"
22005
22006         local max_blksz=$(do_facet ost1 \
22007                           $ZFS get -p recordsize $(facet_device ost1) |
22008                           awk '!/VALUE/{print $3}')
22009
22010         # to make life a little bit easier
22011         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22012         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22013
22014         local tf=$DIR/$tdir/$tfile
22015         touch $tf
22016         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22017
22018         # Get ZFS object id
22019         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22020         # block size change by sequential overwrite
22021         local bs
22022
22023         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22024                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22025
22026                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22027                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22028         done
22029         rm -f $tf
22030
22031         # block size change by sequential append write
22032         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22033         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22034         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22035         local count
22036
22037         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22038                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22039                         oflag=sync conv=notrunc
22040
22041                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22042                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22043                         error "blksz error, actual $blksz, " \
22044                                 "expected: 2 * $count * $PAGE_SIZE"
22045         done
22046         rm -f $tf
22047
22048         # random write
22049         touch $tf
22050         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22051         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22052
22053         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22054         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22055         [ $blksz -eq $PAGE_SIZE ] ||
22056                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22057
22058         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22059         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22060         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22061
22062         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22063         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22064         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22065 }
22066 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22067
22068 test_313() {
22069         remote_ost_nodsh && skip "remote OST with nodsh"
22070
22071         local file=$DIR/$tfile
22072
22073         rm -f $file
22074         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22075
22076         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22077         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22078         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22079                 error "write should failed"
22080         do_facet ost1 "$LCTL set_param fail_loc=0"
22081         rm -f $file
22082 }
22083 run_test 313 "io should fail after last_rcvd update fail"
22084
22085 test_314() {
22086         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22087
22088         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22089         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22090         rm -f $DIR/$tfile
22091         wait_delete_completed
22092         do_facet ost1 "$LCTL set_param fail_loc=0"
22093 }
22094 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22095
22096 test_315() { # LU-618
22097         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22098
22099         local file=$DIR/$tfile
22100         rm -f $file
22101
22102         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22103                 error "multiop file write failed"
22104         $MULTIOP $file oO_RDONLY:r4063232_c &
22105         PID=$!
22106
22107         sleep 2
22108
22109         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22110         kill -USR1 $PID
22111
22112         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22113         rm -f $file
22114 }
22115 run_test 315 "read should be accounted"
22116
22117 test_316() {
22118         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22119         large_xattr_enabled || skip_env "ea_inode feature disabled"
22120
22121         rm -rf $DIR/$tdir/d
22122         mkdir -p $DIR/$tdir/d
22123         chown nobody $DIR/$tdir/d
22124         touch $DIR/$tdir/d/file
22125
22126         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22127 }
22128 run_test 316 "lfs mv"
22129
22130 test_317() {
22131         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22132                 skip "Need MDS version at least 2.11.53"
22133         if [ "$ost1_FSTYPE" == "zfs" ]; then
22134                 skip "LU-10370: no implementation for ZFS"
22135         fi
22136
22137         local trunc_sz
22138         local grant_blk_size
22139
22140         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22141                         awk '/grant_block_size:/ { print $2; exit; }')
22142         #
22143         # Create File of size 5M. Truncate it to below size's and verify
22144         # blocks count.
22145         #
22146         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22147                 error "Create file $DIR/$tfile failed"
22148         stack_trap "rm -f $DIR/$tfile" EXIT
22149
22150         for trunc_sz in 2097152 4097 4000 509 0; do
22151                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22152                         error "truncate $tfile to $trunc_sz failed"
22153                 local sz=$(stat --format=%s $DIR/$tfile)
22154                 local blk=$(stat --format=%b $DIR/$tfile)
22155                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22156                                      grant_blk_size) * 8))
22157
22158                 if [[ $blk -ne $trunc_blk ]]; then
22159                         $(which stat) $DIR/$tfile
22160                         error "Expected Block $trunc_blk got $blk for $tfile"
22161                 fi
22162
22163                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22164                         error "Expected Size $trunc_sz got $sz for $tfile"
22165         done
22166
22167         #
22168         # sparse file test
22169         # Create file with a hole and write actual two blocks. Block count
22170         # must be 16.
22171         #
22172         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22173                 conv=fsync || error "Create file : $DIR/$tfile"
22174
22175         # Calculate the final truncate size.
22176         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22177
22178         #
22179         # truncate to size $trunc_sz bytes. Strip the last block
22180         # The block count must drop to 8
22181         #
22182         $TRUNCATE $DIR/$tfile $trunc_sz ||
22183                 error "truncate $tfile to $trunc_sz failed"
22184
22185         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22186         sz=$(stat --format=%s $DIR/$tfile)
22187         blk=$(stat --format=%b $DIR/$tfile)
22188
22189         if [[ $blk -ne $trunc_bsz ]]; then
22190                 $(which stat) $DIR/$tfile
22191                 error "Expected Block $trunc_bsz got $blk for $tfile"
22192         fi
22193
22194         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22195                 error "Expected Size $trunc_sz got $sz for $tfile"
22196 }
22197 run_test 317 "Verify blocks get correctly update after truncate"
22198
22199 test_318() {
22200         local old_max_active=$($LCTL get_param -n \
22201                             llite.*.max_read_ahead_async_active 2>/dev/null)
22202
22203         $LCTL set_param llite.*.max_read_ahead_async_active=256
22204         local max_active=$($LCTL get_param -n \
22205                            llite.*.max_read_ahead_async_active 2>/dev/null)
22206         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22207
22208         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22209                 error "set max_read_ahead_async_active should succeed"
22210
22211         $LCTL set_param llite.*.max_read_ahead_async_active=512
22212         max_active=$($LCTL get_param -n \
22213                      llite.*.max_read_ahead_async_active 2>/dev/null)
22214         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22215
22216         # restore @max_active
22217         [ $old_max_active -ne 0 ] && $LCTL set_param \
22218                 llite.*.max_read_ahead_async_active=$old_max_active
22219
22220         local old_threshold=$($LCTL get_param -n \
22221                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22222         local max_per_file_mb=$($LCTL get_param -n \
22223                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22224
22225         local invalid=$(($max_per_file_mb + 1))
22226         $LCTL set_param \
22227                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22228                         && error "set $invalid should fail"
22229
22230         local valid=$(($invalid - 1))
22231         $LCTL set_param \
22232                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22233                         error "set $valid should succeed"
22234         local threshold=$($LCTL get_param -n \
22235                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22236         [ $threshold -eq $valid ] || error \
22237                 "expect threshold $valid got $threshold"
22238         $LCTL set_param \
22239                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22240 }
22241 run_test 318 "Verify async readahead tunables"
22242
22243 test_319() {
22244         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22245
22246         local before=$(date +%s)
22247         local evict
22248         local mdir=$DIR/$tdir
22249         local file=$mdir/xxx
22250
22251         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22252         touch $file
22253
22254 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22255         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22256         $LFS mv -m1 $file &
22257
22258         sleep 1
22259         dd if=$file of=/dev/null
22260         wait
22261         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22262           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22263
22264         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22265 }
22266 run_test 319 "lost lease lock on migrate error"
22267
22268 test_398a() { # LU-4198
22269         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22270         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22271
22272         # request a new lock on client
22273         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22274
22275         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22276         local lock_count=$($LCTL get_param -n \
22277                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22278         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22279
22280         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22281
22282         # no lock cached, should use lockless IO and not enqueue new lock
22283         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22284         lock_count=$($LCTL get_param -n \
22285                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22286         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22287 }
22288 run_test 398a "direct IO should cancel lock otherwise lockless"
22289
22290 test_398b() { # LU-4198
22291         which fio || skip_env "no fio installed"
22292         $LFS setstripe -c -1 $DIR/$tfile
22293
22294         local size=12
22295         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22296
22297         local njobs=4
22298         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22299         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22300                 --numjobs=$njobs --fallocate=none \
22301                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22302                 --filename=$DIR/$tfile &
22303         bg_pid=$!
22304
22305         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22306         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22307                 --numjobs=$njobs --fallocate=none \
22308                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22309                 --filename=$DIR/$tfile || true
22310         wait $bg_pid
22311
22312         rm -rf $DIR/$tfile
22313 }
22314 run_test 398b "DIO and buffer IO race"
22315
22316 test_398c() { # LU-4198
22317         which fio || skip_env "no fio installed"
22318
22319         saved_debug=$($LCTL get_param -n debug)
22320         $LCTL set_param debug=0
22321
22322         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22323         ((size /= 1024)) # by megabytes
22324         ((size /= 2)) # write half of the OST at most
22325         [ $size -gt 40 ] && size=40 #reduce test time anyway
22326
22327         $LFS setstripe -c 1 $DIR/$tfile
22328
22329         # it seems like ldiskfs reserves more space than necessary if the
22330         # writing blocks are not mapped, so it extends the file firstly
22331         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22332         cancel_lru_locks osc
22333
22334         # clear and verify rpc_stats later
22335         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22336
22337         local njobs=4
22338         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22339         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22340                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22341                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22342                 --filename=$DIR/$tfile
22343         [ $? -eq 0 ] || error "fio write error"
22344
22345         [ $($LCTL get_param -n \
22346          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22347                 error "Locks were requested while doing AIO"
22348
22349         # get the percentage of 1-page I/O
22350         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22351                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22352                 awk '{print $7}')
22353         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22354
22355         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22356         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22357                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22358                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22359                 --filename=$DIR/$tfile
22360         [ $? -eq 0 ] || error "fio mixed read write error"
22361
22362         echo "AIO with large block size ${size}M"
22363         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22364                 --numjobs=1 --fallocate=none --ioengine=libaio \
22365                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22366                 --filename=$DIR/$tfile
22367         [ $? -eq 0 ] || error "fio large block size failed"
22368
22369         rm -rf $DIR/$tfile
22370         $LCTL set_param debug="$saved_debug"
22371 }
22372 run_test 398c "run fio to test AIO"
22373
22374 test_398d() { #  LU-13846
22375         test -f aiocp || skip_env "no aiocp installed"
22376         local aio_file=$DIR/aio_file
22377
22378         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22379
22380         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22381         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22382
22383         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22384
22385         # make sure we don't crash and fail properly
22386         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22387                 error "aio not aligned with PAGE SIZE should fail"
22388
22389         rm -rf $DIR/$tfile $aio_file
22390 }
22391 run_test 398d "run aiocp to verify block size > stripe size"
22392
22393 test_398e() {
22394         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22395         touch $DIR/$tfile.new
22396         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22397 }
22398 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22399
22400 test_fake_rw() {
22401         local read_write=$1
22402         if [ "$read_write" = "write" ]; then
22403                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22404         elif [ "$read_write" = "read" ]; then
22405                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22406         else
22407                 error "argument error"
22408         fi
22409
22410         # turn off debug for performance testing
22411         local saved_debug=$($LCTL get_param -n debug)
22412         $LCTL set_param debug=0
22413
22414         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22415
22416         # get ost1 size - $FSNAME-OST0000
22417         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22418         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22419         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22420
22421         if [ "$read_write" = "read" ]; then
22422                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22423         fi
22424
22425         local start_time=$(date +%s.%N)
22426         $dd_cmd bs=1M count=$blocks oflag=sync ||
22427                 error "real dd $read_write error"
22428         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22429
22430         if [ "$read_write" = "write" ]; then
22431                 rm -f $DIR/$tfile
22432         fi
22433
22434         # define OBD_FAIL_OST_FAKE_RW           0x238
22435         do_facet ost1 $LCTL set_param fail_loc=0x238
22436
22437         local start_time=$(date +%s.%N)
22438         $dd_cmd bs=1M count=$blocks oflag=sync ||
22439                 error "fake dd $read_write error"
22440         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22441
22442         if [ "$read_write" = "write" ]; then
22443                 # verify file size
22444                 cancel_lru_locks osc
22445                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22446                         error "$tfile size not $blocks MB"
22447         fi
22448         do_facet ost1 $LCTL set_param fail_loc=0
22449
22450         echo "fake $read_write $duration_fake vs. normal $read_write" \
22451                 "$duration in seconds"
22452         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22453                 error_not_in_vm "fake write is slower"
22454
22455         $LCTL set_param -n debug="$saved_debug"
22456         rm -f $DIR/$tfile
22457 }
22458 test_399a() { # LU-7655 for OST fake write
22459         remote_ost_nodsh && skip "remote OST with nodsh"
22460
22461         test_fake_rw write
22462 }
22463 run_test 399a "fake write should not be slower than normal write"
22464
22465 test_399b() { # LU-8726 for OST fake read
22466         remote_ost_nodsh && skip "remote OST with nodsh"
22467         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22468                 skip_env "ldiskfs only test"
22469         fi
22470
22471         test_fake_rw read
22472 }
22473 run_test 399b "fake read should not be slower than normal read"
22474
22475 test_400a() { # LU-1606, was conf-sanity test_74
22476         if ! which $CC > /dev/null 2>&1; then
22477                 skip_env "$CC is not installed"
22478         fi
22479
22480         local extra_flags=''
22481         local out=$TMP/$tfile
22482         local prefix=/usr/include/lustre
22483         local prog
22484
22485         # Oleg removes c files in his test rig so test if any c files exist
22486         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22487                 skip_env "Needed c test files are missing"
22488
22489         if ! [[ -d $prefix ]]; then
22490                 # Assume we're running in tree and fixup the include path.
22491                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22492                 extra_flags+=" -L$LUSTRE/utils/.lib"
22493         fi
22494
22495         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22496                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22497                         error "client api broken"
22498         done
22499         rm -f $out
22500 }
22501 run_test 400a "Lustre client api program can compile and link"
22502
22503 test_400b() { # LU-1606, LU-5011
22504         local header
22505         local out=$TMP/$tfile
22506         local prefix=/usr/include/linux/lustre
22507
22508         # We use a hard coded prefix so that this test will not fail
22509         # when run in tree. There are headers in lustre/include/lustre/
22510         # that are not packaged (like lustre_idl.h) and have more
22511         # complicated include dependencies (like config.h and lnet/types.h).
22512         # Since this test about correct packaging we just skip them when
22513         # they don't exist (see below) rather than try to fixup cppflags.
22514
22515         if ! which $CC > /dev/null 2>&1; then
22516                 skip_env "$CC is not installed"
22517         fi
22518
22519         for header in $prefix/*.h; do
22520                 if ! [[ -f "$header" ]]; then
22521                         continue
22522                 fi
22523
22524                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22525                         continue # lustre_ioctl.h is internal header
22526                 fi
22527
22528                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22529                         error "cannot compile '$header'"
22530         done
22531         rm -f $out
22532 }
22533 run_test 400b "packaged headers can be compiled"
22534
22535 test_401a() { #LU-7437
22536         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22537         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22538
22539         #count the number of parameters by "list_param -R"
22540         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22541         #count the number of parameters by listing proc files
22542         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22543         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22544         echo "proc_dirs='$proc_dirs'"
22545         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22546         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22547                       sort -u | wc -l)
22548
22549         [ $params -eq $procs ] ||
22550                 error "found $params parameters vs. $procs proc files"
22551
22552         # test the list_param -D option only returns directories
22553         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22554         #count the number of parameters by listing proc directories
22555         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22556                 sort -u | wc -l)
22557
22558         [ $params -eq $procs ] ||
22559                 error "found $params parameters vs. $procs proc files"
22560 }
22561 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22562
22563 test_401b() {
22564         # jobid_var may not allow arbitrary values, so use jobid_name
22565         # if available
22566         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22567                 local testname=jobid_name tmp='testing%p'
22568         else
22569                 local testname=jobid_var tmp=testing
22570         fi
22571
22572         local save=$($LCTL get_param -n $testname)
22573
22574         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22575                 error "no error returned when setting bad parameters"
22576
22577         local jobid_new=$($LCTL get_param -n foe $testname baz)
22578         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22579
22580         $LCTL set_param -n fog=bam $testname=$save bat=fog
22581         local jobid_old=$($LCTL get_param -n foe $testname bag)
22582         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22583 }
22584 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22585
22586 test_401c() {
22587         # jobid_var may not allow arbitrary values, so use jobid_name
22588         # if available
22589         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22590                 local testname=jobid_name
22591         else
22592                 local testname=jobid_var
22593         fi
22594
22595         local jobid_var_old=$($LCTL get_param -n $testname)
22596         local jobid_var_new
22597
22598         $LCTL set_param $testname= &&
22599                 error "no error returned for 'set_param a='"
22600
22601         jobid_var_new=$($LCTL get_param -n $testname)
22602         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22603                 error "$testname was changed by setting without value"
22604
22605         $LCTL set_param $testname &&
22606                 error "no error returned for 'set_param a'"
22607
22608         jobid_var_new=$($LCTL get_param -n $testname)
22609         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22610                 error "$testname was changed by setting without value"
22611 }
22612 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22613
22614 test_401d() {
22615         # jobid_var may not allow arbitrary values, so use jobid_name
22616         # if available
22617         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22618                 local testname=jobid_name new_value='foo=bar%p'
22619         else
22620                 local testname=jobid_var new_valuie=foo=bar
22621         fi
22622
22623         local jobid_var_old=$($LCTL get_param -n $testname)
22624         local jobid_var_new
22625
22626         $LCTL set_param $testname=$new_value ||
22627                 error "'set_param a=b' did not accept a value containing '='"
22628
22629         jobid_var_new=$($LCTL get_param -n $testname)
22630         [[ "$jobid_var_new" == "$new_value" ]] ||
22631                 error "'set_param a=b' failed on a value containing '='"
22632
22633         # Reset the $testname to test the other format
22634         $LCTL set_param $testname=$jobid_var_old
22635         jobid_var_new=$($LCTL get_param -n $testname)
22636         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22637                 error "failed to reset $testname"
22638
22639         $LCTL set_param $testname $new_value ||
22640                 error "'set_param a b' did not accept a value containing '='"
22641
22642         jobid_var_new=$($LCTL get_param -n $testname)
22643         [[ "$jobid_var_new" == "$new_value" ]] ||
22644                 error "'set_param a b' failed on a value containing '='"
22645
22646         $LCTL set_param $testname $jobid_var_old
22647         jobid_var_new=$($LCTL get_param -n $testname)
22648         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22649                 error "failed to reset $testname"
22650 }
22651 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22652
22653 test_402() {
22654         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22655         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22656                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22657         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22658                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22659                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22660         remote_mds_nodsh && skip "remote MDS with nodsh"
22661
22662         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22663 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22664         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22665         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22666                 echo "Touch failed - OK"
22667 }
22668 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22669
22670 test_403() {
22671         local file1=$DIR/$tfile.1
22672         local file2=$DIR/$tfile.2
22673         local tfile=$TMP/$tfile
22674
22675         rm -f $file1 $file2 $tfile
22676
22677         touch $file1
22678         ln $file1 $file2
22679
22680         # 30 sec OBD_TIMEOUT in ll_getattr()
22681         # right before populating st_nlink
22682         $LCTL set_param fail_loc=0x80001409
22683         stat -c %h $file1 > $tfile &
22684
22685         # create an alias, drop all locks and reclaim the dentry
22686         < $file2
22687         cancel_lru_locks mdc
22688         cancel_lru_locks osc
22689         sysctl -w vm.drop_caches=2
22690
22691         wait
22692
22693         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22694
22695         rm -f $tfile $file1 $file2
22696 }
22697 run_test 403 "i_nlink should not drop to zero due to aliasing"
22698
22699 test_404() { # LU-6601
22700         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22701                 skip "Need server version newer than 2.8.52"
22702         remote_mds_nodsh && skip "remote MDS with nodsh"
22703
22704         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22705                 awk '/osp .*-osc-MDT/ { print $4}')
22706
22707         local osp
22708         for osp in $mosps; do
22709                 echo "Deactivate: " $osp
22710                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22711                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22712                         awk -vp=$osp '$4 == p { print $2 }')
22713                 [ $stat = IN ] || {
22714                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22715                         error "deactivate error"
22716                 }
22717                 echo "Activate: " $osp
22718                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22719                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22720                         awk -vp=$osp '$4 == p { print $2 }')
22721                 [ $stat = UP ] || {
22722                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22723                         error "activate error"
22724                 }
22725         done
22726 }
22727 run_test 404 "validate manual {de}activated works properly for OSPs"
22728
22729 test_405() {
22730         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22731         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22732                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22733                         skip "Layout swap lock is not supported"
22734
22735         check_swap_layouts_support
22736         check_swap_layout_no_dom $DIR
22737
22738         test_mkdir $DIR/$tdir
22739         swap_lock_test -d $DIR/$tdir ||
22740                 error "One layout swap locked test failed"
22741 }
22742 run_test 405 "Various layout swap lock tests"
22743
22744 test_406() {
22745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22746         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22747         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22749         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22750                 skip "Need MDS version at least 2.8.50"
22751
22752         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22753         local test_pool=$TESTNAME
22754
22755         pool_add $test_pool || error "pool_add failed"
22756         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22757                 error "pool_add_targets failed"
22758
22759         save_layout_restore_at_exit $MOUNT
22760
22761         # parent set default stripe count only, child will stripe from both
22762         # parent and fs default
22763         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22764                 error "setstripe $MOUNT failed"
22765         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22766         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22767         for i in $(seq 10); do
22768                 local f=$DIR/$tdir/$tfile.$i
22769                 touch $f || error "touch failed"
22770                 local count=$($LFS getstripe -c $f)
22771                 [ $count -eq $OSTCOUNT ] ||
22772                         error "$f stripe count $count != $OSTCOUNT"
22773                 local offset=$($LFS getstripe -i $f)
22774                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22775                 local size=$($LFS getstripe -S $f)
22776                 [ $size -eq $((def_stripe_size * 2)) ] ||
22777                         error "$f stripe size $size != $((def_stripe_size * 2))"
22778                 local pool=$($LFS getstripe -p $f)
22779                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22780         done
22781
22782         # change fs default striping, delete parent default striping, now child
22783         # will stripe from new fs default striping only
22784         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22785                 error "change $MOUNT default stripe failed"
22786         $LFS setstripe -c 0 $DIR/$tdir ||
22787                 error "delete $tdir default stripe failed"
22788         for i in $(seq 11 20); do
22789                 local f=$DIR/$tdir/$tfile.$i
22790                 touch $f || error "touch $f failed"
22791                 local count=$($LFS getstripe -c $f)
22792                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22793                 local offset=$($LFS getstripe -i $f)
22794                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22795                 local size=$($LFS getstripe -S $f)
22796                 [ $size -eq $def_stripe_size ] ||
22797                         error "$f stripe size $size != $def_stripe_size"
22798                 local pool=$($LFS getstripe -p $f)
22799                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22800         done
22801
22802         unlinkmany $DIR/$tdir/$tfile. 1 20
22803
22804         local f=$DIR/$tdir/$tfile
22805         pool_remove_all_targets $test_pool $f
22806         pool_remove $test_pool $f
22807 }
22808 run_test 406 "DNE support fs default striping"
22809
22810 test_407() {
22811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22812         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22813                 skip "Need MDS version at least 2.8.55"
22814         remote_mds_nodsh && skip "remote MDS with nodsh"
22815
22816         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22817                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22818         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22819                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22820         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22821
22822         #define OBD_FAIL_DT_TXN_STOP    0x2019
22823         for idx in $(seq $MDSCOUNT); do
22824                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22825         done
22826         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22827         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22828                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22829         true
22830 }
22831 run_test 407 "transaction fail should cause operation fail"
22832
22833 test_408() {
22834         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22835
22836         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22837         lctl set_param fail_loc=0x8000040a
22838         # let ll_prepare_partial_page() fail
22839         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22840
22841         rm -f $DIR/$tfile
22842
22843         # create at least 100 unused inodes so that
22844         # shrink_icache_memory(0) should not return 0
22845         touch $DIR/$tfile-{0..100}
22846         rm -f $DIR/$tfile-{0..100}
22847         sync
22848
22849         echo 2 > /proc/sys/vm/drop_caches
22850 }
22851 run_test 408 "drop_caches should not hang due to page leaks"
22852
22853 test_409()
22854 {
22855         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22856
22857         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22858         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22859         touch $DIR/$tdir/guard || error "(2) Fail to create"
22860
22861         local PREFIX=$(str_repeat 'A' 128)
22862         echo "Create 1K hard links start at $(date)"
22863         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22864                 error "(3) Fail to hard link"
22865
22866         echo "Links count should be right although linkEA overflow"
22867         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22868         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22869         [ $linkcount -eq 1001 ] ||
22870                 error "(5) Unexpected hard links count: $linkcount"
22871
22872         echo "List all links start at $(date)"
22873         ls -l $DIR/$tdir/foo > /dev/null ||
22874                 error "(6) Fail to list $DIR/$tdir/foo"
22875
22876         echo "Unlink hard links start at $(date)"
22877         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22878                 error "(7) Fail to unlink"
22879         echo "Unlink hard links finished at $(date)"
22880 }
22881 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22882
22883 test_410()
22884 {
22885         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22886                 skip "Need client version at least 2.9.59"
22887         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22888                 skip "Need MODULES build"
22889
22890         # Create a file, and stat it from the kernel
22891         local testfile=$DIR/$tfile
22892         touch $testfile
22893
22894         local run_id=$RANDOM
22895         local my_ino=$(stat --format "%i" $testfile)
22896
22897         # Try to insert the module. This will always fail as the
22898         # module is designed to not be inserted.
22899         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22900             &> /dev/null
22901
22902         # Anything but success is a test failure
22903         dmesg | grep -q \
22904             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22905             error "no inode match"
22906 }
22907 run_test 410 "Test inode number returned from kernel thread"
22908
22909 cleanup_test411_cgroup() {
22910         trap 0
22911         rmdir "$1"
22912 }
22913
22914 test_411() {
22915         local cg_basedir=/sys/fs/cgroup/memory
22916         # LU-9966
22917         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22918                 skip "no setup for cgroup"
22919
22920         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22921                 error "test file creation failed"
22922         cancel_lru_locks osc
22923
22924         # Create a very small memory cgroup to force a slab allocation error
22925         local cgdir=$cg_basedir/osc_slab_alloc
22926         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22927         trap "cleanup_test411_cgroup $cgdir" EXIT
22928         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22929         echo 1M > $cgdir/memory.limit_in_bytes
22930
22931         # Should not LBUG, just be killed by oom-killer
22932         # dd will return 0 even allocation failure in some environment.
22933         # So don't check return value
22934         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22935         cleanup_test411_cgroup $cgdir
22936
22937         return 0
22938 }
22939 run_test 411 "Slab allocation error with cgroup does not LBUG"
22940
22941 test_412() {
22942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22943         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22944                 skip "Need server version at least 2.10.55"
22945         fi
22946
22947         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22948                 error "mkdir failed"
22949         $LFS getdirstripe $DIR/$tdir
22950         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22951         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22952                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22953         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22954         [ $stripe_count -eq 2 ] ||
22955                 error "expect 2 get $stripe_count"
22956 }
22957 run_test 412 "mkdir on specific MDTs"
22958
22959 test_qos_mkdir() {
22960         local mkdir_cmd=$1
22961         local stripe_count=$2
22962         local mdts=$(comma_list $(mdts_nodes))
22963
22964         local testdir
22965         local lmv_qos_prio_free
22966         local lmv_qos_threshold_rr
22967         local lmv_qos_maxage
22968         local lod_qos_prio_free
22969         local lod_qos_threshold_rr
22970         local lod_qos_maxage
22971         local count
22972         local i
22973
22974         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22975         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22976         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22977                 head -n1)
22978         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22979         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22980         stack_trap "$LCTL set_param \
22981                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22982         stack_trap "$LCTL set_param \
22983                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22984         stack_trap "$LCTL set_param \
22985                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22986
22987         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22988                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22989         lod_qos_prio_free=${lod_qos_prio_free%%%}
22990         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22991                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22992         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22993         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22994                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22995         stack_trap "do_nodes $mdts $LCTL set_param \
22996                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22997         stack_trap "do_nodes $mdts $LCTL set_param \
22998                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22999                 EXIT
23000         stack_trap "do_nodes $mdts $LCTL set_param \
23001                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23002
23003         echo
23004         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23005
23006         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23007         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23008
23009         testdir=$DIR/$tdir-s$stripe_count/rr
23010
23011         for i in $(seq $((100 * MDSCOUNT))); do
23012                 eval $mkdir_cmd $testdir/subdir$i ||
23013                         error "$mkdir_cmd subdir$i failed"
23014         done
23015
23016         for i in $(seq $MDSCOUNT); do
23017                 count=$($LFS getdirstripe -i $testdir/* |
23018                                 grep ^$((i - 1))$ | wc -l)
23019                 echo "$count directories created on MDT$((i - 1))"
23020                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23021
23022                 if [ $stripe_count -gt 1 ]; then
23023                         count=$($LFS getdirstripe $testdir/* |
23024                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23025                         echo "$count stripes created on MDT$((i - 1))"
23026                         # deviation should < 5% of average
23027                         [ $count -lt $((95 * stripe_count)) ] ||
23028                         [ $count -gt $((105 * stripe_count)) ] &&
23029                                 error "stripes are not evenly distributed"
23030                 fi
23031         done
23032
23033         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23034         do_nodes $mdts $LCTL set_param \
23035                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23036
23037         echo
23038         echo "Check for uneven MDTs: "
23039
23040         local ffree
23041         local bavail
23042         local max
23043         local min
23044         local max_index
23045         local min_index
23046         local tmp
23047
23048         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23049         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23050         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23051
23052         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23053         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23054         max_index=0
23055         min_index=0
23056         for ((i = 1; i < ${#ffree[@]}; i++)); do
23057                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23058                 if [ $tmp -gt $max ]; then
23059                         max=$tmp
23060                         max_index=$i
23061                 fi
23062                 if [ $tmp -lt $min ]; then
23063                         min=$tmp
23064                         min_index=$i
23065                 fi
23066         done
23067
23068         [ ${ffree[min_index]} -eq 0 ] &&
23069                 skip "no free files in MDT$min_index"
23070         [ ${ffree[min_index]} -gt 100000000 ] &&
23071                 skip "too much free files in MDT$min_index"
23072
23073         # Check if we need to generate uneven MDTs
23074         local threshold=50
23075         local diff=$(((max - min) * 100 / min))
23076         local value="$(generate_string 1024)"
23077
23078         while [ $diff -lt $threshold ]; do
23079                 # generate uneven MDTs, create till $threshold% diff
23080                 echo -n "weight diff=$diff% must be > $threshold% ..."
23081                 count=$((${ffree[min_index]} / 10))
23082                 # 50 sec per 10000 files in vm
23083                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23084                         skip "$count files to create"
23085                 echo "Fill MDT$min_index with $count files"
23086                 [ -d $DIR/$tdir-MDT$min_index ] ||
23087                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23088                         error "mkdir $tdir-MDT$min_index failed"
23089                 for i in $(seq $count); do
23090                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23091                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23092                                 error "create f$j_$i failed"
23093                         setfattr -n user.413b -v $value \
23094                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23095                                 error "setfattr f$j_$i failed"
23096                 done
23097
23098                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23099                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23100                 max=$(((${ffree[max_index]} >> 8) * \
23101                         (${bavail[max_index]} * bsize >> 16)))
23102                 min=$(((${ffree[min_index]} >> 8) * \
23103                         (${bavail[min_index]} * bsize >> 16)))
23104                 diff=$(((max - min) * 100 / min))
23105         done
23106
23107         echo "MDT filesfree available: ${ffree[@]}"
23108         echo "MDT blocks available: ${bavail[@]}"
23109         echo "weight diff=$diff%"
23110
23111         echo
23112         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23113
23114         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23115         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23116         # decrease statfs age, so that it can be updated in time
23117         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23118         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23119
23120         sleep 1
23121
23122         testdir=$DIR/$tdir-s$stripe_count/qos
23123
23124         for i in $(seq $((100 * MDSCOUNT))); do
23125                 eval $mkdir_cmd $testdir/subdir$i ||
23126                         error "$mkdir_cmd subdir$i failed"
23127         done
23128
23129         for i in $(seq $MDSCOUNT); do
23130                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23131                         wc -l)
23132                 echo "$count directories created on MDT$((i - 1))"
23133
23134                 if [ $stripe_count -gt 1 ]; then
23135                         count=$($LFS getdirstripe $testdir/* |
23136                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23137                         echo "$count stripes created on MDT$((i - 1))"
23138                 fi
23139         done
23140
23141         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23142         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23143
23144         # D-value should > 10% of averge
23145         [ $((max - min)) -lt 10 ] &&
23146                 error "subdirs shouldn't be evenly distributed"
23147
23148         # ditto
23149         if [ $stripe_count -gt 1 ]; then
23150                 max=$($LFS getdirstripe $testdir/* |
23151                         grep -P "^\s+$max_index\t" | wc -l)
23152                 min=$($LFS getdirstripe $testdir/* |
23153                         grep -P "^\s+$min_index\t" | wc -l)
23154                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23155                         error "stripes shouldn't be evenly distributed"|| true
23156         fi
23157 }
23158
23159 test_413a() {
23160         [ $MDSCOUNT -lt 2 ] &&
23161                 skip "We need at least 2 MDTs for this test"
23162
23163         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23164                 skip "Need server version at least 2.12.52"
23165
23166         local stripe_count
23167
23168         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23169                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23170                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23171                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23172                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23173         done
23174 }
23175 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23176
23177 test_413b() {
23178         [ $MDSCOUNT -lt 2 ] &&
23179                 skip "We need at least 2 MDTs for this test"
23180
23181         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23182                 skip "Need server version at least 2.12.52"
23183
23184         local stripe_count
23185
23186         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23187                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23188                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23189                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23190                 $LFS setdirstripe -D -c $stripe_count \
23191                         $DIR/$tdir-s$stripe_count/rr ||
23192                         error "setdirstripe failed"
23193                 $LFS setdirstripe -D -c $stripe_count \
23194                         $DIR/$tdir-s$stripe_count/qos ||
23195                         error "setdirstripe failed"
23196                 test_qos_mkdir "mkdir" $stripe_count
23197         done
23198 }
23199 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23200
23201 test_414() {
23202 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23203         $LCTL set_param fail_loc=0x80000521
23204         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23205         rm -f $DIR/$tfile
23206 }
23207 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23208
23209 test_415() {
23210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23211         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23212                 skip "Need server version at least 2.11.52"
23213
23214         # LU-11102
23215         local total
23216         local setattr_pid
23217         local start_time
23218         local end_time
23219         local duration
23220
23221         total=500
23222         # this test may be slow on ZFS
23223         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23224
23225         # though this test is designed for striped directory, let's test normal
23226         # directory too since lock is always saved as CoS lock.
23227         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23228         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23229
23230         (
23231                 while true; do
23232                         touch $DIR/$tdir
23233                 done
23234         ) &
23235         setattr_pid=$!
23236
23237         start_time=$(date +%s)
23238         for i in $(seq $total); do
23239                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23240                         > /dev/null
23241         done
23242         end_time=$(date +%s)
23243         duration=$((end_time - start_time))
23244
23245         kill -9 $setattr_pid
23246
23247         echo "rename $total files took $duration sec"
23248         [ $duration -lt 100 ] || error "rename took $duration sec"
23249 }
23250 run_test 415 "lock revoke is not missing"
23251
23252 test_416() {
23253         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23254                 skip "Need server version at least 2.11.55"
23255
23256         # define OBD_FAIL_OSD_TXN_START    0x19a
23257         do_facet mds1 lctl set_param fail_loc=0x19a
23258
23259         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23260
23261         true
23262 }
23263 run_test 416 "transaction start failure won't cause system hung"
23264
23265 cleanup_417() {
23266         trap 0
23267         do_nodes $(comma_list $(mdts_nodes)) \
23268                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23269         do_nodes $(comma_list $(mdts_nodes)) \
23270                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23271         do_nodes $(comma_list $(mdts_nodes)) \
23272                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23273 }
23274
23275 test_417() {
23276         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23277         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23278                 skip "Need MDS version at least 2.11.56"
23279
23280         trap cleanup_417 RETURN EXIT
23281
23282         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23283         do_nodes $(comma_list $(mdts_nodes)) \
23284                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23285         $LFS migrate -m 0 $DIR/$tdir.1 &&
23286                 error "migrate dir $tdir.1 should fail"
23287
23288         do_nodes $(comma_list $(mdts_nodes)) \
23289                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23290         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23291                 error "create remote dir $tdir.2 should fail"
23292
23293         do_nodes $(comma_list $(mdts_nodes)) \
23294                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23295         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23296                 error "create striped dir $tdir.3 should fail"
23297         true
23298 }
23299 run_test 417 "disable remote dir, striped dir and dir migration"
23300
23301 # Checks that the outputs of df [-i] and lfs df [-i] match
23302 #
23303 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23304 check_lfs_df() {
23305         local dir=$2
23306         local inodes
23307         local df_out
23308         local lfs_df_out
23309         local count
23310         local passed=false
23311
23312         # blocks or inodes
23313         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23314
23315         for count in {1..100}; do
23316                 cancel_lru_locks
23317                 sync; sleep 0.2
23318
23319                 # read the lines of interest
23320                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23321                         error "df $inodes $dir | tail -n +2 failed"
23322                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23323                         error "lfs df $inodes $dir | grep summary: failed"
23324
23325                 # skip first substrings of each output as they are different
23326                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23327                 # compare the two outputs
23328                 passed=true
23329                 for i in {1..5}; do
23330                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23331                 done
23332                 $passed && break
23333         done
23334
23335         if ! $passed; then
23336                 df -P $inodes $dir
23337                 echo
23338                 lfs df $inodes $dir
23339                 error "df and lfs df $1 output mismatch: "      \
23340                       "df ${inodes}: ${df_out[*]}, "            \
23341                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23342         fi
23343 }
23344
23345 test_418() {
23346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23347
23348         local dir=$DIR/$tdir
23349         local numfiles=$((RANDOM % 4096 + 2))
23350         local numblocks=$((RANDOM % 256 + 1))
23351
23352         wait_delete_completed
23353         test_mkdir $dir
23354
23355         # check block output
23356         check_lfs_df blocks $dir
23357         # check inode output
23358         check_lfs_df inodes $dir
23359
23360         # create a single file and retest
23361         echo "Creating a single file and testing"
23362         createmany -o $dir/$tfile- 1 &>/dev/null ||
23363                 error "creating 1 file in $dir failed"
23364         check_lfs_df blocks $dir
23365         check_lfs_df inodes $dir
23366
23367         # create a random number of files
23368         echo "Creating $((numfiles - 1)) files and testing"
23369         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23370                 error "creating $((numfiles - 1)) files in $dir failed"
23371
23372         # write a random number of blocks to the first test file
23373         echo "Writing $numblocks 4K blocks and testing"
23374         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23375                 count=$numblocks &>/dev/null ||
23376                 error "dd to $dir/${tfile}-0 failed"
23377
23378         # retest
23379         check_lfs_df blocks $dir
23380         check_lfs_df inodes $dir
23381
23382         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23383                 error "unlinking $numfiles files in $dir failed"
23384 }
23385 run_test 418 "df and lfs df outputs match"
23386
23387 test_419()
23388 {
23389         local dir=$DIR/$tdir
23390
23391         mkdir -p $dir
23392         touch $dir/file
23393
23394         cancel_lru_locks mdc
23395
23396         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23397         $LCTL set_param fail_loc=0x1410
23398         cat $dir/file
23399         $LCTL set_param fail_loc=0
23400         rm -rf $dir
23401 }
23402 run_test 419 "Verify open file by name doesn't crash kernel"
23403
23404 test_420()
23405 {
23406         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23407                 skip "Need MDS version at least 2.12.53"
23408
23409         local SAVE_UMASK=$(umask)
23410         local dir=$DIR/$tdir
23411         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23412
23413         mkdir -p $dir
23414         umask 0000
23415         mkdir -m03777 $dir/testdir
23416         ls -dn $dir/testdir
23417         # Need to remove trailing '.' when SELinux is enabled
23418         local dirperms=$(ls -dn $dir/testdir |
23419                          awk '{ sub(/\.$/, "", $1); print $1}')
23420         [ $dirperms == "drwxrwsrwt" ] ||
23421                 error "incorrect perms on $dir/testdir"
23422
23423         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23424                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23425         ls -n $dir/testdir/testfile
23426         local fileperms=$(ls -n $dir/testdir/testfile |
23427                           awk '{ sub(/\.$/, "", $1); print $1}')
23428         [ $fileperms == "-rwxr-xr-x" ] ||
23429                 error "incorrect perms on $dir/testdir/testfile"
23430
23431         umask $SAVE_UMASK
23432 }
23433 run_test 420 "clear SGID bit on non-directories for non-members"
23434
23435 test_421a() {
23436         local cnt
23437         local fid1
23438         local fid2
23439
23440         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23441                 skip "Need MDS version at least 2.12.54"
23442
23443         test_mkdir $DIR/$tdir
23444         createmany -o $DIR/$tdir/f 3
23445         cnt=$(ls -1 $DIR/$tdir | wc -l)
23446         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23447
23448         fid1=$(lfs path2fid $DIR/$tdir/f1)
23449         fid2=$(lfs path2fid $DIR/$tdir/f2)
23450         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23451
23452         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23453         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23454
23455         cnt=$(ls -1 $DIR/$tdir | wc -l)
23456         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23457
23458         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23459         createmany -o $DIR/$tdir/f 3
23460         cnt=$(ls -1 $DIR/$tdir | wc -l)
23461         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23462
23463         fid1=$(lfs path2fid $DIR/$tdir/f1)
23464         fid2=$(lfs path2fid $DIR/$tdir/f2)
23465         echo "remove using fsname $FSNAME"
23466         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23467
23468         cnt=$(ls -1 $DIR/$tdir | wc -l)
23469         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23470 }
23471 run_test 421a "simple rm by fid"
23472
23473 test_421b() {
23474         local cnt
23475         local FID1
23476         local FID2
23477
23478         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23479                 skip "Need MDS version at least 2.12.54"
23480
23481         test_mkdir $DIR/$tdir
23482         createmany -o $DIR/$tdir/f 3
23483         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23484         MULTIPID=$!
23485
23486         FID1=$(lfs path2fid $DIR/$tdir/f1)
23487         FID2=$(lfs path2fid $DIR/$tdir/f2)
23488         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23489
23490         kill -USR1 $MULTIPID
23491         wait
23492
23493         cnt=$(ls $DIR/$tdir | wc -l)
23494         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23495 }
23496 run_test 421b "rm by fid on open file"
23497
23498 test_421c() {
23499         local cnt
23500         local FIDS
23501
23502         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23503                 skip "Need MDS version at least 2.12.54"
23504
23505         test_mkdir $DIR/$tdir
23506         createmany -o $DIR/$tdir/f 3
23507         touch $DIR/$tdir/$tfile
23508         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23509         cnt=$(ls -1 $DIR/$tdir | wc -l)
23510         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23511
23512         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23513         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23514
23515         cnt=$(ls $DIR/$tdir | wc -l)
23516         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23517 }
23518 run_test 421c "rm by fid against hardlinked files"
23519
23520 test_421d() {
23521         local cnt
23522         local FIDS
23523
23524         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23525                 skip "Need MDS version at least 2.12.54"
23526
23527         test_mkdir $DIR/$tdir
23528         createmany -o $DIR/$tdir/f 4097
23529         cnt=$(ls -1 $DIR/$tdir | wc -l)
23530         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23531
23532         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23533         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23534
23535         cnt=$(ls $DIR/$tdir | wc -l)
23536         rm -rf $DIR/$tdir
23537         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23538 }
23539 run_test 421d "rmfid en masse"
23540
23541 test_421e() {
23542         local cnt
23543         local FID
23544
23545         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23546         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23547                 skip "Need MDS version at least 2.12.54"
23548
23549         mkdir -p $DIR/$tdir
23550         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23551         createmany -o $DIR/$tdir/striped_dir/f 512
23552         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23553         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23554
23555         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23556                 sed "s/[/][^:]*://g")
23557         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23558
23559         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23560         rm -rf $DIR/$tdir
23561         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23562 }
23563 run_test 421e "rmfid in DNE"
23564
23565 test_421f() {
23566         local cnt
23567         local FID
23568
23569         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23570                 skip "Need MDS version at least 2.12.54"
23571
23572         test_mkdir $DIR/$tdir
23573         touch $DIR/$tdir/f
23574         cnt=$(ls -1 $DIR/$tdir | wc -l)
23575         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23576
23577         FID=$(lfs path2fid $DIR/$tdir/f)
23578         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23579         # rmfid should fail
23580         cnt=$(ls -1 $DIR/$tdir | wc -l)
23581         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23582
23583         chmod a+rw $DIR/$tdir
23584         ls -la $DIR/$tdir
23585         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23586         # rmfid should fail
23587         cnt=$(ls -1 $DIR/$tdir | wc -l)
23588         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23589
23590         rm -f $DIR/$tdir/f
23591         $RUNAS touch $DIR/$tdir/f
23592         FID=$(lfs path2fid $DIR/$tdir/f)
23593         echo "rmfid as root"
23594         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23595         cnt=$(ls -1 $DIR/$tdir | wc -l)
23596         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23597
23598         rm -f $DIR/$tdir/f
23599         $RUNAS touch $DIR/$tdir/f
23600         cnt=$(ls -1 $DIR/$tdir | wc -l)
23601         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23602         FID=$(lfs path2fid $DIR/$tdir/f)
23603         # rmfid w/o user_fid2path mount option should fail
23604         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23605         cnt=$(ls -1 $DIR/$tdir | wc -l)
23606         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23607
23608         umount_client $MOUNT || error "failed to umount client"
23609         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23610                 error "failed to mount client'"
23611
23612         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23613         # rmfid should succeed
23614         cnt=$(ls -1 $DIR/$tdir | wc -l)
23615         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23616
23617         # rmfid shouldn't allow to remove files due to dir's permission
23618         chmod a+rwx $DIR/$tdir
23619         touch $DIR/$tdir/f
23620         ls -la $DIR/$tdir
23621         FID=$(lfs path2fid $DIR/$tdir/f)
23622         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23623
23624         umount_client $MOUNT || error "failed to umount client"
23625         mount_client $MOUNT "$MOUNT_OPTS" ||
23626                 error "failed to mount client'"
23627
23628 }
23629 run_test 421f "rmfid checks permissions"
23630
23631 test_421g() {
23632         local cnt
23633         local FIDS
23634
23635         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23636         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23637                 skip "Need MDS version at least 2.12.54"
23638
23639         mkdir -p $DIR/$tdir
23640         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23641         createmany -o $DIR/$tdir/striped_dir/f 512
23642         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23643         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23644
23645         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23646                 sed "s/[/][^:]*://g")
23647
23648         rm -f $DIR/$tdir/striped_dir/f1*
23649         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23650         removed=$((512 - cnt))
23651
23652         # few files have been just removed, so we expect
23653         # rmfid to fail on their fids
23654         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23655         [ $removed != $errors ] && error "$errors != $removed"
23656
23657         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23658         rm -rf $DIR/$tdir
23659         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23660 }
23661 run_test 421g "rmfid to return errors properly"
23662
23663 test_422() {
23664         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23665         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23666         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23667         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23668         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23669
23670         local amc=$(at_max_get client)
23671         local amo=$(at_max_get mds1)
23672         local timeout=`lctl get_param -n timeout`
23673
23674         at_max_set 0 client
23675         at_max_set 0 mds1
23676
23677 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23678         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23679                         fail_val=$(((2*timeout + 10)*1000))
23680         touch $DIR/$tdir/d3/file &
23681         sleep 2
23682 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23683         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23684                         fail_val=$((2*timeout + 5))
23685         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23686         local pid=$!
23687         sleep 1
23688         kill -9 $pid
23689         sleep $((2 * timeout))
23690         echo kill $pid
23691         kill -9 $pid
23692         lctl mark touch
23693         touch $DIR/$tdir/d2/file3
23694         touch $DIR/$tdir/d2/file4
23695         touch $DIR/$tdir/d2/file5
23696
23697         wait
23698         at_max_set $amc client
23699         at_max_set $amo mds1
23700
23701         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23702         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23703                 error "Watchdog is always throttled"
23704 }
23705 run_test 422 "kill a process with RPC in progress"
23706
23707 stat_test() {
23708     df -h $MOUNT &
23709     df -h $MOUNT &
23710     df -h $MOUNT &
23711     df -h $MOUNT &
23712     df -h $MOUNT &
23713     df -h $MOUNT &
23714 }
23715
23716 test_423() {
23717     local _stats
23718     # ensure statfs cache is expired
23719     sleep 2;
23720
23721     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23722     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23723
23724     return 0
23725 }
23726 run_test 423 "statfs should return a right data"
23727
23728 test_424() {
23729 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23730         $LCTL set_param fail_loc=0x80000522
23731         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23732         rm -f $DIR/$tfile
23733 }
23734 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23735
23736 test_425() {
23737         test_mkdir -c -1 $DIR/$tdir
23738         $LFS setstripe -c -1 $DIR/$tdir
23739
23740         lru_resize_disable "" 100
23741         stack_trap "lru_resize_enable" EXIT
23742
23743         sleep 5
23744
23745         for i in $(seq $((MDSCOUNT * 125))); do
23746                 local t=$DIR/$tdir/$tfile_$i
23747
23748                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23749                         error_noexit "Create file $t"
23750         done
23751         stack_trap "rm -rf $DIR/$tdir" EXIT
23752
23753         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23754                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23755                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23756
23757                 [ $lock_count -le $lru_size ] ||
23758                         error "osc lock count $lock_count > lru size $lru_size"
23759         done
23760
23761         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23762                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23763                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23764
23765                 [ $lock_count -le $lru_size ] ||
23766                         error "mdc lock count $lock_count > lru size $lru_size"
23767         done
23768 }
23769 run_test 425 "lock count should not exceed lru size"
23770
23771 test_426() {
23772         splice-test -r $DIR/$tfile
23773         splice-test -rd $DIR/$tfile
23774         splice-test $DIR/$tfile
23775         splice-test -d $DIR/$tfile
23776 }
23777 run_test 426 "splice test on Lustre"
23778
23779 lseek_test_430() {
23780         local offset
23781         local file=$1
23782
23783         # data at [200K, 400K)
23784         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23785                 error "256K->512K dd fails"
23786         # data at [2M, 3M)
23787         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23788                 error "2M->3M dd fails"
23789         # data at [4M, 5M)
23790         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23791                 error "4M->5M dd fails"
23792         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23793         # start at first component hole #1
23794         printf "Seeking hole from 1000 ... "
23795         offset=$(lseek_test -l 1000 $file)
23796         echo $offset
23797         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23798         printf "Seeking data from 1000 ... "
23799         offset=$(lseek_test -d 1000 $file)
23800         echo $offset
23801         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23802
23803         # start at first component data block
23804         printf "Seeking hole from 300000 ... "
23805         offset=$(lseek_test -l 300000 $file)
23806         echo $offset
23807         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23808         printf "Seeking data from 300000 ... "
23809         offset=$(lseek_test -d 300000 $file)
23810         echo $offset
23811         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23812
23813         # start at the first component but beyond end of object size
23814         printf "Seeking hole from 1000000 ... "
23815         offset=$(lseek_test -l 1000000 $file)
23816         echo $offset
23817         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23818         printf "Seeking data from 1000000 ... "
23819         offset=$(lseek_test -d 1000000 $file)
23820         echo $offset
23821         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23822
23823         # start at second component stripe 2 (empty file)
23824         printf "Seeking hole from 1500000 ... "
23825         offset=$(lseek_test -l 1500000 $file)
23826         echo $offset
23827         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23828         printf "Seeking data from 1500000 ... "
23829         offset=$(lseek_test -d 1500000 $file)
23830         echo $offset
23831         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23832
23833         # start at second component stripe 1 (all data)
23834         printf "Seeking hole from 3000000 ... "
23835         offset=$(lseek_test -l 3000000 $file)
23836         echo $offset
23837         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23838         printf "Seeking data from 3000000 ... "
23839         offset=$(lseek_test -d 3000000 $file)
23840         echo $offset
23841         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23842
23843         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23844                 error "2nd dd fails"
23845         echo "Add data block at 640K...1280K"
23846
23847         # start at before new data block, in hole
23848         printf "Seeking hole from 600000 ... "
23849         offset=$(lseek_test -l 600000 $file)
23850         echo $offset
23851         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23852         printf "Seeking data from 600000 ... "
23853         offset=$(lseek_test -d 600000 $file)
23854         echo $offset
23855         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23856
23857         # start at the first component new data block
23858         printf "Seeking hole from 1000000 ... "
23859         offset=$(lseek_test -l 1000000 $file)
23860         echo $offset
23861         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23862         printf "Seeking data from 1000000 ... "
23863         offset=$(lseek_test -d 1000000 $file)
23864         echo $offset
23865         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23866
23867         # start at second component stripe 2, new data
23868         printf "Seeking hole from 1200000 ... "
23869         offset=$(lseek_test -l 1200000 $file)
23870         echo $offset
23871         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23872         printf "Seeking data from 1200000 ... "
23873         offset=$(lseek_test -d 1200000 $file)
23874         echo $offset
23875         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23876
23877         # start beyond file end
23878         printf "Using offset > filesize ... "
23879         lseek_test -l 4000000 $file && error "lseek should fail"
23880         printf "Using offset > filesize ... "
23881         lseek_test -d 4000000 $file && error "lseek should fail"
23882
23883         printf "Done\n\n"
23884 }
23885
23886 test_430a() {
23887         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23888                 skip "MDT does not support SEEK_HOLE"
23889
23890         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23891                 skip "OST does not support SEEK_HOLE"
23892
23893         local file=$DIR/$tdir/$tfile
23894
23895         mkdir -p $DIR/$tdir
23896
23897         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23898         # OST stripe #1 will have continuous data at [1M, 3M)
23899         # OST stripe #2 is empty
23900         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23901         lseek_test_430 $file
23902         rm $file
23903         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23904         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23905         lseek_test_430 $file
23906         rm $file
23907         $LFS setstripe -c2 -S 512K $file
23908         echo "Two stripes, stripe size 512K"
23909         lseek_test_430 $file
23910         rm $file
23911         # FLR with stale mirror
23912         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23913                        -N -c2 -S 1M $file
23914         echo "Mirrored file:"
23915         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23916         echo "Plain 2 stripes 1M"
23917         lseek_test_430 $file
23918         rm $file
23919 }
23920 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23921
23922 test_430b() {
23923         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23924                 skip "OST does not support SEEK_HOLE"
23925
23926         local offset
23927         local file=$DIR/$tdir/$tfile
23928
23929         mkdir -p $DIR/$tdir
23930         # Empty layout lseek should fail
23931         $MCREATE $file
23932         # seek from 0
23933         printf "Seeking hole from 0 ... "
23934         lseek_test -l 0 $file && error "lseek should fail"
23935         printf "Seeking data from 0 ... "
23936         lseek_test -d 0 $file && error "lseek should fail"
23937         rm $file
23938
23939         # 1M-hole file
23940         $LFS setstripe -E 1M -c2 -E eof $file
23941         $TRUNCATE $file 1048576
23942         printf "Seeking hole from 1000000 ... "
23943         offset=$(lseek_test -l 1000000 $file)
23944         echo $offset
23945         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23946         printf "Seeking data from 1000000 ... "
23947         lseek_test -d 1000000 $file && error "lseek should fail"
23948         # full first component, non-inited second one
23949         dd if=/dev/urandom of=$file bs=1M count=1
23950         printf "Seeking hole from 1000000 ... "
23951         offset=$(lseek_test -l 1000000 $file)
23952         echo $offset
23953         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23954         printf "Seeking hole from 1048576 ... "
23955         lseek_test -l 1048576 $file && error "lseek should fail"
23956         # init second component and truncate back
23957         echo "123" >> $file
23958         $TRUNCATE $file 1048576
23959         ls -lia $file
23960         printf "Seeking hole from 1000000 ... "
23961         offset=$(lseek_test -l 1000000 $file)
23962         echo $offset
23963         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23964         printf "Seeking hole from 1048576 ... "
23965         lseek_test -l 1048576 $file && error "lseek should fail"
23966         # boundary checks for big values
23967         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
23968         offset=$(lseek_test -d 0 $file.10g)
23969         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
23970         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
23971         offset=$(lseek_test -d 0 $file.100g)
23972         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
23973         return 0
23974 }
23975 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
23976
23977 test_430c() {
23978         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23979                 skip "OST does not support SEEK_HOLE"
23980
23981         local file=$DIR/$tdir/$tfile
23982         local start
23983
23984         mkdir -p $DIR/$tdir
23985         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
23986
23987         # cp version 8.33+ prefers lseek over fiemap
23988         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
23989                 start=$SECONDS
23990                 time cp $file /dev/null
23991                 (( SECONDS - start < 5 )) ||
23992                         error "cp: too long runtime $((SECONDS - start))"
23993
23994         fi
23995         # tar version 1.29+ supports SEEK_HOLE/DATA
23996         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
23997                 start=$SECONDS
23998                 time tar cS $file - | cat > /dev/null
23999                 (( SECONDS - start < 5 )) ||
24000                         error "tar: too long runtime $((SECONDS - start))"
24001         fi
24002 }
24003 run_test 430c "lseek: external tools check"
24004
24005 prep_801() {
24006         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24007         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24008                 skip "Need server version at least 2.9.55"
24009
24010         start_full_debug_logging
24011 }
24012
24013 post_801() {
24014         stop_full_debug_logging
24015 }
24016
24017 barrier_stat() {
24018         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24019                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24020                            awk '/The barrier for/ { print $7 }')
24021                 echo $st
24022         else
24023                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24024                 echo \'$st\'
24025         fi
24026 }
24027
24028 barrier_expired() {
24029         local expired
24030
24031         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24032                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24033                           awk '/will be expired/ { print $7 }')
24034         else
24035                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24036         fi
24037
24038         echo $expired
24039 }
24040
24041 test_801a() {
24042         prep_801
24043
24044         echo "Start barrier_freeze at: $(date)"
24045         #define OBD_FAIL_BARRIER_DELAY          0x2202
24046         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24047         # Do not reduce barrier time - See LU-11873
24048         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24049
24050         sleep 2
24051         local b_status=$(barrier_stat)
24052         echo "Got barrier status at: $(date)"
24053         [ "$b_status" = "'freezing_p1'" ] ||
24054                 error "(1) unexpected barrier status $b_status"
24055
24056         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24057         wait
24058         b_status=$(barrier_stat)
24059         [ "$b_status" = "'frozen'" ] ||
24060                 error "(2) unexpected barrier status $b_status"
24061
24062         local expired=$(barrier_expired)
24063         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24064         sleep $((expired + 3))
24065
24066         b_status=$(barrier_stat)
24067         [ "$b_status" = "'expired'" ] ||
24068                 error "(3) unexpected barrier status $b_status"
24069
24070         # Do not reduce barrier time - See LU-11873
24071         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24072                 error "(4) fail to freeze barrier"
24073
24074         b_status=$(barrier_stat)
24075         [ "$b_status" = "'frozen'" ] ||
24076                 error "(5) unexpected barrier status $b_status"
24077
24078         echo "Start barrier_thaw at: $(date)"
24079         #define OBD_FAIL_BARRIER_DELAY          0x2202
24080         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24081         do_facet mgs $LCTL barrier_thaw $FSNAME &
24082
24083         sleep 2
24084         b_status=$(barrier_stat)
24085         echo "Got barrier status at: $(date)"
24086         [ "$b_status" = "'thawing'" ] ||
24087                 error "(6) unexpected barrier status $b_status"
24088
24089         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24090         wait
24091         b_status=$(barrier_stat)
24092         [ "$b_status" = "'thawed'" ] ||
24093                 error "(7) unexpected barrier status $b_status"
24094
24095         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24096         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24097         do_facet mgs $LCTL barrier_freeze $FSNAME
24098
24099         b_status=$(barrier_stat)
24100         [ "$b_status" = "'failed'" ] ||
24101                 error "(8) unexpected barrier status $b_status"
24102
24103         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24104         do_facet mgs $LCTL barrier_thaw $FSNAME
24105
24106         post_801
24107 }
24108 run_test 801a "write barrier user interfaces and stat machine"
24109
24110 test_801b() {
24111         prep_801
24112
24113         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24114         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24115         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24116         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24117         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24118
24119         cancel_lru_locks mdc
24120
24121         # 180 seconds should be long enough
24122         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24123
24124         local b_status=$(barrier_stat)
24125         [ "$b_status" = "'frozen'" ] ||
24126                 error "(6) unexpected barrier status $b_status"
24127
24128         mkdir $DIR/$tdir/d0/d10 &
24129         mkdir_pid=$!
24130
24131         touch $DIR/$tdir/d1/f13 &
24132         touch_pid=$!
24133
24134         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24135         ln_pid=$!
24136
24137         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24138         mv_pid=$!
24139
24140         rm -f $DIR/$tdir/d4/f12 &
24141         rm_pid=$!
24142
24143         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24144
24145         # To guarantee taht the 'stat' is not blocked
24146         b_status=$(barrier_stat)
24147         [ "$b_status" = "'frozen'" ] ||
24148                 error "(8) unexpected barrier status $b_status"
24149
24150         # let above commands to run at background
24151         sleep 5
24152
24153         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24154         ps -p $touch_pid || error "(10) touch should be blocked"
24155         ps -p $ln_pid || error "(11) link should be blocked"
24156         ps -p $mv_pid || error "(12) rename should be blocked"
24157         ps -p $rm_pid || error "(13) unlink should be blocked"
24158
24159         b_status=$(barrier_stat)
24160         [ "$b_status" = "'frozen'" ] ||
24161                 error "(14) unexpected barrier status $b_status"
24162
24163         do_facet mgs $LCTL barrier_thaw $FSNAME
24164         b_status=$(barrier_stat)
24165         [ "$b_status" = "'thawed'" ] ||
24166                 error "(15) unexpected barrier status $b_status"
24167
24168         wait $mkdir_pid || error "(16) mkdir should succeed"
24169         wait $touch_pid || error "(17) touch should succeed"
24170         wait $ln_pid || error "(18) link should succeed"
24171         wait $mv_pid || error "(19) rename should succeed"
24172         wait $rm_pid || error "(20) unlink should succeed"
24173
24174         post_801
24175 }
24176 run_test 801b "modification will be blocked by write barrier"
24177
24178 test_801c() {
24179         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24180
24181         prep_801
24182
24183         stop mds2 || error "(1) Fail to stop mds2"
24184
24185         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24186
24187         local b_status=$(barrier_stat)
24188         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24189                 do_facet mgs $LCTL barrier_thaw $FSNAME
24190                 error "(2) unexpected barrier status $b_status"
24191         }
24192
24193         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24194                 error "(3) Fail to rescan barrier bitmap"
24195
24196         # Do not reduce barrier time - See LU-11873
24197         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24198
24199         b_status=$(barrier_stat)
24200         [ "$b_status" = "'frozen'" ] ||
24201                 error "(4) unexpected barrier status $b_status"
24202
24203         do_facet mgs $LCTL barrier_thaw $FSNAME
24204         b_status=$(barrier_stat)
24205         [ "$b_status" = "'thawed'" ] ||
24206                 error "(5) unexpected barrier status $b_status"
24207
24208         local devname=$(mdsdevname 2)
24209
24210         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24211
24212         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24213                 error "(7) Fail to rescan barrier bitmap"
24214
24215         post_801
24216 }
24217 run_test 801c "rescan barrier bitmap"
24218
24219 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24220 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24221 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24222 saved_MOUNT_OPTS=$MOUNT_OPTS
24223
24224 cleanup_802a() {
24225         trap 0
24226
24227         stopall
24228         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24229         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24230         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24231         MOUNT_OPTS=$saved_MOUNT_OPTS
24232         setupall
24233 }
24234
24235 test_802a() {
24236         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24237         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24238         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24239                 skip "Need server version at least 2.9.55"
24240
24241         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24242
24243         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24244
24245         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24246                 error "(2) Fail to copy"
24247
24248         trap cleanup_802a EXIT
24249
24250         # sync by force before remount as readonly
24251         sync; sync_all_data; sleep 3; sync_all_data
24252
24253         stopall
24254
24255         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24256         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24257         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24258
24259         echo "Mount the server as read only"
24260         setupall server_only || error "(3) Fail to start servers"
24261
24262         echo "Mount client without ro should fail"
24263         mount_client $MOUNT &&
24264                 error "(4) Mount client without 'ro' should fail"
24265
24266         echo "Mount client with ro should succeed"
24267         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24268         mount_client $MOUNT ||
24269                 error "(5) Mount client with 'ro' should succeed"
24270
24271         echo "Modify should be refused"
24272         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24273
24274         echo "Read should be allowed"
24275         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24276                 error "(7) Read should succeed under ro mode"
24277
24278         cleanup_802a
24279 }
24280 run_test 802a "simulate readonly device"
24281
24282 test_802b() {
24283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24284         remote_mds_nodsh && skip "remote MDS with nodsh"
24285
24286         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24287                 skip "readonly option not available"
24288
24289         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24290
24291         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24292                 error "(2) Fail to copy"
24293
24294         # write back all cached data before setting MDT to readonly
24295         cancel_lru_locks
24296         sync_all_data
24297
24298         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24299         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24300
24301         echo "Modify should be refused"
24302         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24303
24304         echo "Read should be allowed"
24305         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24306                 error "(7) Read should succeed under ro mode"
24307
24308         # disable readonly
24309         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24310 }
24311 run_test 802b "be able to set MDTs to readonly"
24312
24313 test_803a() {
24314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24315         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24316                 skip "MDS needs to be newer than 2.10.54"
24317
24318         mkdir -p $DIR/$tdir
24319         # Create some objects on all MDTs to trigger related logs objects
24320         for idx in $(seq $MDSCOUNT); do
24321                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24322                         $DIR/$tdir/dir${idx} ||
24323                         error "Fail to create $DIR/$tdir/dir${idx}"
24324         done
24325
24326         sync; sleep 3
24327         wait_delete_completed # ensure old test cleanups are finished
24328         echo "before create:"
24329         $LFS df -i $MOUNT
24330         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24331
24332         for i in {1..10}; do
24333                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24334                         error "Fail to create $DIR/$tdir/foo$i"
24335         done
24336
24337         sync; sleep 3
24338         echo "after create:"
24339         $LFS df -i $MOUNT
24340         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24341
24342         # allow for an llog to be cleaned up during the test
24343         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24344                 error "before ($before_used) + 10 > after ($after_used)"
24345
24346         for i in {1..10}; do
24347                 rm -rf $DIR/$tdir/foo$i ||
24348                         error "Fail to remove $DIR/$tdir/foo$i"
24349         done
24350
24351         sleep 3 # avoid MDT return cached statfs
24352         wait_delete_completed
24353         echo "after unlink:"
24354         $LFS df -i $MOUNT
24355         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24356
24357         # allow for an llog to be created during the test
24358         [ $after_used -le $((before_used + 1)) ] ||
24359                 error "after ($after_used) > before ($before_used) + 1"
24360 }
24361 run_test 803a "verify agent object for remote object"
24362
24363 test_803b() {
24364         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24365         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24366                 skip "MDS needs to be newer than 2.13.56"
24367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24368
24369         for i in $(seq 0 $((MDSCOUNT - 1))); do
24370                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24371         done
24372
24373         local before=0
24374         local after=0
24375
24376         local tmp
24377
24378         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24379         for i in $(seq 0 $((MDSCOUNT - 1))); do
24380                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24381                         awk '/getattr/ { print $2 }')
24382                 before=$((before + tmp))
24383         done
24384         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24385         for i in $(seq 0 $((MDSCOUNT - 1))); do
24386                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24387                         awk '/getattr/ { print $2 }')
24388                 after=$((after + tmp))
24389         done
24390
24391         [ $before -eq $after ] || error "getattr count $before != $after"
24392 }
24393 run_test 803b "remote object can getattr from cache"
24394
24395 test_804() {
24396         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24397         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24398                 skip "MDS needs to be newer than 2.10.54"
24399         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24400
24401         mkdir -p $DIR/$tdir
24402         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24403                 error "Fail to create $DIR/$tdir/dir0"
24404
24405         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24406         local dev=$(mdsdevname 2)
24407
24408         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24409                 grep ${fid} || error "NOT found agent entry for dir0"
24410
24411         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24412                 error "Fail to create $DIR/$tdir/dir1"
24413
24414         touch $DIR/$tdir/dir1/foo0 ||
24415                 error "Fail to create $DIR/$tdir/dir1/foo0"
24416         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24417         local rc=0
24418
24419         for idx in $(seq $MDSCOUNT); do
24420                 dev=$(mdsdevname $idx)
24421                 do_facet mds${idx} \
24422                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24423                         grep ${fid} && rc=$idx
24424         done
24425
24426         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24427                 error "Fail to rename foo0 to foo1"
24428         if [ $rc -eq 0 ]; then
24429                 for idx in $(seq $MDSCOUNT); do
24430                         dev=$(mdsdevname $idx)
24431                         do_facet mds${idx} \
24432                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24433                         grep ${fid} && rc=$idx
24434                 done
24435         fi
24436
24437         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24438                 error "Fail to rename foo1 to foo2"
24439         if [ $rc -eq 0 ]; then
24440                 for idx in $(seq $MDSCOUNT); do
24441                         dev=$(mdsdevname $idx)
24442                         do_facet mds${idx} \
24443                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24444                         grep ${fid} && rc=$idx
24445                 done
24446         fi
24447
24448         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24449
24450         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24451                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24452         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24453                 error "Fail to rename foo2 to foo0"
24454         unlink $DIR/$tdir/dir1/foo0 ||
24455                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24456         rm -rf $DIR/$tdir/dir0 ||
24457                 error "Fail to rm $DIR/$tdir/dir0"
24458
24459         for idx in $(seq $MDSCOUNT); do
24460                 dev=$(mdsdevname $idx)
24461                 rc=0
24462
24463                 stop mds${idx}
24464                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24465                         rc=$?
24466                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24467                         error "mount mds$idx failed"
24468                 df $MOUNT > /dev/null 2>&1
24469
24470                 # e2fsck should not return error
24471                 [ $rc -eq 0 ] ||
24472                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24473         done
24474 }
24475 run_test 804 "verify agent entry for remote entry"
24476
24477 cleanup_805() {
24478         do_facet $SINGLEMDS zfs set quota=$old $fsset
24479         unlinkmany $DIR/$tdir/f- 1000000
24480         trap 0
24481 }
24482
24483 test_805() {
24484         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24485         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24486         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24487                 skip "netfree not implemented before 0.7"
24488         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24489                 skip "Need MDS version at least 2.10.57"
24490
24491         local fsset
24492         local freekb
24493         local usedkb
24494         local old
24495         local quota
24496         local pref="osd-zfs.$FSNAME-MDT0000."
24497
24498         # limit available space on MDS dataset to meet nospace issue
24499         # quickly. then ZFS 0.7.2 can use reserved space if asked
24500         # properly (using netfree flag in osd_declare_destroy()
24501         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24502         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24503                 gawk '{print $3}')
24504         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24505         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24506         let "usedkb=usedkb-freekb"
24507         let "freekb=freekb/2"
24508         if let "freekb > 5000"; then
24509                 let "freekb=5000"
24510         fi
24511         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24512         trap cleanup_805 EXIT
24513         mkdir $DIR/$tdir
24514         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24515                 error "Can't set PFL layout"
24516         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24517         rm -rf $DIR/$tdir || error "not able to remove"
24518         do_facet $SINGLEMDS zfs set quota=$old $fsset
24519         trap 0
24520 }
24521 run_test 805 "ZFS can remove from full fs"
24522
24523 # Size-on-MDS test
24524 check_lsom_data()
24525 {
24526         local file=$1
24527         local size=$($LFS getsom -s $file)
24528         local expect=$(stat -c %s $file)
24529
24530         [[ $size == $expect ]] ||
24531                 error "$file expected size: $expect, got: $size"
24532
24533         local blocks=$($LFS getsom -b $file)
24534         expect=$(stat -c %b $file)
24535         [[ $blocks == $expect ]] ||
24536                 error "$file expected blocks: $expect, got: $blocks"
24537 }
24538
24539 check_lsom_size()
24540 {
24541         local size=$($LFS getsom -s $1)
24542         local expect=$2
24543
24544         [[ $size == $expect ]] ||
24545                 error "$file expected size: $expect, got: $size"
24546 }
24547
24548 test_806() {
24549         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24550                 skip "Need MDS version at least 2.11.52"
24551
24552         local bs=1048576
24553
24554         touch $DIR/$tfile || error "touch $tfile failed"
24555
24556         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24557         save_lustre_params client "llite.*.xattr_cache" > $save
24558         lctl set_param llite.*.xattr_cache=0
24559         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24560
24561         # single-threaded write
24562         echo "Test SOM for single-threaded write"
24563         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24564                 error "write $tfile failed"
24565         check_lsom_size $DIR/$tfile $bs
24566
24567         local num=32
24568         local size=$(($num * $bs))
24569         local offset=0
24570         local i
24571
24572         echo "Test SOM for single client multi-threaded($num) write"
24573         $TRUNCATE $DIR/$tfile 0
24574         for ((i = 0; i < $num; i++)); do
24575                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24576                 local pids[$i]=$!
24577                 offset=$((offset + $bs))
24578         done
24579         for (( i=0; i < $num; i++ )); do
24580                 wait ${pids[$i]}
24581         done
24582         check_lsom_size $DIR/$tfile $size
24583
24584         $TRUNCATE $DIR/$tfile 0
24585         for ((i = 0; i < $num; i++)); do
24586                 offset=$((offset - $bs))
24587                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24588                 local pids[$i]=$!
24589         done
24590         for (( i=0; i < $num; i++ )); do
24591                 wait ${pids[$i]}
24592         done
24593         check_lsom_size $DIR/$tfile $size
24594
24595         # multi-client writes
24596         num=$(get_node_count ${CLIENTS//,/ })
24597         size=$(($num * $bs))
24598         offset=0
24599         i=0
24600
24601         echo "Test SOM for multi-client ($num) writes"
24602         $TRUNCATE $DIR/$tfile 0
24603         for client in ${CLIENTS//,/ }; do
24604                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24605                 local pids[$i]=$!
24606                 i=$((i + 1))
24607                 offset=$((offset + $bs))
24608         done
24609         for (( i=0; i < $num; i++ )); do
24610                 wait ${pids[$i]}
24611         done
24612         check_lsom_size $DIR/$tfile $offset
24613
24614         i=0
24615         $TRUNCATE $DIR/$tfile 0
24616         for client in ${CLIENTS//,/ }; do
24617                 offset=$((offset - $bs))
24618                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24619                 local pids[$i]=$!
24620                 i=$((i + 1))
24621         done
24622         for (( i=0; i < $num; i++ )); do
24623                 wait ${pids[$i]}
24624         done
24625         check_lsom_size $DIR/$tfile $size
24626
24627         # verify truncate
24628         echo "Test SOM for truncate"
24629         $TRUNCATE $DIR/$tfile 1048576
24630         check_lsom_size $DIR/$tfile 1048576
24631         $TRUNCATE $DIR/$tfile 1234
24632         check_lsom_size $DIR/$tfile 1234
24633
24634         # verify SOM blocks count
24635         echo "Verify SOM block count"
24636         $TRUNCATE $DIR/$tfile 0
24637         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24638                 error "failed to write file $tfile"
24639         check_lsom_data $DIR/$tfile
24640 }
24641 run_test 806 "Verify Lazy Size on MDS"
24642
24643 test_807() {
24644         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24645         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24646                 skip "Need MDS version at least 2.11.52"
24647
24648         # Registration step
24649         changelog_register || error "changelog_register failed"
24650         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24651         changelog_users $SINGLEMDS | grep -q $cl_user ||
24652                 error "User $cl_user not found in changelog_users"
24653
24654         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24655         save_lustre_params client "llite.*.xattr_cache" > $save
24656         lctl set_param llite.*.xattr_cache=0
24657         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24658
24659         rm -rf $DIR/$tdir || error "rm $tdir failed"
24660         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24661         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24662         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24663         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24664                 error "truncate $tdir/trunc failed"
24665
24666         local bs=1048576
24667         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24668                 error "write $tfile failed"
24669
24670         # multi-client wirtes
24671         local num=$(get_node_count ${CLIENTS//,/ })
24672         local offset=0
24673         local i=0
24674
24675         echo "Test SOM for multi-client ($num) writes"
24676         touch $DIR/$tfile || error "touch $tfile failed"
24677         $TRUNCATE $DIR/$tfile 0
24678         for client in ${CLIENTS//,/ }; do
24679                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24680                 local pids[$i]=$!
24681                 i=$((i + 1))
24682                 offset=$((offset + $bs))
24683         done
24684         for (( i=0; i < $num; i++ )); do
24685                 wait ${pids[$i]}
24686         done
24687
24688         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24689         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24690         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24691         check_lsom_data $DIR/$tdir/trunc
24692         check_lsom_data $DIR/$tdir/single_dd
24693         check_lsom_data $DIR/$tfile
24694
24695         rm -rf $DIR/$tdir
24696         # Deregistration step
24697         changelog_deregister || error "changelog_deregister failed"
24698 }
24699 run_test 807 "verify LSOM syncing tool"
24700
24701 check_som_nologged()
24702 {
24703         local lines=$($LFS changelog $FSNAME-MDT0000 |
24704                 grep 'x=trusted.som' | wc -l)
24705         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24706 }
24707
24708 test_808() {
24709         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24710                 skip "Need MDS version at least 2.11.55"
24711
24712         # Registration step
24713         changelog_register || error "changelog_register failed"
24714
24715         touch $DIR/$tfile || error "touch $tfile failed"
24716         check_som_nologged
24717
24718         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24719                 error "write $tfile failed"
24720         check_som_nologged
24721
24722         $TRUNCATE $DIR/$tfile 1234
24723         check_som_nologged
24724
24725         $TRUNCATE $DIR/$tfile 1048576
24726         check_som_nologged
24727
24728         # Deregistration step
24729         changelog_deregister || error "changelog_deregister failed"
24730 }
24731 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24732
24733 check_som_nodata()
24734 {
24735         $LFS getsom $1
24736         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24737 }
24738
24739 test_809() {
24740         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24741                 skip "Need MDS version at least 2.11.56"
24742
24743         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24744                 error "failed to create DoM-only file $DIR/$tfile"
24745         touch $DIR/$tfile || error "touch $tfile failed"
24746         check_som_nodata $DIR/$tfile
24747
24748         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24749                 error "write $tfile failed"
24750         check_som_nodata $DIR/$tfile
24751
24752         $TRUNCATE $DIR/$tfile 1234
24753         check_som_nodata $DIR/$tfile
24754
24755         $TRUNCATE $DIR/$tfile 4097
24756         check_som_nodata $DIR/$file
24757 }
24758 run_test 809 "Verify no SOM xattr store for DoM-only files"
24759
24760 test_810() {
24761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24762         $GSS && skip_env "could not run with gss"
24763         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24764                 skip "OST < 2.12.58 doesn't align checksum"
24765
24766         set_checksums 1
24767         stack_trap "set_checksums $ORIG_CSUM" EXIT
24768         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24769
24770         local csum
24771         local before
24772         local after
24773         for csum in $CKSUM_TYPES; do
24774                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24775                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24776                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24777                         eval set -- $i
24778                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24779                         before=$(md5sum $DIR/$tfile)
24780                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24781                         after=$(md5sum $DIR/$tfile)
24782                         [ "$before" == "$after" ] ||
24783                                 error "$csum: $before != $after bs=$1 seek=$2"
24784                 done
24785         done
24786 }
24787 run_test 810 "partial page writes on ZFS (LU-11663)"
24788
24789 test_812a() {
24790         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24791                 skip "OST < 2.12.51 doesn't support this fail_loc"
24792
24793         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24794         # ensure ost1 is connected
24795         stat $DIR/$tfile >/dev/null || error "can't stat"
24796         wait_osc_import_state client ost1 FULL
24797         # no locks, no reqs to let the connection idle
24798         cancel_lru_locks osc
24799
24800         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24801 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24802         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24803         wait_osc_import_state client ost1 CONNECTING
24804         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24805
24806         stat $DIR/$tfile >/dev/null || error "can't stat file"
24807 }
24808 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24809
24810 test_812b() { # LU-12378
24811         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24812                 skip "OST < 2.12.51 doesn't support this fail_loc"
24813
24814         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24815         # ensure ost1 is connected
24816         stat $DIR/$tfile >/dev/null || error "can't stat"
24817         wait_osc_import_state client ost1 FULL
24818         # no locks, no reqs to let the connection idle
24819         cancel_lru_locks osc
24820
24821         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24822 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24823         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24824         wait_osc_import_state client ost1 CONNECTING
24825         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24826
24827         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24828         wait_osc_import_state client ost1 IDLE
24829 }
24830 run_test 812b "do not drop no resend request for idle connect"
24831
24832 test_813() {
24833         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24834         [ -z "$file_heat_sav" ] && skip "no file heat support"
24835
24836         local readsample
24837         local writesample
24838         local readbyte
24839         local writebyte
24840         local readsample1
24841         local writesample1
24842         local readbyte1
24843         local writebyte1
24844
24845         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24846         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24847
24848         $LCTL set_param -n llite.*.file_heat=1
24849         echo "Turn on file heat"
24850         echo "Period second: $period_second, Decay percentage: $decay_pct"
24851
24852         echo "QQQQ" > $DIR/$tfile
24853         echo "QQQQ" > $DIR/$tfile
24854         echo "QQQQ" > $DIR/$tfile
24855         cat $DIR/$tfile > /dev/null
24856         cat $DIR/$tfile > /dev/null
24857         cat $DIR/$tfile > /dev/null
24858         cat $DIR/$tfile > /dev/null
24859
24860         local out=$($LFS heat_get $DIR/$tfile)
24861
24862         $LFS heat_get $DIR/$tfile
24863         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24864         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24865         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24866         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24867
24868         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24869         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24870         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24871         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24872
24873         sleep $((period_second + 3))
24874         echo "Sleep $((period_second + 3)) seconds..."
24875         # The recursion formula to calculate the heat of the file f is as
24876         # follow:
24877         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24878         # Where Hi is the heat value in the period between time points i*I and
24879         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24880         # to the weight of Ci.
24881         out=$($LFS heat_get $DIR/$tfile)
24882         $LFS heat_get $DIR/$tfile
24883         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24884         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24885         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24886         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24887
24888         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24889                 error "read sample ($readsample) is wrong"
24890         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24891                 error "write sample ($writesample) is wrong"
24892         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24893                 error "read bytes ($readbyte) is wrong"
24894         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24895                 error "write bytes ($writebyte) is wrong"
24896
24897         echo "QQQQ" > $DIR/$tfile
24898         echo "QQQQ" > $DIR/$tfile
24899         echo "QQQQ" > $DIR/$tfile
24900         cat $DIR/$tfile > /dev/null
24901         cat $DIR/$tfile > /dev/null
24902         cat $DIR/$tfile > /dev/null
24903         cat $DIR/$tfile > /dev/null
24904
24905         sleep $((period_second + 3))
24906         echo "Sleep $((period_second + 3)) seconds..."
24907
24908         out=$($LFS heat_get $DIR/$tfile)
24909         $LFS heat_get $DIR/$tfile
24910         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24911         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24912         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24913         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24914
24915         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24916                 4 * $decay_pct) / 100") -eq 1 ] ||
24917                 error "read sample ($readsample1) is wrong"
24918         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24919                 3 * $decay_pct) / 100") -eq 1 ] ||
24920                 error "write sample ($writesample1) is wrong"
24921         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24922                 20 * $decay_pct) / 100") -eq 1 ] ||
24923                 error "read bytes ($readbyte1) is wrong"
24924         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24925                 15 * $decay_pct) / 100") -eq 1 ] ||
24926                 error "write bytes ($writebyte1) is wrong"
24927
24928         echo "Turn off file heat for the file $DIR/$tfile"
24929         $LFS heat_set -o $DIR/$tfile
24930
24931         echo "QQQQ" > $DIR/$tfile
24932         echo "QQQQ" > $DIR/$tfile
24933         echo "QQQQ" > $DIR/$tfile
24934         cat $DIR/$tfile > /dev/null
24935         cat $DIR/$tfile > /dev/null
24936         cat $DIR/$tfile > /dev/null
24937         cat $DIR/$tfile > /dev/null
24938
24939         out=$($LFS heat_get $DIR/$tfile)
24940         $LFS heat_get $DIR/$tfile
24941         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24942         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24943         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24944         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24945
24946         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24947         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24948         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24949         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24950
24951         echo "Trun on file heat for the file $DIR/$tfile"
24952         $LFS heat_set -O $DIR/$tfile
24953
24954         echo "QQQQ" > $DIR/$tfile
24955         echo "QQQQ" > $DIR/$tfile
24956         echo "QQQQ" > $DIR/$tfile
24957         cat $DIR/$tfile > /dev/null
24958         cat $DIR/$tfile > /dev/null
24959         cat $DIR/$tfile > /dev/null
24960         cat $DIR/$tfile > /dev/null
24961
24962         out=$($LFS heat_get $DIR/$tfile)
24963         $LFS heat_get $DIR/$tfile
24964         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24965         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24966         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24967         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24968
24969         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24970         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24971         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24972         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24973
24974         $LFS heat_set -c $DIR/$tfile
24975         $LCTL set_param -n llite.*.file_heat=0
24976         echo "Turn off file heat support for the Lustre filesystem"
24977
24978         echo "QQQQ" > $DIR/$tfile
24979         echo "QQQQ" > $DIR/$tfile
24980         echo "QQQQ" > $DIR/$tfile
24981         cat $DIR/$tfile > /dev/null
24982         cat $DIR/$tfile > /dev/null
24983         cat $DIR/$tfile > /dev/null
24984         cat $DIR/$tfile > /dev/null
24985
24986         out=$($LFS heat_get $DIR/$tfile)
24987         $LFS heat_get $DIR/$tfile
24988         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24989         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24990         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24991         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24992
24993         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24994         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24995         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24996         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24997
24998         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24999         rm -f $DIR/$tfile
25000 }
25001 run_test 813 "File heat verfication"
25002
25003 test_814()
25004 {
25005         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25006         echo -n y >> $DIR/$tfile
25007         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25008         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25009 }
25010 run_test 814 "sparse cp works as expected (LU-12361)"
25011
25012 test_815()
25013 {
25014         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25015         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25016 }
25017 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25018
25019 test_816() {
25020         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25021         # ensure ost1 is connected
25022         stat $DIR/$tfile >/dev/null || error "can't stat"
25023         wait_osc_import_state client ost1 FULL
25024         # no locks, no reqs to let the connection idle
25025         cancel_lru_locks osc
25026         lru_resize_disable osc
25027         local before
25028         local now
25029         before=$($LCTL get_param -n \
25030                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25031
25032         wait_osc_import_state client ost1 IDLE
25033         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25034         now=$($LCTL get_param -n \
25035               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25036         [ $before == $now ] || error "lru_size changed $before != $now"
25037 }
25038 run_test 816 "do not reset lru_resize on idle reconnect"
25039
25040 cleanup_817() {
25041         umount $tmpdir
25042         exportfs -u localhost:$DIR/nfsexp
25043         rm -rf $DIR/nfsexp
25044 }
25045
25046 test_817() {
25047         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25048
25049         mkdir -p $DIR/nfsexp
25050         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25051                 error "failed to export nfs"
25052
25053         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25054         stack_trap cleanup_817 EXIT
25055
25056         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25057                 error "failed to mount nfs to $tmpdir"
25058
25059         cp /bin/true $tmpdir
25060         $DIR/nfsexp/true || error "failed to execute 'true' command"
25061 }
25062 run_test 817 "nfsd won't cache write lock for exec file"
25063
25064 test_818() {
25065         mkdir $DIR/$tdir
25066         $LFS setstripe -c1 -i0 $DIR/$tfile
25067         $LFS setstripe -c1 -i1 $DIR/$tfile
25068         stop $SINGLEMDS
25069         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25070         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25071         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25072                 error "start $SINGLEMDS failed"
25073         rm -rf $DIR/$tdir
25074 }
25075 run_test 818 "unlink with failed llog"
25076
25077 test_819a() {
25078         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25079         cancel_lru_locks osc
25080         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25081         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25082         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25083         rm -f $TDIR/$tfile
25084 }
25085 run_test 819a "too big niobuf in read"
25086
25087 test_819b() {
25088         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25089         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25090         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25091         cancel_lru_locks osc
25092         sleep 1
25093         rm -f $TDIR/$tfile
25094 }
25095 run_test 819b "too big niobuf in write"
25096
25097
25098 function test_820_start_ost() {
25099         sleep 5
25100
25101         for num in $(seq $OSTCOUNT); do
25102                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25103         done
25104 }
25105
25106 test_820() {
25107         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25108
25109         mkdir $DIR/$tdir
25110         umount_client $MOUNT || error "umount failed"
25111         for num in $(seq $OSTCOUNT); do
25112                 stop ost$num
25113         done
25114
25115         # mount client with no active OSTs
25116         # so that the client can't initialize max LOV EA size
25117         # from OSC notifications
25118         mount_client $MOUNT || error "mount failed"
25119         # delay OST starting to keep this 0 max EA size for a while
25120         test_820_start_ost &
25121
25122         # create a directory on MDS2
25123         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25124                 error "Failed to create directory"
25125         # open intent should update default EA size
25126         # see mdc_update_max_ea_from_body()
25127         # notice this is the very first RPC to MDS2
25128         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25129         ret=$?
25130         echo $out
25131         # With SSK, this situation can lead to -EPERM being returned.
25132         # In that case, simply retry.
25133         if [ $ret -ne 0 ] && $SHARED_KEY; then
25134                 if echo "$out" | grep -q "not permitted"; then
25135                         cp /etc/services $DIR/$tdir/mds2
25136                         ret=$?
25137                 fi
25138         fi
25139         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25140 }
25141 run_test 820 "update max EA from open intent"
25142
25143 #
25144 # tests that do cleanup/setup should be run at the end
25145 #
25146
25147 test_900() {
25148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25149         local ls
25150
25151         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25152         $LCTL set_param fail_loc=0x903
25153
25154         cancel_lru_locks MGC
25155
25156         FAIL_ON_ERROR=true cleanup
25157         FAIL_ON_ERROR=true setup
25158 }
25159 run_test 900 "umount should not race with any mgc requeue thread"
25160
25161 # LUS-6253/LU-11185
25162 test_901() {
25163         local oldc
25164         local newc
25165         local olds
25166         local news
25167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25168
25169         # some get_param have a bug to handle dot in param name
25170         cancel_lru_locks MGC
25171         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25172         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25173         umount_client $MOUNT || error "umount failed"
25174         mount_client $MOUNT || error "mount failed"
25175         cancel_lru_locks MGC
25176         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25177         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25178
25179         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25180         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25181
25182         return 0
25183 }
25184 run_test 901 "don't leak a mgc lock on client umount"
25185
25186 # LU-13377
25187 test_902() {
25188         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25189                 skip "client does not have LU-13377 fix"
25190         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25191         $LCTL set_param fail_loc=0x1415
25192         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25193         cancel_lru_locks osc
25194         rm -f $DIR/$tfile
25195 }
25196 run_test 902 "test short write doesn't hang lustre"
25197
25198 complete $SECONDS
25199 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25200 check_and_cleanup_lustre
25201 if [ "$I_MOUNTED" != "yes" ]; then
25202         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25203 fi
25204 exit_status